Initial opendaylight infrastructure commit!! 67/67/1
authorGiovanni Meo <gmeo@cisco.com>
Fri, 22 Mar 2013 11:46:02 +0000 (12:46 +0100)
committerGiovanni Meo <gmeo@cisco.com>
Fri, 22 Mar 2013 11:46:02 +0000 (12:46 +0100)
Change-Id: I2f6610f89c8c32dc6dab4e6982ce06a9b038a85a
Signed-off-by: Giovanni Meo <gmeo@cisco.com>
752 files changed:
.gitignore [new file with mode: 0644]
README.OPENDAYLIGHT [new file with mode: 0644]
opendaylight/clustering/services/pom.xml [new file with mode: 0644]
opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/CacheConfigException.java [new file with mode: 0644]
opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/CacheExistException.java [new file with mode: 0644]
opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/CacheListenerAddException.java [new file with mode: 0644]
opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/ICacheUpdateAware.java [new file with mode: 0644]
opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IClusterContainerServices.java [new file with mode: 0644]
opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IClusterGlobalServices.java [new file with mode: 0644]
opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IClusterServices.java [new file with mode: 0644]
opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IClusterServicesCommon.java [new file with mode: 0644]
opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/ICoordinatorChangeAware.java [new file with mode: 0644]
opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IGetUpdates.java [new file with mode: 0644]
opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IListenRoleChange.java [new file with mode: 0644]
opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/ListenRoleChangeAddException.java [new file with mode: 0644]
opendaylight/clustering/services_implementation/pom.xml [new file with mode: 0644]
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/Activator.java [new file with mode: 0644]
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/CacheListenerContainer.java [new file with mode: 0644]
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterContainerManager.java [new file with mode: 0644]
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterGlobalManager.java [new file with mode: 0644]
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManager.java [new file with mode: 0644]
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManagerCommon.java [new file with mode: 0644]
opendaylight/clustering/services_implementation/src/main/resources/OSGI-INF/component-cachemanager.xml [new file with mode: 0644]
opendaylight/clustering/services_implementation/src/main/resources/config/infinispan-config.xml [new file with mode: 0644]
opendaylight/clustering/services_implementation/src/main/resources/config/jgroups.xml [new file with mode: 0644]
opendaylight/clustering/stub/pom.xml [new file with mode: 0644]
opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/Activator.java [new file with mode: 0644]
opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterContainerManager.java [new file with mode: 0644]
opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterGlobalManager.java [new file with mode: 0644]
opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterManagerCommon.java [new file with mode: 0644]
opendaylight/clustering/stub/src/test/java/org/opendaylight/controller/clustering/stub/internal/TestClusteringStub.java [new file with mode: 0644]
opendaylight/clustering/test/pom.xml [new file with mode: 0644]
opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/ComplexClass.java [new file with mode: 0644]
opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/ComplexClass1.java [new file with mode: 0644]
opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/ComplexContainer.java [new file with mode: 0644]
opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/IComplex.java [new file with mode: 0644]
opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/LoggingListener.java [new file with mode: 0644]
opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/SimpleClient.java [new file with mode: 0644]
opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/StringContainer.java [new file with mode: 0644]
opendaylight/clustering/test/src/main/resources/OSGI-INF/component.xml [new file with mode: 0644]
opendaylight/clustering/test/src/test/java/org/opendaylight/controller/clustering/test/internal/TestClusteringTest.java [new file with mode: 0644]
opendaylight/commons/opendaylight/logback.xml [new file with mode: 0644]
opendaylight/commons/opendaylight/pom.xml [new file with mode: 0644]
opendaylight/commons/opendaylight/sun_coding_style.xml [new file with mode: 0644]
opendaylight/distribution/opendaylight/opendaylight-application.launch [new file with mode: 0644]
opendaylight/distribution/opendaylight/opendaylight-assembleit-fast.launch [new file with mode: 0644]
opendaylight/distribution/opendaylight/opendaylight-assembleit-noclean.launch [new file with mode: 0644]
opendaylight/distribution/opendaylight/opendaylight-assembleit-skiput.launch [new file with mode: 0644]
opendaylight/distribution/opendaylight/opendaylight-assembleit-sonar.launch [new file with mode: 0644]
opendaylight/distribution/opendaylight/opendaylight-assembleit.launch [new file with mode: 0644]
opendaylight/distribution/opendaylight/opendaylight-sonar-fast.launch [new file with mode: 0644]
opendaylight/distribution/opendaylight/opendaylight-sonar.launch [new file with mode: 0644]
opendaylight/distribution/opendaylight/pom.xml [new file with mode: 0644]
opendaylight/distribution/opendaylight/src/assemble/bin.xml [new file with mode: 0644]
opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini [new file with mode: 0644]
opendaylight/distribution/opendaylight/src/main/resources/configuration/context.xml [new file with mode: 0644]
opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml [new file with mode: 0644]
opendaylight/distribution/opendaylight/src/main/resources/configuration/tomcat-server.xml [new file with mode: 0644]
opendaylight/distribution/opendaylight/src/main/resources/run.bat [new file with mode: 0644]
opendaylight/distribution/opendaylight/src/main/resources/run.sh [new file with mode: 0755]
opendaylight/distribution/opendaylight/src/main/resources/version.properties [new file with mode: 0644]
opendaylight/distribution/sdk/pom.xml [new file with mode: 0644]
opendaylight/distribution/sdk/src/assemble/bin.xml [new file with mode: 0644]
opendaylight/logging/bridge/pom.xml [new file with mode: 0644]
opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/Activator.java [new file with mode: 0644]
opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/LogListenerImpl.java [new file with mode: 0644]
opendaylight/sal/api/pom.xml [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Action.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/ActionType.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Controller.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Drop.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Flood.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/FloodAll.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/HwPath.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Loopback.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Output.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/PopVlan.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/PushVlan.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetDlDst.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetDlSrc.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetDlType.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetNwDst.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetNwSrc.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetNwTos.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetTpDst.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetTpSrc.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetVlanCfi.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetVlanId.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetVlanPcp.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SwPath.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/AppRole.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/AppRoleLevel.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/AuthResultEnum.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/IResourceAuthorization.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/Privilege.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/Resource.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/ResourceGroup.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/UserLevel.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Actions.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/AdvertisedBandwidth.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Bandwidth.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Buffers.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Capabilities.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ComponentActivatorAbstractBase.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Config.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ConstructionException.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ContainerFlow.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ContainerServiceDependency.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Edge.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Host.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/IContainer.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/IContainerAware.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/IContainerListener.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Latency.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/MacAddress.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Name.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Node.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/NodeConnector.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Path.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/PeerBandwidth.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Property.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/State.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/SupportedBandwidth.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Tables.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Tier.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/TimeStamp.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/UpdateType.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/discovery/IDiscoveryService.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/flowprogrammer/Flow.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/flowprogrammer/IFlowProgrammerService.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/flowprogrammer/IPluginInFlowProgrammerService.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/inventory/IInventoryService.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/inventory/IListenInventoryUpdates.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/inventory/IPluginInInventoryService.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/inventory/IPluginOutInventoryService.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/Match.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchField.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/ARP.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/BitBufferHelper.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/Ethernet.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/ICMP.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IDataPacketService.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IListenDataPacket.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPluginInDataPacketService.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPluginOutDataPacketService.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPv4.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LLDP.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LLDPTLV.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LinkEncap.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/Packet.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/PacketResult.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/RawPacket.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/TCP.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/UDP.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/address/DataLinkAddress.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/address/EthernetAddress.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/FlowOnNode.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/IPluginInReadService.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/IReadService.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/NodeConnectorStatistics.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/NodeDescription.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/routing/IListenRoutingUpdates.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/routing/IRouting.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/topology/IListenTopoUpdates.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/topology/IPluginInTopologyService.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/topology/IPluginOutTopologyService.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/topology/ITopologyService.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ConfigurationObject.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/Direction.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/EtherTypes.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/GUIField.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/GlobalConstants.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/HexEncode.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/IObjectReader.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/IPProtocols.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NodeConnectorCreator.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NodeCreator.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ObjectReader.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ObjectWriter.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ReadFromFile.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ServiceHelper.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/Status.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/StatusCode.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/TierHelper.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/WriteToFile.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/action/ActionTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/authorization/AuthorizationTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/EdgeTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/NodeConnectorTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/NodeTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/PathTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/PropertyTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/flowprogrammer/FlowTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/match/MatchTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/ARPTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/BitBufferHelperTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/EthernetTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/ICMPTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/IPv4Test.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/PacketTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/TCPTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/UDPTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/address/EthernetAddressTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/reader/FlowOnNodeTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/reader/NodeConnectorStatisticsTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/reader/NodeDescriptionTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/EtherTypesTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/HexEncodeTest.java [new file with mode: 0644]
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/NetUtilsTest.java [new file with mode: 0644]
opendaylight/sal/implementation/pom.xml [new file with mode: 0644]
opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/Activator.java [new file with mode: 0644]
opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/DataPacketService.java [new file with mode: 0644]
opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/FlowProgrammerService.java [new file with mode: 0644]
opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/Inventory.java [new file with mode: 0644]
opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/ReadService.java [new file with mode: 0644]
opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/Topology.java [new file with mode: 0644]
opendaylight/sal/implementation/src/test/java/org/opendaylight/controller/sal/implementation/DataPacketServiceTest.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/.gitignore [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-api/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-api/src/main/java/org/opendaylight/controller/sal/binding/generator/api/BindingGenerator.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-api/src/main/java/org/opendaylight/controller/sal/binding/generator/api/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/BindingGeneratorImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/ConstantBuilderImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/EnumerationBuilderImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/GeneratedTOBuilderImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/GeneratedTypeBuilderImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/MethodParameterImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/BaseYangTypes.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/TypeProviderImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/yang/types/test/BaseTypeProvider.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/yang/types/test/DefinedTypesProviderTest.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/yang/types/test/GeneratedTypesTest.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/yang/types/test/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/demo-topology.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/simple-container-demo.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/simple-leaf-list-demo.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/simple-list-demo.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/BindingGeneratorServiceProvider.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/TypeProvider.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/TypeProviderFactory.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/YANGModuleIdentifier.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-util/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/AbstractBaseType.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/CodeGeneratorHelper.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/Types.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/CompositeKeyGenerator.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/Constants.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorJavaFile.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/InterfaceGenerator.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/controller/sal/java/api/generator/test/GeneratorJavaFileTest.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/controller/sal/java/api/generator/test/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/abstract-topology.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/demo-topology.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/simple-container-demo.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/simple-leaf-list-demo.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/simple-list-demo.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/AccessModifier.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/CodeGenerator.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/ConcreteType.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/Constant.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/Enumeration.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedProperty.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedTransferObject.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedType.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/MethodSignature.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/ParameterizedType.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/Type.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/ConstantBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/EnumBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/GeneratedPropertyBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/GeneratedTOBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/GeneratedTypeBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/MethodSignatureBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/provider/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/code-generator-demo/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/java/org/opendaylight/controller/Demo.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo-topology.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types1.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types2.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types3.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/test-topology.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangLexer.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParser.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParserBaseListener.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParserBaseVisitor.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParserListener.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParserVisitor.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/AbstractChildNodeBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/AugmentationSchemaBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/AugmentationTargetBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/Builder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/ChildNodeBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/DataSchemaNodeBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/GroupingBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/SchemaNodeBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/TypeAwareBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/TypeDefinitionAwareBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/TypeDefinitionBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/UsesNodeBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/AugmentationSchemaBuilderImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/ContainerSchemaNodeBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/DeviationBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/FeatureBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/GroupingBuilderImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/LeafListSchemaNodeBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/LeafSchemaNodeBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/ListSchemaNodeBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/ModuleBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/MustAwareBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/MustDefinitionBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/NotificationBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/RpcDefinitionBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/TypedefBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/UsesNodeBuilderImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/YangModelBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/impl/YangModelParserImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/util/YangModelBuilderHelper.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/builder/ContainerSchemaNodeBuilderTest.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/builder/LeafListSchemaNodeBuilderTest.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/builder/ListSchemaNodeBuilderTest.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/builder/TestUtils.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/impl/YangModelParserTest.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang1.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang2.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang3.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/.gitignore [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-api/.gitignore [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-api/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareBroker.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareConsumer.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareProvider.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareService.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataBrokerService.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataCommitHandler.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataProviderService.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataRefresher.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataValidator.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationProviderService.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationService.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/BrokerImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/BrokerServiceImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/ConsumerSessionImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/ProviderSessionImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/RpcUtils.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/Utils.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/data/DataBrokerModule.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/data/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/notify/NotificationModule.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/notify/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/rpc/RpcModule.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/rpc/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-common/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-common/src/main/java/org/opendaylight/controller/sal/common/DataStoreIdentifier.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-common/src/main/java/org/opendaylight/controller/sal/common/GlobalDataStore.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-common/src/main/java/org/opendaylight/controller/sal/common/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/.gitignore [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/Broker.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/BrokerService.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/Consumer.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/Provider.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcImplementation.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataBrokerService.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataCommitHandler.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataProviderService.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataValidator.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/NotificationListener.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/NotificationProviderService.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/NotificationService.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-demo/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoConsumerImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoProviderImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoUtils.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/SALDemo.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-spi/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-spi/src/main/java/org/opendaylight/controller/sal/core/spi/BrokerModule.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-core-spi/src/main/java/org/opendaylight/controller/sal/core/spi/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-data-api/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-schema-repository-api/.gitignore [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-schema-repository-api/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-schema-repository-api/src/main/java/org/opendaylight/controller/sal/schema/api/SchemaContext.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-schema-repository-api/src/main/java/org/opendaylight/controller/sal/schema/api/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-binding/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/DataRoot.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/Notification.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/NotificationListener.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/RpcService.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-common/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-common/src/main/java/org/opendaylight/controller/yang/common/QName.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-common/src/main/java/org/opendaylight/controller/yang/common/RpcError.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-common/src/main/java/org/opendaylight/controller/yang/common/RpcResult.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-api/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/CompositeNode.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/CompositeNodeModification.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/ModifyAction.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/Node.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/SimpleNode.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-util/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-util/src/main/java/org/opendaylight/controller/data/util/AbstractContainerNode.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-util/src/main/java/org/opendaylight/controller/data/util/AbstractNode.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-util/src/main/java/org/opendaylight/controller/data/util/Nodes.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/BinaryTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/BitsTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/BooleanTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/DecimalTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/EmptyTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/EnumTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/IdentityTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/IdentityrefTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/InstanceIdentifierTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/IntegerTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/LeafrefTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/LengthConstraint.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/PatternConstraint.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/RangeConstraint.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/StringTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/UnionTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/UnknownTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/UnsignedIntegerTypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/AnyXmlSchemaNode.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/AugmentationSchema.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/AugmentationTarget.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ChoiceCaseNode.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ChoiceNode.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ConstraintDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ConstraintMetaDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ContainerSchemaNode.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/DataNodeContainer.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/DataSchemaNode.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Deviation.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ExtensionDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/FeatureDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/GroupingDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/KeyDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/LeafListSchemaNode.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/LeafSchemaNode.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ListSchemaNode.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Module.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ModuleImport.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/MustDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/NotificationDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/RevisionAwareXPath.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/RpcDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/SchemaNode.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/SchemaPath.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Status.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/TypeDefinition.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/UsesNode.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/package-info.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/pom.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/AbstractInteger.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BaseConstraints.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BaseTypes.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BinaryType.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BitsType.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BooleanType.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Decimal64.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/EnumerationType.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/ExtendedType.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/IdentityType.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Identityref.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/InstanceIdentifier.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Int16.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Int32.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Int64.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Int8.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Leafref.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/StringType.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Uint16.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Uint32.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Uint64.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Uint8.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/UnknownType.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/YangTypesConverter.java [new file with mode: 0644]
sitebuildsettings-pom.xml [new file with mode: 0644]
third-party/commons/thirdparty/pom.xml [new file with mode: 0644]
third-party/jersey-servlet/pom.xml [new file with mode: 0644]
third-party/net.sf.jung2/pom.xml [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/blockmodel/StructurallyEquivalent.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/blockmodel/VertexPartition.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/blockmodel/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/BicomponentClusterer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/EdgeBetweennessClusterer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/VoltageClusterer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/WeakComponentClusterer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/EdgePredicateFilter.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/Filter.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/FilterUtils.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/KNeighborhoodFilter.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/VertexPredicateFilter.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/flows/EdmondsKarpMaxFlow.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/flows/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/EvolvingGraphGenerator.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/GraphGenerator.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/Lattice2DGenerator.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/BarabasiAlbertGenerator.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/EppsteinPowerLawGenerator.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/ErdosRenyiGenerator.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/KleinbergSmallWorldGenerator.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/MixedRandomGraphGenerator.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/AbstractRanker.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/BetweennessCentrality.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/KStepMarkov.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/Ranking.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/RelativeAuthorityRanker.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/WeightedNIPaths.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/AbstractLayout.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/AggregateLayout.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/BalloonLayout.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/CircleLayout.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/DAGLayout.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/FRLayout.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/FRLayout2.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/GraphElementAccessor.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/ISOMLayout.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/KKLayout.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/Layout.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/LayoutDecorator.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/PolarPoint.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/RadialTreeLayout.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/RadiusGraphElementAccessor.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/SpringLayout.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/SpringLayout2.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/StaticLayout.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/TreeLayout.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/util/RandomLocationTransformer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/util/Relaxer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/util/VisRunner.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/util/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/matrix/MatrixElementOperations.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/matrix/RealMatrixElementOperations.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/matrix/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/metrics/Metrics.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/metrics/StructuralHoles.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/metrics/TriadicCensus.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/metrics/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/AbstractIterativeScorer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/AbstractIterativeScorerWithPriors.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/BarycenterScorer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/BetweennessCentrality.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/ClosenessCentrality.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/DegreeScorer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/DistanceCentralityScorer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/EdgeScorer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/EigenvectorCentrality.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/HITS.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/HITSWithPriors.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/KStepMarkov.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/PageRank.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/PageRankWithPriors.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/VertexScorer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/VoltageScorer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/DelegateToEdgeTransformer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/ScoringUtils.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/UniformDegreeWeight.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/UniformInOut.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/VEPair.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/VertexScoreTransformer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/BFSDistanceLabeler.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/DijkstraDistance.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/DijkstraShortestPath.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/Distance.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/DistanceStatistics.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/MinimumSpanningForest.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/MinimumSpanningForest2.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/PrimMinimumSpanningTree.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/ShortestPath.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/ShortestPathUtils.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/UnweightedShortestPath.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/transformation/DirectionTransformer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/transformation/FoldingTransformer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/transformation/VertexPartitionCollapser.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/transformation/package.html [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/BasicMapEntry.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/ConstantMap.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/DiscreteDistribution.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/Indexer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/IterativeContext.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/IterativeProcess.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/KMeansClusterer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/MapBinaryHeap.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/MapSettableTransformer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/SelfLoopEdgePredicate.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/SettableTransformer.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/WeightedChoice.java [new file with mode: 0644]
third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/package.html [new file with mode: 0644]
third-party/openflowj/LICENSE [new file with mode: 0644]
third-party/openflowj/Makefile [new file with mode: 0644]
third-party/openflowj/README [new file with mode: 0644]
third-party/openflowj/eclipse_codestyle.xml [new file with mode: 0644]
third-party/openflowj/lib/commons-cli-1.2.jar [new file with mode: 0644]
third-party/openflowj/lib/junit-4.8.1.jar [new file with mode: 0644]
third-party/openflowj/pom.xml [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/example/SelectListener.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/example/SelectLoop.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/example/SimpleController.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/example/cli/Option.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/example/cli/Options.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/example/cli/ParseException.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/example/cli/SimpleCLI.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/io/OFMessageAsyncStream.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/io/OFMessageInStream.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/io/OFMessageOutStream.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/Instantiable.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFBarrierReply.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFBarrierRequest.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFEchoReply.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFEchoRequest.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFError.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFFeaturesReply.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFFeaturesRequest.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFFlowMod.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFFlowRemoved.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFGetConfigReply.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFGetConfigRequest.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFHello.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFMatch.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFMatchBeanInfo.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFMessage.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFPacketIn.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFPacketOut.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFPhysicalPort.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFPort.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFPortMod.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFPortStatus.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFQueueConfigReply.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFQueueConfigRequest.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFSetConfig.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFStatisticsMessageBase.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFStatisticsReply.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFStatisticsRequest.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFSwitchConfig.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFType.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/OFVendor.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/ActionVendorOutputNextHop.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFAction.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionDataLayer.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionDataLayerDestination.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionDataLayerSource.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionEnqueue.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionNetworkLayerAddress.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionNetworkLayerDestination.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionNetworkLayerSource.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionNetworkTypeOfService.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionOutput.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionStripVirtualLan.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionTransportLayer.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionTransportLayerDestination.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionTransportLayerSource.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionType.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionVendor.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionVirtualLanIdentifier.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionVirtualLanPriorityCodePoint.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/factory/BasicFactory.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFActionFactory.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFActionFactoryAware.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFMessageFactory.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFMessageFactoryAware.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFQueuePropertyFactory.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFQueuePropertyFactoryAware.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFStatisticsFactory.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFStatisticsFactoryAware.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/queue/OFPacketQueue.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/queue/OFQueueProperty.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/queue/OFQueuePropertyMinRate.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/queue/OFQueuePropertyType.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFAggregateStatisticsReply.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFAggregateStatisticsRequest.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFDescriptionStatistics.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFFlowStatisticsReply.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFFlowStatisticsRequest.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsRequest.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFQueueStatisticsReply.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFQueueStatisticsRequest.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFStatistics.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFStatisticsType.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFTableStatistics.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFVendorStatistics.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/util/HexString.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/util/LRULinkedHashMap.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/util/StringByteSerializer.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/util/U16.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/util/U32.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/util/U64.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/util/U8.java [new file with mode: 0644]
third-party/openflowj/src/main/java/org/openflow/util/Unsigned.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/io/OFMessageAsyncStreamTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/BasicFactoryTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFActionTypeTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFBarrierReplyTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFBarrierRequestTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFErrorTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFFeaturesReplyTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFFlowRemovedTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFGetConfigReplyTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFGetConfigRequestTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFMatchTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFPortConfigTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFPortStatusTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFQueueConfigTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFSetConfigTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFStatisticsReplyTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFStatisticsRequestTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFStatisticsTypeTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFTypeTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/OFVendorTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/protocol/queue/OFQueuePropertyTypeTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/util/HexStringTest.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/util/OFTestCase.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/util/U16Test.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/util/U32Test.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/util/U64Test.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/util/U8Test.java [new file with mode: 0644]
third-party/openflowj/src/test/java/org/openflow/util/UnsignedTest.java [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..f1f8a6e
--- /dev/null
@@ -0,0 +1,13 @@
+*.class
+**/target
+**/bin
+dist
+**/logs
+products
+repository
+workspace
+*~
+target
+.classpath
+.project
+.settings
diff --git a/README.OPENDAYLIGHT b/README.OPENDAYLIGHT
new file mode 100644 (file)
index 0000000..9165980
--- /dev/null
@@ -0,0 +1,34 @@
+DIRECTORY ORGANIZATION
+======================
+- third-party: contains all the third-party artifacts than needed
+repackaging or needed code modifications.
+- third-party/commons: contains all the parent POM files for the
+projects under the third-party directory. Only one is expected, which
+is the one located under third-party/commons/third-party, but there is
+a directory just in case we need to host more with different
+variations.
+- opendaylight: contains all the artifacts that constitute the
+controller project.
+- opendaylight/distribution: contains all the distributions that can
+be generated by packaging the several artifact. In practice for now
+there are two:
+      - "opendaylight", which is the full distribution of the controller
+      - "sdk", which contains only the artifact needed to build an app
+      against the controller (beaware this is still incomplete)
+The idea of the distribution directory is that more distribution can
+be added at will, maybe just composing subsets of the whole controller
+artifact set.
+
+HOW TO BUILD
+============
+In order to build it's required to have JDK 1.7+ and Maven 3+, to get
+a build going it's needed to:
+1) Choose the distribution, from within opendaylight/distribution
+2) Go in the directory and run
+   "mvn clean install"
+3) On succesfull completion go in the target directory to pick the zip
+file of the distribution or controller can be executed right from
+there going into the distribution directory.
+
+Thanks!!
+
diff --git a/opendaylight/clustering/services/pom.xml b/opendaylight/clustering/services/pom.xml
new file mode 100644 (file)
index 0000000..a5e09fa
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.0-SNAPSHOT</version>
+    <relativePath>../../commons/opendaylight</relativePath>
+  </parent>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>clustering.services</artifactId>
+  <version>0.4.0-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <build>
+    <plugins>
+      <plugin>
+       <groupId>org.apache.felix</groupId>
+       <artifactId>maven-bundle-plugin</artifactId>
+       <version>2.3.6</version>
+       <extensions>true</extensions>
+       <configuration>
+         <instructions>
+           <Export-Package>
+              org.opendaylight.controller.clustering.services
+            </Export-Package>
+            <Import-Package>
+              javax.transaction
+            </Import-Package>
+         </instructions>
+       </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/CacheConfigException.java b/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/CacheConfigException.java
new file mode 100644 (file)
index 0000000..98e5695
--- /dev/null
@@ -0,0 +1,36 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   CacheConfigException.java
+ *
+ * @brief  Describe an exception that is raised when the cache being
+ * allocated has configuration errors, like mismatch parameters are
+ * passed and so on.
+ *
+ *
+ */
+package org.opendaylight.controller.clustering.services;
+
+import java.lang.Exception;
+
+/**
+ * Describe an exception that is raised when the cache being
+ * allocated has configuration errors, like mismatch parameters are
+ * passed and so on.
+ */
+public class CacheConfigException extends Exception {
+
+    /**
+     * Instantiates a new cache config exception.
+     */
+    public CacheConfigException() {
+        super();
+    }
+}
diff --git a/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/CacheExistException.java b/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/CacheExistException.java
new file mode 100644 (file)
index 0000000..21bf700
--- /dev/null
@@ -0,0 +1,34 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   CacheExistException.java
+ *
+ * @brief  Describe an exception that is raised when the cache being
+ * allocated already exists
+ *
+ *
+ */
+package org.opendaylight.controller.clustering.services;
+
+import java.lang.Exception;
+
+/**
+ * Describe an exception that is raised when the cache being
+ * allocated already exists
+ */
+public class CacheExistException extends Exception {
+
+    /**
+     * Instantiates a new cache exist exception.
+     */
+    public CacheExistException() {
+        super();
+    }
+}
diff --git a/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/CacheListenerAddException.java b/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/CacheListenerAddException.java
new file mode 100644 (file)
index 0000000..f171e9c
--- /dev/null
@@ -0,0 +1,33 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   CacheListenerAddException.java
+ *
+ * @brief  Describe an exception that is raised when the cache
+ * Listener being added fails for any reason
+ *
+ */
+package org.opendaylight.controller.clustering.services;
+
+import java.lang.Exception;
+
+/**
+ * Describe an exception that is raised when the cache
+ * Listener being added fails for any reason
+ */
+public class CacheListenerAddException extends Exception {
+
+    /**
+     * Instantiates a new cache listener add exception.
+     */
+    public CacheListenerAddException() {
+        super();
+    }
+}
diff --git a/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/ICacheUpdateAware.java b/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/ICacheUpdateAware.java
new file mode 100644 (file)
index 0000000..187309b
--- /dev/null
@@ -0,0 +1,67 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   ICacheUpdateAware.java
+ *
+ * @brief Interface for getting clustered cache updates
+ *
+ * Interface that needs to be implemented by the components
+ * that want to be informed of an update in a Clustered Cache. The
+ * interface need to be registerd in the OSGi service registry with a
+ * property "cachenames" which will contains a PropertySet object
+ * listing all the caches for which their is interes.
+ */
+package org.opendaylight.controller.clustering.services;
+
+/**
+ * Interface that needs to be implemented by the components
+ * that want to be informed of an update in a Clustered Cache. The
+ * interface need to be registerd in the OSGi service registry with a
+ * property "cachenames" which will contains a PropertySet object
+ * listing all the caches for which their is interes.
+ *
+ */
+public interface ICacheUpdateAware<K, V> {
+    /**
+     * Invoked when a new entry is available in the cache, the key is
+     * only provided, the value will come as an entryUpdate invocation
+     *
+     * @param key Key for the entry just created
+     * @param cacheName name of the cache for which update has been
+     * received
+     * @param originLocal true if the event is generated from this
+     * node
+     */
+    void entryCreated(K key, String cacheName, boolean originLocal);
+
+    /**
+     * Called anytime a given entry is updated
+     *
+     * @param key Key for the entry modified
+     * @param new_value the new value the key will have
+     * @param cacheName name of the cache for which update has been
+     * received
+     * @param originLocal true if the event is generated from this
+     * node
+     */
+    void entryUpdated(K key, V new_value, String cacheName, boolean originLocal);
+
+    /**
+     * Called anytime a given key is removed from the
+     * ConcurrentHashMap we are listening to.
+     *
+     * @param key Key of the entry removed
+     * @param cacheName name of the cache for which update has been
+     * received
+     * @param originLocal true if the event is generated from this
+     * node
+     */
+    void entryDeleted(K key, String cacheName, boolean originLocal);
+}
diff --git a/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IClusterContainerServices.java b/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IClusterContainerServices.java
new file mode 100644 (file)
index 0000000..f0d6d7e
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   IClusterContainerServices.java
+ *
+ * @brief  : Set of services and application will expect from the
+ * clustering services provider. This interface is per-container and so
+ * the container parameter is implicitely known
+ *
+ * Contract between the applications and the clustering service
+ * providers. Container version
+ */
+
+package org.opendaylight.controller.clustering.services;
+
+/**
+ * Set of services and application will expect from the
+ * clustering services provider. This interface is per-container and so
+ * the container parameter is implicitely known
+ *
+ */
+public interface IClusterContainerServices extends IClusterServicesCommon {
+}
diff --git a/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IClusterGlobalServices.java b/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IClusterGlobalServices.java
new file mode 100644 (file)
index 0000000..61ad415
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   IClusterGlobalServices.java
+ *
+ * @brief  : Set of services and application will expect from the
+ * clustering services provider. This interface is supposed to have
+ * Global scope
+ *
+ * Contract between the applications and the clustering service
+ * providers. Global version
+ */
+
+package org.opendaylight.controller.clustering.services;
+
+/**
+ * Set of services and application will expect from the
+ * clustering services provider. This interface is supposed to have
+ * Global scope
+ *
+ */
+public interface IClusterGlobalServices extends IClusterServicesCommon {
+}
diff --git a/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IClusterServices.java b/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IClusterServices.java
new file mode 100644 (file)
index 0000000..031434f
--- /dev/null
@@ -0,0 +1,285 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   IClusterServices.java
+ *
+ * @brief  : Set of services and application will expect from the
+ * clustering services provider
+ *
+ * Contract between the applications and the clustering service
+ * providers.
+ */
+
+package org.opendaylight.controller.clustering.services;
+
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+
+/**
+ * Set of services and application will expect from the
+ * clustering services provider
+ *
+ */
+public interface IClusterServices {
+
+    /**
+     * Enumeration of the several modality with which a
+     * ConcurrentHashMap cache can be requested to the clustering
+     * services. The property that can be requested can be multiple.
+     *
+     */
+    public enum cacheMode {
+        /**
+         * Set for a cache that supports transaction that implies that
+         * is a transaction is open on the current thread the data
+         * will not immediately be reflected in the cache but will be
+         * staged till commit or rollback. If the transaction if NOT
+         * open the data will immediately go in the cache without
+         * staging.
+         */
+        TRANSACTIONAL,
+        /**
+         * Set on a cache that doesn't want to support
+         * transaction, so irrespective of the fact that we are in
+         * the middle of a transaction or no data will be
+         * immediately committed in the cache.
+         *
+         */
+        NON_TRANSACTIONAL;
+    }
+
+    /**
+     * Enumeration of the several properties that a cache can carry
+     *
+     */
+    public enum cacheProps {
+        /**
+         * The property returned describe the caracteristics of the
+         * transaction setup for the cache it was retrieved.
+         */
+        TRANSACTION_PROP,
+        /**
+         * The property returned report the clustering
+         * caracteristics of the cache for which property was
+         * queried.
+         */
+        CLUSTERING_PROP,
+        /**
+         * The property returned reports the locking
+         * caracteristics of the cache for which the property was
+         * queried
+         */
+        LOCKING_PROP;
+    }
+
+    /**
+     * Method that will create a new named cache per-container. The data
+     * structure if already present will cause an exception to be
+     * thrown to the caller.
+     *
+     * @param containerName Container to which the datastructure is associated
+     * @param cacheName Name of the ConcurrentHashMap to create
+     * @param cMode Mode of the cache that need to be retrieved. This
+     * is a set such that more than one property can be provided, of
+     * course contrasting requirements will not be accepted and in
+     * that case an exception is thrown
+     *
+     * @return ConcurrentHashMap to be used to modify the data structure
+     */
+    ConcurrentMap<?, ?> createCache(String containerName, String cacheName,
+            Set<cacheMode> cMode) throws CacheExistException,
+            CacheConfigException;
+
+    /**
+     * Method that will retrieve and return the handle to modify a
+     * data structire distributed via clustering services. The
+     * datastructure shall already have been created else a null
+     * reference will be returned.
+     *
+     * @param containerName Container to which the datastructure is associated
+     * @param cacheName Name of the ConcurrentHashMap to retrieve
+     *
+     * @return ConcurrentHashMap to be used to modify the data structure
+     */
+    ConcurrentMap<?, ?> getCache(String containerName, String cacheName);
+
+    /**
+     * Destroy a cachename given containerName/cachename, if doesn't exist
+     * the function does nothing. If the datastructure exists, the
+     * whole cluster will destroy the instance
+     *
+     * @param containerName Container to which the datastructure is associated
+     * @param cacheName Name of the ConcurrentHashMap to destroy
+     */
+    void destroyCache(String containerName, String cacheName);
+
+    /**
+     * Function to test the existance of a cache with a given name already
+     *
+     * @param containerName Container to which the datastructure is associated
+     * @param cacheName Name of the ConcurrentHashMap to destroy
+     *
+     * @return true if exists already, false otherwise
+     */
+    boolean existCache(String containerName, String cacheName);
+
+    /**
+     * Return the list of all teh caches registered with a container
+     *
+     * @param containerName Container for which we want to list all the caches registered
+     *
+     * @return The set of names, expressed as strings
+     */
+    Set<String> getCacheList(String containerName);
+
+    /**
+     * Return a list of properties that caracterize the cache
+     *
+     * @param containerName Name of the container where data structure resides
+     * @param cacheName Name of the cache
+     *
+     * @return The list of properties related to the cache
+     */
+    Properties getCacheProperties(String containerName, String cacheName);
+
+    /**
+     * Register an update handler for a given containerName/cacheName
+     * shared data structure. Multiple listeners are possible.
+     *
+     * @param containerName Container to which the datastructure is associated
+     * @param cacheName Name of the ConcurrentHashMap for which we
+     * want to register the listener
+     * @param u Interface to invoke when the updates are received
+     */
+    void addListener(String containerName, String cacheName, IGetUpdates<?, ?> u)
+            throws CacheListenerAddException;
+
+    /**
+     * Return a set of interfaces that are interesteed to listen to
+     * updates coming for a given datastructure shared via clustering
+     * services.
+     *
+     * @param containerName Container to which the datastructure is associated
+     * @param cacheName Name of the ConcurrentHashMap for which we
+     * want to retrieve the listener
+     */
+    Set<IGetUpdates<?, ?>> getListeners(String containerName, String cacheName);
+
+    /**
+     * UN-Register an update handler for a given containerName/cacheName
+     * shared data structure. Multiple listeners are possible.
+     *
+     * @param containerName Container to which the datastructure is associated
+     * @param cacheName Name of the ConcurrentHashMap for which we
+     * want to un-register the listener
+     * @param u Interface to un-register
+     */
+    void removeListener(String containerName, String cacheName,
+            IGetUpdates<?, ?> u);
+
+    /**
+     * Begin a transaction covering with all the data structures/HW
+     * updates. One transaction per-thread can be opened at the
+     * most, that means if multiple thread are available, multiple
+     * transactions can be outstanding.
+     *
+     */
+    void tbegin() throws NotSupportedException, SystemException;
+
+    /**
+     * Commit a transaction covering all the data structures/HW updates.
+     */
+    void tcommit() throws RollbackException, HeuristicMixedException,
+            HeuristicRollbackException, java.lang.SecurityException,
+            java.lang.IllegalStateException, SystemException;
+
+    /**
+     * Rollback a transaction covering all the data structures/HW updates
+     */
+    void trollback() throws java.lang.IllegalStateException,
+            java.lang.SecurityException, SystemException;
+
+    /**
+     * Return the javax.transaction.Transaction associated with this thread
+     *
+     *
+     * @return Return the current transaction associated with this thread
+     */
+    Transaction tgetTransaction() throws SystemException;
+
+    /**
+     * @deprecated
+     * Function that says if we are standby in the 1-1 redundancy with
+     * active/standby model. The API is not encouraged hence is
+     * deprecated. It is supposed to be used as a stop-gap till the
+     * active-standby goal is achieved. The only guys that are
+     * supposed to use are:
+     * - southbound layer, should not listen on the OF port if standby
+     * - jetty configuration, on standby jetty should redirect calls
+     * to the active.
+     *
+     * @return true if the role is the one of standby, else false
+     */
+    boolean amIStandby();
+
+    /**
+     * @deprecated
+     * Get the InetAddress of the active controller for the
+     * active-standby case, where the standby controller has to
+     * redirect the HTTP requests received from applications layer
+     *
+     * @return Address of the active controller
+     */
+    InetAddress getActiveAddress();
+
+    /**
+     * Get the InetAddress of the all the controllers that make up this
+     * Cluster
+     *
+     * @return List of InetAddress'es of all the controllers
+     */
+    List<InetAddress> getClusteredControllers();
+
+    /**
+     * Get the InetAddress of this Controller as seen by the Cluster Manager
+     *
+     * @return InetAddress of this Controller as seen by the Cluster Manager.
+     */
+    InetAddress getMyAddress();
+
+    /**
+     * @deprecated
+     * Register a listener to the event of ChangeRole, raised every
+     * time there is a change in the role of active or standby.
+     *
+     * @param i Interface that will be called when the Role Change happens
+     */
+    void listenRoleChange(IListenRoleChange i)
+            throws ListenRoleChangeAddException;
+
+    /**
+     * @deprecated
+     * UN-Register a listener to the event of ChangeRole, raised every
+     * time there is a change in the role of active or standby.
+     *
+     * @param i Interface that will be called when the Role Change happens
+     */
+    void unlistenRoleChange(IListenRoleChange i);
+}
diff --git a/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IClusterServicesCommon.java b/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IClusterServicesCommon.java
new file mode 100644 (file)
index 0000000..e292f73
--- /dev/null
@@ -0,0 +1,178 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   IClusterServicesCommon.java
+ *
+ * @brief  : Set of services and application will expect from the
+ * clustering services provider. This interface is going to be the
+ * base for per-container and Global services and so the container
+ * parameter is omitted but who uses knows about it
+ *
+ * Contract between the applications and the clustering service
+ * providers. Common version
+ */
+
+package org.opendaylight.controller.clustering.services;
+
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+
+/**
+ * @deprecated for internal use
+ * Set of services and application will expect from the
+ * clustering services provider. This interface is going to be the
+ * base for per-container and Global services and so the container
+ * parameter is omitted but who uses knows about it
+ *
+ */
+public interface IClusterServicesCommon {
+    /**
+     * Method that will create a new named cache. The data
+     * structure if already present will cause an exception to be
+     * thrown to the caller.
+     *
+     * @param cacheName Name of the ConcurrentHashMap to create
+     * @param cMode Mode of the cache that need to be retrieved. This
+     * is a set such that more than one property can be provided, of
+     * course contrasting requirements will not be accepted and in
+     * that case an exception is thrown
+     *
+     * @return ConcurrentHashMap to be used to modify the data structure
+     */
+    ConcurrentMap<?, ?> createCache(String cacheName,
+            Set<IClusterServices.cacheMode> cMode) throws CacheExistException,
+            CacheConfigException;
+
+    /**
+     * Method that will retrieve and return the handle to modify a
+     * data structire distributed via clustering services. The
+     * datastructure shall already have been created else a null
+     * reference will be returned.
+     *
+     * @param cacheName Name of the ConcurrentHashMap to retrieve
+     *
+     * @return ConcurrentHashMap to be used to modify the data structure
+     */
+    ConcurrentMap<?, ?> getCache(String cacheName);
+
+    /**
+     * Destroy a cachename given cachename, if doesn't exist
+     * the function does nothing. If the datastructure exists, the
+     * whole cluster will destroy the instance
+     *
+     * @param cacheName Name of the ConcurrentHashMap to destroy
+     */
+    void destroyCache(String cacheName);
+
+    /**
+     * Function to test the existance of a cache with a given name already
+     *
+     * @param cacheName Name of the ConcurrentHashMap to destroy
+     *
+     * @return true if exists already, false otherwise
+     */
+    boolean existCache(String cacheName);
+
+    /**
+     * Return the list of all teh caches registered in the context of
+     * the called
+     *
+     *
+     * @return The set of names, expressed as strings
+     */
+    Set<String> getCacheList();
+
+    /**
+     * Return a list of properties that caracterize the cache
+     *
+     * @param cacheName Name of the cache
+     *
+     * @return The list of properties related to the cache
+     */
+    Properties getCacheProperties(String cacheName);
+
+    /**
+     * Begin a transaction covering with all the data structures/HW
+     * updates. One transaction per-thread can be opened at the
+     * most, that means if multiple thread are available, multiple
+     * transactions can be outstanding.
+     *
+     */
+    void tbegin() throws NotSupportedException, SystemException;
+
+    /**
+     * Commit a transaction covering all the data structures/HW updates.
+     */
+    void tcommit() throws RollbackException, HeuristicMixedException,
+            HeuristicRollbackException, java.lang.SecurityException,
+            java.lang.IllegalStateException, SystemException;
+
+    /**
+     * Rollback a transaction covering all the data structures/HW updates
+     */
+    void trollback() throws java.lang.IllegalStateException,
+            java.lang.SecurityException, SystemException;
+
+    /**
+     * Return the javax.transaction.Transaction associated with this thread
+     *
+     *
+     * @return Return the current transaction associated with this thread
+     */
+    Transaction tgetTransaction() throws SystemException;
+
+    /**
+     *
+     * Get the InetAddress of the coordinator controller in the cluster
+     *
+     * @return Address of the coordinator controller
+     */
+    InetAddress getCoordinatorAddress();
+
+    /**
+     * Get the InetAddress of the all the controllers that make up this
+     * Cluster
+     *
+     * @return List of InetAddress'es of all the controllers
+     */
+    List<InetAddress> getClusteredControllers();
+
+    /**
+     * Get the InetAddress of this Controller as seen by the Cluster Manager
+     *
+     * @return InetAddress of this Controller as seen by the Cluster Manager.
+     */
+    InetAddress getMyAddress();
+
+    /**
+     * Function that is used to know if the node on which is called is
+     * the cluster coordinator. The API is useful in scenario where
+     * the same logic is not worthed to be replicated on multiple
+     * nodes in the cluster and one can cook it up for all the
+     * others. In this scenario running the logic on the coordinator
+     * make sense, this of course implies logics that are not heavy
+     * and don't need to be scaled out linearly with the size of the
+     * cluster.
+     *
+     * @return true if the node on which the API is called is the
+     * coordinator for the cluster
+     */
+    boolean amICoordinator();
+}
diff --git a/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/ICoordinatorChangeAware.java b/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/ICoordinatorChangeAware.java
new file mode 100644 (file)
index 0000000..4a92aca
--- /dev/null
@@ -0,0 +1,32 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   ICoordinatorChangeAware.java
+ *
+ *
+ * @brief  Interface that needs to be implemented by who wants to be
+ * notified of coordinator role change
+ *
+ */
+package org.opendaylight.controller.clustering.services;
+
+/**
+ * Interface that needs to be implemented by who wants to be
+ * notified of coordinator role change
+ *
+ */
+public interface ICoordinatorChangeAware {
+
+    /**
+     * Function that will be called when there is the event of
+     * coordinator change in the cluster.
+     */
+    public void coordinatorChanged();
+}
diff --git a/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IGetUpdates.java b/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IGetUpdates.java
new file mode 100644 (file)
index 0000000..1f9a45a
--- /dev/null
@@ -0,0 +1,59 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   IGetUpdates.java
+ *
+ * @brief  Interface that needs to be implemented by the listeners of
+ * updates received on data structure shared in the cluster
+ *
+ * Interface that needs to be implemented by the listeners of updates
+ * received on data structure shared in the cluster
+ */
+package org.opendaylight.controller.clustering.services;
+
+/**
+ * @deprecated for internal use
+ * Interface that needs to be implemented by the listeners of
+ * updates received on data structure shared in the cluster
+ */
+public interface IGetUpdates<K, V> {
+    /**
+     * Invoked when a new entry is available in the cache, the key is
+     * only provided, the value will come as an entryUpdate invocation
+     *
+     * @param key Key for the entry just created
+     * @param containerName container for which the update has been received
+     * @param cacheName name of the cache for which update has been received
+     */
+    void entryCreated(K key, String containerName, String cacheName,
+            boolean local);
+
+    /**
+     * Called anytime a given entry is updated
+     *
+     * @param key Key for the entry modified
+     * @param new_value the new value the key will have
+     * @param containerName container for which the update has been received
+     * @param cacheName name of the cache for which update has been received
+     */
+    void entryUpdated(K key, V new_value, String containerName,
+            String cacheName, boolean local);
+
+    /**
+     * Called anytime a given key is removed from the
+     * ConcurrentHashMap we are listening to.
+     *
+     * @param key Key of the entry removed
+     * @param containerName container for which the update has been received
+     * @param cacheName name of the cache for which update has been received
+     */
+    void entryDeleted(K key, String containerName, String cacheName,
+            boolean originLocal);
+}
diff --git a/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IListenRoleChange.java b/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/IListenRoleChange.java
new file mode 100644 (file)
index 0000000..e5c7a88
--- /dev/null
@@ -0,0 +1,41 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   IListenRoleChange.java
+ *
+ *
+ * @brief  Interface that needs to be implemented by who wants to be
+ * notified of new active change
+ *
+ * @deprecated
+ *
+ * Interface that needs to be implemented by who wants to be notified
+ * of newly active taking over. Interface that is supposed to be
+ * short-lived and will be removed as soon as active-standby goal is reached.
+ */
+package org.opendaylight.controller.clustering.services;
+
+/**
+ * Interface that needs to be implemented by who wants to be notified
+ * of newly active taking over. Interface that is supposed to be
+ * short-lived and will be removed as soon as active-standby goal is reached.
+ *
+ */
+public interface IListenRoleChange {
+
+    /**
+     * @deprecated
+     * Function that will be called when a new active is
+     * available. This function is supposed only to be of use till
+     * active-standby milestone is reached, after will be removed.
+     *
+     */
+    public void newActiveAvailable();
+}
diff --git a/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/ListenRoleChangeAddException.java b/opendaylight/clustering/services/src/main/java/org/opendaylight/controller/clustering/services/ListenRoleChangeAddException.java
new file mode 100644 (file)
index 0000000..ad6cd2e
--- /dev/null
@@ -0,0 +1,33 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   ListenRoleChangeAddException.java
+ *
+ * @brief  Describe an exception that is raised when the cache
+ * Listener being added fails for any reason
+ *
+ */
+package org.opendaylight.controller.clustering.services;
+
+import java.lang.Exception;
+
+/**
+ * @deprecated for internal use
+ * The Class ListenRoleChangeAddException.
+ */
+public class ListenRoleChangeAddException extends Exception {
+
+    /**
+     * Instantiates a new listen role change add exception.
+     */
+    public ListenRoleChangeAddException() {
+        super();
+    }
+}
diff --git a/opendaylight/clustering/services_implementation/pom.xml b/opendaylight/clustering/services_implementation/pom.xml
new file mode 100644 (file)
index 0000000..82a97b6
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.0-SNAPSHOT</version>
+    <relativePath>../../commons/opendaylight</relativePath>
+  </parent>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>clustering.services-implementation</artifactId>
+  <version>0.4.0-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <build>
+    <plugins>
+      <plugin>
+       <groupId>org.apache.felix</groupId>
+       <artifactId>maven-bundle-plugin</artifactId>
+       <version>2.3.6</version>
+       <extensions>true</extensions>
+       <configuration>
+         <instructions>
+           <Import-Package>
+              org.slf4j,
+              !org.jboss.*,
+              !bsh*,
+              !net.jcip.*,
+              javax.transaction,
+              *,
+              org.opendaylight.controller.clustering.services,
+              org.opendaylight.controller.sal.core
+            </Import-Package>
+            <Bundle-Activator>
+              org.opendaylight.controller.clustering.services_implementation.internal.Activator
+            </Bundle-Activator>
+            <!-- Add in the DynamicImport-Package ONLY the packages that -->
+            <!-- contains types that MUST be unmarshalled by the -->
+            <!-- infinispan. They need to be wired at runtime even during -->
+            <!-- the bundle is already RESOLVED, but at the same time if -->
+            <!-- those are missing the bundle will still come up, this is -->
+            <!-- why those dependencies ends in the DynamicImport-Package -->
+            <!-- rather in the Import-Package  -->
+            <DynamicImport-Package>
+              *
+            </DynamicImport-Package>
+            <Embed-Dependency>
+              infinispan-core,jgroups,jboss-marshalling-river,jboss-marshalling,jboss-logging,staxmapper;type=!pom;inline=false
+            </Embed-Dependency>
+            <Embed-Transitive>
+              true
+            </Embed-Transitive>
+         </instructions>
+       </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.infinispan</groupId>
+      <artifactId>infinispan-core</artifactId>
+      <version>5.2.3.Final</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>clustering.services</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/Activator.java b/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/Activator.java
new file mode 100644 (file)
index 0000000..79af2cf
--- /dev/null
@@ -0,0 +1,149 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.services_implementation.internal;
+
+import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
+
+import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.clustering.services.ICoordinatorChangeAware;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.felix.dm.Component;
+
+public class Activator extends ComponentActivatorAbstractBase {
+    protected static final Logger logger = LoggerFactory
+            .getLogger(Activator.class);
+
+    /**
+     * Function called when the activator starts just after some
+     * initializations are done by the
+     * ComponentActivatorAbstractBase.
+     *
+     */
+    public void init() {
+    }
+
+    /**
+     * Function called when the activator stops just before the
+     * cleanup done by ComponentActivatorAbstractBase
+     *
+     */
+    public void destroy() {
+    }
+
+    /**
+     * Function that is used to communicate to dependency manager the
+     * list of known implementations for services inside a container
+     *
+     *
+     * @return An array containing all the CLASS objects that will be
+     * instantiated in order to get an fully working implementation
+     * Object
+     */
+    public Object[] getGlobalImplementations() {
+        Object[] res = { ClusterManager.class, ClusterGlobalManager.class };
+        return res;
+    }
+
+    /**
+     * Function that is used to communicate to dependency manager the
+     * list of known implementations for services inside a container
+     *
+     *
+     * @return An array containing all the CLASS objects that will be
+     * instantiated in order to get an fully working implementation
+     * Object
+     */
+    public Object[] getImplementations() {
+        Object[] res = { ClusterContainerManager.class };
+        return res;
+    }
+
+    /**
+     * Function that is called when configuration of the dependencies
+     * is required.
+     *
+     * @param c dependency manager Component object, used for
+     * configuring the dependencies exported and imported
+     * @param imp Implementation class that is being configured,
+     * needed as long as the same routine can configure multiple
+     * implementations
+     * @param containerName The containerName being configured, this allow
+     * also optional per-container different behavior if needed, usually
+     * should not be the case though.
+     */
+    public void configureInstance(Component c, Object imp, String containerName) {
+        if (imp.equals(ClusterContainerManager.class)) {
+            c.setInterface(new String[] { IClusterContainerServices.class
+                    .getName() }, null);
+
+            c.add(createServiceDependency().setService(IClusterServices.class)
+                    .setCallbacks("setClusterService", "unsetClusterService")
+                    .setRequired(true));
+
+            // CacheUpdate services will be none or many so the
+            // dependency is optional
+            c.add(createContainerServiceDependency(containerName).setService(
+                    ICacheUpdateAware.class).setCallbacks(
+                    "setCacheUpdateAware", "unsetCacheUpdateAware")
+                    .setRequired(false));
+
+            // Coordinator change event can be one or many so
+            // dependency is optional
+            c.add(createContainerServiceDependency(containerName).setService(
+                    ICoordinatorChangeAware.class).setCallbacks(
+                    "setCoordinatorChangeAware", "unsetCoordinatorChangeAware")
+                    .setRequired(false));
+        }
+    }
+
+    /**
+     * Function that is called when configuration of the dependencies
+     * is required.
+     *
+     * @param c dependency manager Component object, used for
+     * configuring the dependencies exported and imported
+     * @param imp Implementation class that is being configured,
+     * needed as long as the same routine can configure multiple
+     * implementations
+     */
+    public void configureGlobalInstance(Component c, Object imp) {
+        if (imp.equals(ClusterManager.class)) {
+            // export the service for Apps and Plugins
+            c.setInterface(new String[] { IClusterServices.class.getName() },
+                    null);
+        }
+
+        if (imp.equals(ClusterGlobalManager.class)) {
+            c.setInterface(new String[] { IClusterGlobalServices.class
+                    .getName() }, null);
+
+            c.add(createServiceDependency().setService(IClusterServices.class)
+                    .setCallbacks("setClusterService", "unsetClusterService")
+                    .setRequired(true));
+
+            // CacheUpdate services will be none or many so the
+            // dependency is optional
+            c.add(createServiceDependency().setService(ICacheUpdateAware.class)
+                    .setCallbacks("setCacheUpdateAware",
+                            "unsetCacheUpdateAware").setRequired(false));
+
+            // Coordinator change event can be one or many so
+            // dependency is optional
+            c.add(createServiceDependency().setService(
+                    ICoordinatorChangeAware.class).setCallbacks(
+                    "setCoordinatorChangeAware", "unsetCoordinatorChangeAware")
+                    .setRequired(false));
+        }
+    }
+}
diff --git a/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/CacheListenerContainer.java b/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/CacheListenerContainer.java
new file mode 100644 (file)
index 0000000..c3c0621
--- /dev/null
@@ -0,0 +1,73 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.services_implementation.internal;
+
+import org.infinispan.notifications.Listener;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryCreated;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
+import org.infinispan.notifications.cachelistener.event.CacheEntryCreatedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
+import org.opendaylight.controller.clustering.services.IGetUpdates;
+
+@Listener
+public class CacheListenerContainer {
+    private IGetUpdates toBeUpdated;
+    private String containerName;
+    private String cacheName;
+
+    public CacheListenerContainer(IGetUpdates i, String containerName,
+            String cacheName) {
+        this.toBeUpdated = i;
+        this.containerName = containerName;
+        this.cacheName = cacheName;
+    }
+
+    public IGetUpdates whichListener() {
+        return this.toBeUpdated;
+    }
+
+    @CacheEntryCreated
+    public void observeCreate(CacheEntryCreatedEvent<Object, Object> event) {
+        if (event.isPre()) {
+            return;
+        }
+
+        if (this.toBeUpdated != null) {
+            this.toBeUpdated.entryCreated(event.getKey(), this.containerName,
+                    this.cacheName, event.isOriginLocal());
+        }
+    }
+
+    @CacheEntryModified
+    public void observeModify(CacheEntryModifiedEvent<Object, Object> event) {
+        if (event.isPre()) {
+            return;
+        }
+
+        if (this.toBeUpdated != null) {
+            this.toBeUpdated.entryUpdated(event.getKey(), event.getValue(),
+                    this.containerName, this.cacheName, event.isOriginLocal());
+        }
+    }
+
+    @CacheEntryRemoved
+    public void observeRemove(CacheEntryRemovedEvent<Object, Object> event) {
+        if (event.isPre()) {
+            return;
+        }
+
+        if (this.toBeUpdated != null) {
+            this.toBeUpdated.entryDeleted(event.getKey(), this.containerName,
+                    this.cacheName, event.isOriginLocal());
+        }
+    }
+}
diff --git a/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterContainerManager.java b/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterContainerManager.java
new file mode 100644 (file)
index 0000000..9496c33
--- /dev/null
@@ -0,0 +1,16 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.services_implementation.internal;
+
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+
+public class ClusterContainerManager extends ClusterManagerCommon implements
+        IClusterContainerServices {
+}
diff --git a/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterGlobalManager.java b/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterGlobalManager.java
new file mode 100644 (file)
index 0000000..8211846
--- /dev/null
@@ -0,0 +1,16 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.services_implementation.internal;
+
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+
+public class ClusterGlobalManager extends ClusterManagerCommon implements
+        IClusterGlobalServices {
+}
diff --git a/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManager.java b/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManager.java
new file mode 100644 (file)
index 0000000..d3cd23e
--- /dev/null
@@ -0,0 +1,672 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.services_implementation.internal;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.infinispan.Cache;
+import org.infinispan.configuration.cache.Configuration;
+import org.infinispan.manager.DefaultCacheManager;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.notifications.Listener;
+import org.infinispan.notifications.cachemanagerlistener.annotation.ViewChanged;
+import org.infinispan.notifications.cachemanagerlistener.event.ViewChangedEvent;
+import org.infinispan.remoting.transport.Address;
+import org.infinispan.remoting.transport.Transport;
+import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
+import org.infinispan.remoting.transport.jgroups.JGroupsTransport;
+import org.jgroups.Channel;
+import org.jgroups.Event;
+import org.jgroups.stack.GossipRouter;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.CacheListenerAddException;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.clustering.services.IGetUpdates;
+import org.opendaylight.controller.clustering.services.IListenRoleChange;
+import org.opendaylight.controller.clustering.services.ListenRoleChangeAddException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ClusterManager implements IClusterServices {
+    protected static final Logger logger = LoggerFactory
+            .getLogger(ClusterManager.class);
+    private DefaultCacheManager cm;
+    GossipRouter gossiper;
+    private HashSet roleChangeListeners;
+    private ViewChangedListener cacheManagerListener;
+
+    private static String loopbackAddress = "127.0.0.1";
+
+    /**
+     * Start a JGroups GossipRouter if we are a supernode. The
+     * GosispRouter is nothing more than a simple
+     * rendevouz-pointer. All the nodes that wants to join the cluster
+     * will come to any of the rendevouz point and they introduce the
+     * nodes to all the others. Once the meet and greet phase if over,
+     * the nodes will open a full-mesh with the remaining n-1 nodes,
+     * so even if the GossipRouter goes down nothing is lost.
+     * NOTE: This function has the side effect to set some of the
+     * JGROUPS configurations, this because in this function already
+     * we try to retrieve some of the network capabilities of the
+     * device and so it's better not to do that again
+     *
+     *
+     * @return GossipRouter
+     */
+    private GossipRouter startGossiper() {
+        boolean amIGossipRouter = false;
+        Integer gossipRouterPortDefault = 12001;
+        Integer gossipRouterPort = gossipRouterPortDefault;
+        InetAddress gossipRouterAddress = null;
+        String supernodes_list = System.getProperty("supernodes",
+                loopbackAddress);
+        StringBuffer sanitized_supernodes_list = new StringBuffer();
+        List<InetAddress> myAddresses = new ArrayList<InetAddress>();
+
+        StringTokenizer supernodes = new StringTokenizer(supernodes_list, ":");
+        if (supernodes.hasMoreTokens()) {
+            // Populate the list of my addresses
+            try {
+                Enumeration e = NetworkInterface.getNetworkInterfaces();
+                while (e.hasMoreElements()) {
+                    NetworkInterface n = (NetworkInterface) e.nextElement();
+                    Enumeration ee = n.getInetAddresses();
+                    while (ee.hasMoreElements()) {
+                        InetAddress i = (InetAddress) ee.nextElement();
+                        myAddresses.add(i);
+                    }
+                }
+            } catch (SocketException se) {
+                logger.error("Cannot get the list of network interfaces");
+                return null;
+            }
+        }
+        while (supernodes.hasMoreTokens()) {
+            String curr_supernode = supernodes.nextToken();
+            logger.debug("Examining supernode " + curr_supernode);
+            StringTokenizer host_port = new StringTokenizer(curr_supernode,
+                    "[]");
+            String host;
+            String port;
+            Integer port_num = gossipRouterPortDefault;
+            if (host_port.countTokens() > 2) {
+                logger.error("Error parsing supernode " + curr_supernode
+                        + " proceed to the next one");
+                continue;
+            }
+            host = host_port.nextToken();
+            InetAddress hostAddr;
+            try {
+                hostAddr = InetAddress.getByName(host);
+            } catch (UnknownHostException ue) {
+                logger.error("Host not known");
+                continue;
+            }
+            if (host_port.hasMoreTokens()) {
+                port = host_port.nextToken();
+                try {
+                    port_num = Integer.valueOf(port);
+                } catch (NumberFormatException ne) {
+                    logger
+                            .error("Supplied supernode gossiepr port is not recognized, using standard gossipport");
+                    port_num = gossipRouterPortDefault;
+                }
+                if ((port_num > 65535) || (port_num < 0)) {
+                    logger
+                            .error("Supplied supernode gossip port is outside a valid TCP port range");
+                    port_num = gossipRouterPortDefault;
+                }
+            }
+            if (!amIGossipRouter) {
+                if (host != null) {
+                    for (InetAddress myAddr : myAddresses) {
+                        if (myAddr.equals(hostAddr)) {
+                            amIGossipRouter = true;
+                            gossipRouterAddress = hostAddr;
+                            gossipRouterPort = port_num;
+                            break;
+                        }
+                    }
+                }
+            }
+            if (!sanitized_supernodes_list.toString().equals("")) {
+                sanitized_supernodes_list.append(",");
+            }
+            sanitized_supernodes_list.append(hostAddr.getHostAddress() + "["
+                    + port_num + "]");
+        }
+
+        if (amIGossipRouter) {
+            // Set the Jgroups binding interface to the one we got
+            // from the supernodes attribute
+            if (gossipRouterAddress != null) {
+                System.setProperty("jgroups.tcp.address", gossipRouterAddress
+                        .getHostAddress());
+            }
+        } else {
+            // Set the Jgroup binding interface to the one we are well
+            // known outside or else to the first with non-local
+            // scope.
+            try {
+                String myBind = InetAddress.getLocalHost().getHostAddress();
+                if (myBind == null
+                        || InetAddress.getLocalHost().isLoopbackAddress()) {
+                    for (InetAddress myAddr : myAddresses) {
+                        if (myAddr.isLoopbackAddress()
+                                || myAddr.isLinkLocalAddress()) {
+                            logger.debug("Skipping local address "
+                                    + myAddr.getHostAddress());
+                            continue;
+                        } else {
+                            // First non-local address
+                            myBind = myAddr.getHostAddress();
+                            logger.debug("First non-local address " + myBind);
+                            break;
+                        }
+                    }
+                }
+                String jgroupAddress = System
+                        .getProperty("jgroups.tcp.address");
+                if (jgroupAddress == null) {
+                    if (myBind != null) {
+                        logger.debug("Set bind address to be " + myBind);
+                        System.setProperty("jgroups.tcp.address", myBind);
+                    } else {
+                        logger
+                                .debug("Set bind address to be LOCALHOST=127.0.0.1");
+                        System.setProperty("jgroups.tcp.address", "127.0.0.1");
+                    }
+                } else {
+                    logger.debug("jgroup.tcp.address already set to be "
+                            + jgroupAddress);
+                }
+            } catch (UnknownHostException uhe) {
+                logger
+                        .error("Met UnknownHostException while trying to get binding address for jgroups");
+            }
+        }
+
+        // The supernodes list constitute also the tcpgossip initial
+        // host list
+        System.setProperty("jgroups.tcpgossip.initial_hosts",
+                sanitized_supernodes_list.toString());
+        logger.debug("jgroups.tcp.address set to "
+                + System.getProperty("jgroups.tcp.address"));
+        logger.debug("jgroups.tcpgossip.initial_hosts set to "
+                + System.getProperty("jgroups.tcpgossip.initial_hosts"));
+        GossipRouter res = null;
+        if (amIGossipRouter) {
+            logger.info("I'm a GossipRouter will listen on port "
+                    + gossipRouterPort);
+            res = new GossipRouter(gossipRouterPort);
+        }
+        return res;
+    }
+
+    public void start() {
+        this.gossiper = startGossiper();
+        if (this.gossiper != null) {
+            logger.debug("Trying to start Gossiper");
+            try {
+                this.gossiper.start();
+                logger.info("Started GossipRouter");
+            } catch (Exception e) {
+                logger.error("GossipRouter didn't start exception " + e
+                        + " met");
+                StringWriter sw = new StringWriter();
+                logger.error("Stack Trace that raised the exception");
+                e.printStackTrace(new PrintWriter(sw));
+                logger.error(sw.toString());
+            }
+        }
+        logger.info("Starting the ClusterManager");
+        try {
+            //FIXME keeps throwing FileNotFoundException
+            this.cm = new DefaultCacheManager("/config/infinispan-config.xml");
+            logger.debug("Allocated ClusterManager");
+            if (this.cm != null) {
+                this.cm.start();
+                this.cm.startCache();
+                logger.debug("Started the ClusterManager");
+            }
+        } catch (Exception ioe) {
+            StringWriter sw = new StringWriter();
+            logger.error("Cannot configure infinispan .. bailing out ");
+            logger.error("Stack Trace that raised th exception");
+            ioe.printStackTrace(new PrintWriter(sw));
+            logger.error(sw.toString());
+            this.cm = null;
+            this.stop();
+        }
+        logger.debug("Cache Manager has value " + this.cm);
+    }
+
+    public void stop() {
+        logger.info("Stopping the ClusterManager");
+        if (this.cm != null) {
+            logger.info("Found a valid ClusterManager, now let it be stopped");
+            this.cm.stop();
+            this.cm = null;
+        }
+        if (this.gossiper != null) {
+            this.gossiper.stop();
+            this.gossiper = null;
+        }
+    }
+
+    @Override
+    public ConcurrentMap<?, ?> createCache(String containerName,
+            String cacheName, Set<cacheMode> cMode) throws CacheExistException,
+            CacheConfigException {
+        EmbeddedCacheManager manager = this.cm;
+        Cache c;
+        String realCacheName = "{" + containerName + "}_{" + cacheName + "}";
+        if (manager == null) {
+            return null;
+        }
+
+        if (manager.cacheExists(realCacheName)) {
+            throw new CacheExistException();
+        }
+
+        // Sanity check to avoid contrasting parameters
+        if (cMode.containsAll(EnumSet.of(
+                IClusterServices.cacheMode.NON_TRANSACTIONAL,
+                IClusterServices.cacheMode.TRANSACTIONAL))) {
+            throw new CacheConfigException();
+        }
+
+        if (cMode.contains(IClusterServices.cacheMode.NON_TRANSACTIONAL)) {
+            c = manager.getCache(realCacheName);
+            return c;
+        } else if (cMode.contains(IClusterServices.cacheMode.TRANSACTIONAL)) {
+            Configuration rc = manager
+                    .getCacheConfiguration("transactional-type");
+            manager.defineConfiguration(realCacheName, rc);
+            c = manager.getCache(realCacheName);
+            return c;
+        }
+        return null;
+    }
+
+    @Override
+    public ConcurrentMap<?, ?> getCache(String containerName, String cacheName) {
+        EmbeddedCacheManager manager = this.cm;
+        Cache c;
+        String realCacheName = "{" + containerName + "}_{" + cacheName + "}";
+        if (manager == null) {
+            return null;
+        }
+
+        if (manager.cacheExists(realCacheName)) {
+            c = manager.getCache(realCacheName);
+            return c;
+        }
+        return null;
+    }
+
+    @Override
+    public void destroyCache(String containerName, String cacheName) {
+        EmbeddedCacheManager manager = this.cm;
+        String realCacheName = "{" + containerName + "}_{" + cacheName + "}";
+        if (manager == null) {
+            return;
+        }
+        if (manager.cacheExists(realCacheName)) {
+            manager.removeCache(realCacheName);
+        }
+    }
+
+    @Override
+    public boolean existCache(String containerName, String cacheName) {
+        EmbeddedCacheManager manager = this.cm;
+        String realCacheName = "{" + containerName + "}_{" + cacheName + "}";
+        if (manager == null) {
+            return false;
+        }
+        return manager.cacheExists(realCacheName);
+    }
+
+    @Override
+    public Set<String> getCacheList(String containerName) {
+        Set<String> perContainerCaches = new HashSet();
+        EmbeddedCacheManager manager = this.cm;
+        if (manager == null) {
+            return null;
+        }
+        for (String cacheName : manager.getCacheNames()) {
+            if (cacheName.startsWith("{" + containerName + "}_")) {
+                String[] res = cacheName.split("[{}]");
+                if (res.length >= 4 && res[1].equals(containerName)
+                        && res[2].equals("_")) {
+                    perContainerCaches.add(res[3]);
+                }
+            }
+        }
+
+        return (perContainerCaches);
+    }
+
+    @Override
+    public Properties getCacheProperties(String containerName, String cacheName) {
+        EmbeddedCacheManager manager = this.cm;
+        if (manager == null) {
+            return null;
+        }
+        String realCacheName = "{" + containerName + "}_{" + cacheName + "}";
+        if (!manager.cacheExists(realCacheName)) {
+            return null;
+        }
+        Configuration conf = manager.getCache(realCacheName).getAdvancedCache()
+                .getCacheConfiguration();
+        Properties p = new Properties();
+        p.setProperty(IClusterServices.cacheProps.TRANSACTION_PROP.toString(),
+                conf.transaction().toString());
+        p.setProperty(IClusterServices.cacheProps.CLUSTERING_PROP.toString(),
+                conf.clustering().toString());
+        p.setProperty(IClusterServices.cacheProps.LOCKING_PROP.toString(), conf
+                .locking().toString());
+        return p;
+    }
+
+    @Override
+    public void addListener(String containerName, String cacheName,
+            IGetUpdates<?, ?> u) throws CacheListenerAddException {
+        EmbeddedCacheManager manager = this.cm;
+        Cache c;
+        String realCacheName = "{" + containerName + "}_{" + cacheName + "}";
+        if (manager == null) {
+            return;
+        }
+
+        if (!manager.cacheExists(realCacheName)) {
+            throw new CacheListenerAddException();
+        }
+        c = manager.getCache(realCacheName);
+        CacheListenerContainer cl = new CacheListenerContainer(u,
+                containerName, cacheName);
+        if (cl == null) {
+            throw new CacheListenerAddException();
+        }
+        c.addListener(cl);
+    }
+
+    @Override
+    public Set<IGetUpdates<?, ?>> getListeners(String containerName,
+            String cacheName) {
+        EmbeddedCacheManager manager = this.cm;
+        Cache c;
+        String realCacheName = "{" + containerName + "}_{" + cacheName + "}";
+        if (manager == null) {
+            return null;
+        }
+
+        if (!manager.cacheExists(realCacheName)) {
+            return null;
+        }
+        c = manager.getCache(realCacheName);
+
+        Set<IGetUpdates<?, ?>> res = new HashSet();
+        Set<Object> listeners = c.getListeners();
+        for (Object listener : listeners) {
+            if (listener instanceof CacheListenerContainer) {
+                CacheListenerContainer cl = (CacheListenerContainer) listener;
+                res.add(cl.whichListener());
+            }
+        }
+
+        return res;
+    }
+
+    @Override
+    public void removeListener(String containerName, String cacheName,
+            IGetUpdates<?, ?> u) {
+        EmbeddedCacheManager manager = this.cm;
+        Cache c;
+        String realCacheName = "{" + containerName + "}_{" + cacheName + "}";
+        if (manager == null) {
+            return;
+        }
+
+        if (!manager.cacheExists(realCacheName)) {
+            return;
+        }
+        c = manager.getCache(realCacheName);
+
+        Set<Object> listeners = c.getListeners();
+        for (Object listener : listeners) {
+            if (listener instanceof CacheListenerContainer) {
+                CacheListenerContainer cl = (CacheListenerContainer) listener;
+                if (cl.whichListener() == u) {
+                    c.removeListener(listener);
+                    return;
+                }
+            }
+        }
+    }
+
+    @Override
+    public void tbegin() throws NotSupportedException, SystemException {
+        EmbeddedCacheManager manager = this.cm;
+        if (manager == null) {
+            throw new IllegalStateException();
+        }
+        TransactionManager tm = manager.getCache("transactional-type")
+                .getAdvancedCache().getTransactionManager();
+        if (tm == null) {
+            throw new IllegalStateException();
+        }
+        tm.begin();
+    }
+
+    @Override
+    public void tcommit() throws RollbackException, HeuristicMixedException,
+            HeuristicRollbackException, java.lang.SecurityException,
+            java.lang.IllegalStateException, SystemException {
+        EmbeddedCacheManager manager = this.cm;
+        if (manager == null) {
+            throw new IllegalStateException();
+        }
+        TransactionManager tm = manager.getCache("transactional-type")
+                .getAdvancedCache().getTransactionManager();
+        if (tm == null) {
+            throw new IllegalStateException();
+        }
+        tm.commit();
+    }
+
+    @Override
+    public void trollback() throws java.lang.IllegalStateException,
+            java.lang.SecurityException, SystemException {
+        EmbeddedCacheManager manager = this.cm;
+        if (manager == null) {
+            throw new IllegalStateException();
+        }
+        TransactionManager tm = manager.getCache("transactional-type")
+                .getAdvancedCache().getTransactionManager();
+        if (tm == null) {
+            throw new IllegalStateException();
+        }
+        tm.rollback();
+    }
+
+    @Override
+    public Transaction tgetTransaction() throws SystemException {
+        EmbeddedCacheManager manager = this.cm;
+        if (manager == null) {
+            throw new IllegalStateException();
+        }
+        TransactionManager tm = manager.getCache("transactional-type")
+                .getAdvancedCache().getTransactionManager();
+        if (tm == null) {
+            return null;
+        }
+        return tm.getTransaction();
+    }
+
+    @Override
+    public boolean amIStandby() {
+        EmbeddedCacheManager manager = this.cm;
+        if (manager == null) {
+            // In case we cannot fetch the information, lets assume we
+            // are standby, so to have less responsability.
+            return true;
+        }
+        return (!manager.isCoordinator());
+    }
+
+    private InetAddress addressToInetAddress(Address a) {
+        EmbeddedCacheManager manager = this.cm;
+        if ((manager == null) || (a == null)) {
+            // In case we cannot fetch the information, lets assume we
+            // are standby, so to have less responsability.
+            return null;
+        }
+        Transport t = manager.getTransport();
+        if (t instanceof JGroupsTransport) {
+            JGroupsTransport jt = (JGroupsTransport) t;
+            Channel c = jt.getChannel();
+            if (a instanceof JGroupsAddress) {
+                JGroupsAddress ja = (JGroupsAddress) a;
+                org.jgroups.Address phys = (org.jgroups.Address) c
+                        .down(new Event(Event.GET_PHYSICAL_ADDRESS, ja
+                                .getJGroupsAddress()));
+                if (phys instanceof org.jgroups.stack.IpAddress) {
+                    InetAddress bindAddress = ((org.jgroups.stack.IpAddress) phys)
+                            .getIpAddress();
+                    return bindAddress;
+                }
+            }
+        }
+        return null;
+    }
+
+    public List<InetAddress> getClusteredControllers() {
+        EmbeddedCacheManager manager = this.cm;
+        if (manager == null) {
+            return null;
+        }
+        List<Address> controllers = manager.getMembers();
+        if ((controllers == null) || controllers.size() == 0)
+            return null;
+
+        List<InetAddress> clusteredControllers = new ArrayList<InetAddress>();
+        for (Address a : controllers) {
+            InetAddress inetAddress = addressToInetAddress(a);
+            if (inetAddress != null
+                    && !inetAddress.getHostAddress().equals(loopbackAddress))
+                clusteredControllers.add(inetAddress);
+        }
+        return clusteredControllers;
+    }
+
+    public InetAddress getMyAddress() {
+        EmbeddedCacheManager manager = this.cm;
+        if (manager == null) {
+            return null;
+        }
+        return addressToInetAddress(manager.getAddress());
+    }
+
+    @Override
+    public InetAddress getActiveAddress() {
+        EmbeddedCacheManager manager = this.cm;
+        if (manager == null) {
+            // In case we cannot fetch the information, lets assume we
+            // are standby, so to have less responsability.
+            return null;
+        }
+
+        return addressToInetAddress(manager.getCoordinator());
+    }
+
+    @Override
+    public void listenRoleChange(IListenRoleChange i)
+            throws ListenRoleChangeAddException {
+        EmbeddedCacheManager manager = this.cm;
+        if (manager == null) {
+            // In case we cannot fetch the information, lets assume we
+            // are standby, so to have less responsability.
+            throw new ListenRoleChangeAddException();
+        }
+
+        if (this.roleChangeListeners == null) {
+            this.roleChangeListeners = new HashSet();
+            this.cacheManagerListener = new ViewChangedListener(
+                    this.roleChangeListeners);
+            manager.addListener(this.cacheManagerListener);
+        }
+
+        if (this.roleChangeListeners != null) {
+            this.roleChangeListeners.add(i);
+        }
+    }
+
+    @Override
+    public void unlistenRoleChange(IListenRoleChange i) {
+        EmbeddedCacheManager manager = this.cm;
+        if (manager == null) {
+            // In case we cannot fetch the information, lets assume we
+            // are standby, so to have less responsability.
+            return;
+        }
+
+        if (this.roleChangeListeners != null) {
+            this.roleChangeListeners.remove(i);
+        }
+
+        if ((this.roleChangeListeners != null && this.roleChangeListeners
+                .isEmpty())
+                && (this.cacheManagerListener != null)) {
+            manager.removeListener(this.cacheManagerListener);
+            this.cacheManagerListener = null;
+            this.roleChangeListeners = null;
+        }
+    }
+
+    @Listener
+    public class ViewChangedListener {
+        Set<IListenRoleChange> roleListeners;
+
+        public ViewChangedListener(Set<IListenRoleChange> s) {
+            this.roleListeners = s;
+        }
+
+        @ViewChanged
+        public void viewChanged(ViewChangedEvent e) {
+            for (IListenRoleChange i : this.roleListeners) {
+                i.newActiveAvailable();
+            }
+        }
+    }
+}
diff --git a/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManagerCommon.java b/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManagerCommon.java
new file mode 100644 (file)
index 0000000..2afbabe
--- /dev/null
@@ -0,0 +1,282 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.services_implementation.internal;
+
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.CacheListenerAddException;
+import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.clustering.services.IClusterServicesCommon;
+import org.opendaylight.controller.clustering.services.ICoordinatorChangeAware;
+import org.opendaylight.controller.clustering.services.IListenRoleChange;
+import org.opendaylight.controller.clustering.services.ListenRoleChangeAddException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Dictionary;
+import java.util.Collections;
+import java.util.HashSet;
+import org.apache.felix.dm.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+abstract public class ClusterManagerCommon implements IClusterServicesCommon {
+    protected String containerName = null;
+    private IClusterServices clusterService = null;
+    protected static final Logger logger = LoggerFactory
+            .getLogger(ClusterManagerCommon.class);
+    private Set<ICacheUpdateAware> cacheUpdateAware = Collections
+            .synchronizedSet(new HashSet<ICacheUpdateAware>());
+    private Set<ICoordinatorChangeAware> coordinatorChangeAware = Collections
+            .synchronizedSet(new HashSet<ICoordinatorChangeAware>());
+    private ListenCoordinatorChange coordinatorChangeListener = null;
+
+    /**
+     * Class needed to listen to the role changes from the cluster
+     * manager and to pass it along to the other components that
+     * export the interface ICoordinatorChangeAware
+     */
+    class ListenCoordinatorChange implements IListenRoleChange {
+        public void newActiveAvailable() {
+            if (coordinatorChangeAware != null) {
+                // Make sure to look the set while walking it
+                synchronized (coordinatorChangeAware) {
+                    for (ICoordinatorChangeAware s : coordinatorChangeAware) {
+                        // Now walk every instance and signal that the
+                        // coordinator has changed
+                        s.coordinatorChanged();
+                    }
+                }
+            }
+        }
+    }
+
+    void setCoordinatorChangeAware(ICoordinatorChangeAware s) {
+        if (this.coordinatorChangeAware != null) {
+            this.coordinatorChangeAware.add(s);
+        }
+    }
+
+    void unsetCoordinatorChangeAware(ICoordinatorChangeAware s) {
+        if (this.coordinatorChangeAware != null) {
+            this.coordinatorChangeAware.remove(s);
+        }
+    }
+
+    void setCacheUpdateAware(ICacheUpdateAware s) {
+        if (this.cacheUpdateAware != null) {
+            this.cacheUpdateAware.add(s);
+        }
+    }
+
+    void unsetCacheUpdateAware(ICacheUpdateAware s) {
+        if (this.cacheUpdateAware != null) {
+            this.cacheUpdateAware.remove(s);
+        }
+    }
+
+    public void setClusterService(IClusterServices s) {
+        this.clusterService = s;
+    }
+
+    public void unsetClusterServices(IClusterServices s) {
+        if (this.clusterService == s) {
+            this.clusterService = null;
+        }
+    }
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init(Component c) {
+        Dictionary props = c.getServiceProperties();
+        if (props != null) {
+            this.containerName = (String) props.get("containerName");
+            logger.debug("Running containerName:" + this.containerName);
+        } else {
+            // In the Global instance case the containerName is empty
+            this.containerName = "";
+        }
+        if (this.clusterService != null) {
+            this.coordinatorChangeListener = new ListenCoordinatorChange();
+            try {
+                this.clusterService
+                        .listenRoleChange(this.coordinatorChangeListener);
+                logger.debug("Coordinator change handler registered");
+            } catch (ListenRoleChangeAddException ex) {
+                logger.error("Could not register coordinator change");
+            }
+        }
+    }
+
+    /**
+     * Function called by the dependency manager when any of the required
+     * dependencies are going away
+     *
+     */
+    void destroy() {
+        if (this.clusterService != null
+                && this.coordinatorChangeListener != null) {
+            this.clusterService
+                    .unlistenRoleChange(this.coordinatorChangeListener);
+            this.coordinatorChangeListener = null;
+            logger.debug("Coordinator change handler UNregistered");
+        }
+    }
+
+    @Override
+    public ConcurrentMap<?, ?> createCache(String cacheName,
+            Set<IClusterServices.cacheMode> cMode) throws CacheExistException,
+            CacheConfigException {
+        if (this.clusterService != null) {
+            return this.clusterService.createCache(this.containerName,
+                    cacheName, cMode);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public ConcurrentMap<?, ?> getCache(String cacheName) {
+        if (this.clusterService != null) {
+            return this.clusterService.getCache(this.containerName, cacheName);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public void destroyCache(String cacheName) {
+        if (this.clusterService != null) {
+            this.clusterService.destroyCache(this.containerName, cacheName);
+        }
+    }
+
+    @Override
+    public boolean existCache(String cacheName) {
+        if (this.clusterService != null) {
+            return this.clusterService
+                    .existCache(this.containerName, cacheName);
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public Set<String> getCacheList() {
+        if (this.clusterService != null) {
+            return this.clusterService.getCacheList(this.containerName);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public Properties getCacheProperties(String cacheName) {
+        if (this.clusterService != null) {
+            return this.clusterService.getCacheProperties(this.containerName,
+                    cacheName);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public void tbegin() throws NotSupportedException, SystemException {
+        if (this.clusterService != null) {
+            this.clusterService.tbegin();
+        } else {
+            throw new IllegalStateException();
+        }
+    }
+
+    @Override
+    public void tcommit() throws RollbackException, HeuristicMixedException,
+            HeuristicRollbackException, java.lang.SecurityException,
+            java.lang.IllegalStateException, SystemException {
+        if (this.clusterService != null) {
+            this.clusterService.tcommit();
+        } else {
+            throw new IllegalStateException();
+        }
+    }
+
+    @Override
+    public void trollback() throws java.lang.IllegalStateException,
+            java.lang.SecurityException, SystemException {
+        if (this.clusterService != null) {
+            this.clusterService.trollback();
+        } else {
+            throw new IllegalStateException();
+        }
+    }
+
+    @Override
+    public Transaction tgetTransaction() throws SystemException {
+        if (this.clusterService != null) {
+            return this.clusterService.tgetTransaction();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public List<InetAddress> getClusteredControllers() {
+        if (this.clusterService != null) {
+            return this.clusterService.getClusteredControllers();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public InetAddress getMyAddress() {
+        if (this.clusterService != null) {
+            return this.clusterService.getMyAddress();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public InetAddress getCoordinatorAddress() {
+        if (this.clusterService != null) {
+            return this.clusterService.getActiveAddress();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean amICoordinator() {
+        if (this.clusterService != null) {
+            return (!this.clusterService.amIStandby());
+        } else {
+            return false;
+        }
+    }
+}
diff --git a/opendaylight/clustering/services_implementation/src/main/resources/OSGI-INF/component-cachemanager.xml b/opendaylight/clustering/services_implementation/src/main/resources/OSGI-INF/component-cachemanager.xml
new file mode 100644 (file)
index 0000000..f3baf79
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"
+               activate="start"
+               deactivate="stop"
+               immediate="true"
+               name="org.opendaylight.controller.clustering.services_implementation.internal.ClusterManager">
+  <implementation class="org.opendaylight.controller.clustering.services_implementation.internal.ClusterManager"/>
+  <service>
+    <provide interface="org.opendaylight.controller.clustering.services.IClusterServices"/>
+  </service>
+</scr:component>
diff --git a/opendaylight/clustering/services_implementation/src/main/resources/config/infinispan-config.xml b/opendaylight/clustering/services_implementation/src/main/resources/config/infinispan-config.xml
new file mode 100644 (file)
index 0000000..96eff96
--- /dev/null
@@ -0,0 +1,38 @@
+<infinispan xsi:schemaLocation="urn:infinispan:config:5.1 http://www.infinispan.org/schemas/infinispan-config-5.1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:infinispan:config:5.1">
+  <global>
+    <transport>
+      <properties>
+        <property name="configurationFile" value="/config/jgroups.xml"/>
+      </properties>
+    </transport>
+    <!-- Enable JMX statistics -->
+    <globalJmxStatistics
+        enabled="true"
+        jmxDomain="org.infinispan"
+        cacheManagerName="SampleCacheManager"/>
+  </global>
+  <default>
+    <!-- Configure a synchronous replication cache -->
+    <clustering mode="replication">
+      <sync/>
+    </clustering>
+    <!--
+        Used to register JMX statistics in any available MBean server
+    -->
+    <jmxStatistics enabled="true"/>    
+  </default>
+  <!-- transactionManagerLookupClass="org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup" -->
+  <namedCache name="transactional-type">
+    <transaction
+        transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"
+        syncRollbackPhase="false"
+        syncCommitPhase="false"
+        cacheStopTimeout="30000"
+        use1PcForAutoCommitTransactions="false"
+        autoCommit="true"
+        lockingMode="OPTIMISTIC"
+        useSynchronization="false"
+        transactionMode="TRANSACTIONAL"
+        />
+  </namedCache>
+</infinispan>
diff --git a/opendaylight/clustering/services_implementation/src/main/resources/config/jgroups.xml b/opendaylight/clustering/services_implementation/src/main/resources/config/jgroups.xml
new file mode 100644 (file)
index 0000000..b1dc033
--- /dev/null
@@ -0,0 +1,77 @@
+<!--
+    TCP based stack, with flow control and message bundling. This is usually used when IP
+    multicasting cannot be used in a network, e.g. because it is disabled (routers discard multicast).
+    Note that TCP.bind_addr and TCPPING.initial_hosts should be set, possibly via system properties, e.g.
+    -Djgroups.bind_addr=192.168.5.2 and -Djgroups.tcpping.initial_hosts=192.168.5.2[7800]".
+    author: Bela Ban
+-->
+<config xmlns="urn:org:jgroups"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/JGroups-3.0.xsd">
+
+  <TCP loopback="true"
+       bind_addr="${jgroups.tcp.address:127.0.0.1}"
+       bind_port="${jgroups.tcp.port:7800}"
+       recv_buf_size="${tcp.recv_buf_size:20M}"
+       send_buf_size="${tcp.send_buf_size:640K}"
+       discard_incompatible_packets="true"
+       max_bundle_size="64K"
+       max_bundle_timeout="30"
+       enable_bundling="true"
+       use_send_queues="true"
+       sock_conn_timeout="300"
+       timer_type="new"
+       timer.min_threads="4"
+       timer.max_threads="10"
+       timer.keep_alive_time="3000"
+       timer.queue_max_size="500"
+       thread_pool.enabled="true"
+       thread_pool.min_threads="2"
+       thread_pool.max_threads="30"
+       thread_pool.keep_alive_time="60000"
+       thread_pool.queue_enabled="false"
+       thread_pool.queue_max_size="100"
+       thread_pool.rejection_policy="discard"
+       oob_thread_pool.enabled="true"
+       oob_thread_pool.min_threads="2"
+       oob_thread_pool.max_threads="30"
+       oob_thread_pool.keep_alive_time="60000"
+       oob_thread_pool.queue_enabled="false"
+       oob_thread_pool.queue_max_size="100"
+       oob_thread_pool.rejection_policy="discard"/>
+
+    <!-- <TCP_NIO -->
+    <!--         bind_port="7800" -->
+    <!--         bind_interface="${jgroups.tcp_nio.bind_interface:bond0}" -->
+    <!--         use_send_queues="true" -->
+    <!--         sock_conn_timeout="300" -->
+    <!--         reader_threads="3" -->
+    <!--         writer_threads="3" -->
+    <!--         processor_threads="0" -->
+    <!--         processor_minThreads="0" -->
+    <!--         processor_maxThreads="0" -->
+    <!--         processor_queueSize="100" -->
+    <!--         processor_keepAliveTime="9223372036854775807"/> -->
+    <TCPGOSSIP initial_hosts="${jgroups.tcpgossip.initial_hosts}"/>
+    <!-- <TCPPING initial_hosts="${jgroups.tcpping.initial_hosts}" -->
+    <!--          port_range="0" -->
+    <!--          timeout="3000" -->
+    <!--          /> -->
+    <MERGE2 max_interval="30000" min_interval="10000"/>
+    <FD_SOCK/>
+    <FD timeout="3000" max_tries="3"/>
+    <VERIFY_SUSPECT timeout="1500"/>
+    <pbcast.NAKACK
+        use_mcast_xmit="false"
+        retransmit_timeout="300,600,1200,2400,4800"
+        discard_delivered_msgs="false"/>
+    <UNICAST2 timeout="300,600,1200"
+              stable_interval="5000"
+              max_bytes="1m"/>
+    <pbcast.STABLE stability_delay="500" desired_avg_gossip="5000" max_bytes="1m"/>
+    <pbcast.GMS print_local_addr="false" join_timeout="3000" view_bundling="true"/>
+    <UFC max_credits="200k" min_threshold="0.20"/>
+    <MFC max_credits="200k" min_threshold="0.20"/>
+    <FRAG2 frag_size="60000"/>
+    <RSVP timeout="60000" resend_interval="500" ack_on_delivery="false" />
+</config>
diff --git a/opendaylight/clustering/stub/pom.xml b/opendaylight/clustering/stub/pom.xml
new file mode 100644 (file)
index 0000000..2670c72
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.0-SNAPSHOT</version>
+    <relativePath>../../commons/opendaylight</relativePath>
+  </parent>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>clustering.stub</artifactId>
+  <version>0.4.0-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>2.3.6</version>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Import-Package>
+              javax.transaction,
+              org.apache.felix.dm,
+              org.slf4j,
+              org.opendaylight.controller.clustering.services,
+              org.opendaylight.controller.sal.core
+            </Import-Package>
+            <Bundle-Activator>
+              org.opendaylight.controller.clustering.stub.internal.Activator
+            </Bundle-Activator>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>clustering.services</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/Activator.java b/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/Activator.java
new file mode 100644 (file)
index 0000000..e73155a
--- /dev/null
@@ -0,0 +1,108 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.stub.internal;
+
+import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
+
+import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.clustering.services.ICoordinatorChangeAware;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.felix.dm.Component;
+
+public class Activator extends ComponentActivatorAbstractBase {
+    protected static final Logger logger = LoggerFactory
+            .getLogger(Activator.class);
+
+    /**
+     * Function called when the activator starts just after some
+     * initializations are done by the
+     * ComponentActivatorAbstractBase.
+     *
+     */
+    public void init() {
+    }
+
+    /**
+     * Function called when the activator stops just before the
+     * cleanup done by ComponentActivatorAbstractBase
+     *
+     */
+    public void destroy() {
+    }
+
+    /**
+     * Function that is used to communicate to dependency manager the
+     * list of known implementations for services inside a container
+     *
+     *
+     * @return An array containing all the CLASS objects that will be
+     * instantiated in order to get an fully working implementation
+     * Object
+     */
+    public Object[] getGlobalImplementations() {
+        Object[] res = { ClusterGlobalManager.class };
+        return res;
+    }
+
+    /**
+     * Function that is used to communicate to dependency manager the
+     * list of known implementations for services inside a container
+     *
+     *
+     * @return An array containing all the CLASS objects that will be
+     * instantiated in order to get an fully working implementation
+     * Object
+     */
+    public Object[] getImplementations() {
+        Object[] res = { ClusterContainerManager.class };
+        return res;
+    }
+
+    /**
+     * Function that is called when configuration of the dependencies
+     * is required.
+     *
+     * @param c dependency manager Component object, used for
+     * configuring the dependencies exported and imported
+     * @param imp Implementation class that is being configured,
+     * needed as long as the same routine can configure multiple
+     * implementations
+     * @param containerName The containerName being configured, this allow
+     * also optional per-container different behavior if needed, usually
+     * should not be the case though.
+     */
+    public void configureInstance(Component c, Object imp, String containerName) {
+        if (imp.equals(ClusterContainerManager.class)) {
+            c.setInterface(new String[] { IClusterContainerServices.class
+                    .getName() }, null);
+        }
+    }
+
+    /**
+     * Function that is called when configuration of the dependencies
+     * is required.
+     *
+     * @param c dependency manager Component object, used for
+     * configuring the dependencies exported and imported
+     * @param imp Implementation class that is being configured,
+     * needed as long as the same routine can configure multiple
+     * implementations
+     */
+    public void configureGlobalInstance(Component c, Object imp) {
+        if (imp.equals(ClusterGlobalManager.class)) {
+            c.setInterface(new String[] { IClusterGlobalServices.class
+                    .getName() }, null);
+        }
+    }
+}
diff --git a/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterContainerManager.java b/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterContainerManager.java
new file mode 100644 (file)
index 0000000..627db22
--- /dev/null
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.stub.internal;
+
+import java.net.UnknownHostException;
+
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+
+public class ClusterContainerManager extends ClusterManagerCommon implements
+        IClusterContainerServices {
+    public ClusterContainerManager() throws UnknownHostException {
+        super();
+    }
+}
diff --git a/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterGlobalManager.java b/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterGlobalManager.java
new file mode 100644 (file)
index 0000000..f9f9be8
--- /dev/null
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.stub.internal;
+
+import java.net.UnknownHostException;
+
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+
+public class ClusterGlobalManager extends ClusterManagerCommon implements
+        IClusterGlobalServices {
+    public ClusterGlobalManager() throws UnknownHostException {
+        super();
+    }
+}
diff --git a/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterManagerCommon.java b/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterManagerCommon.java
new file mode 100644 (file)
index 0000000..13d05bb
--- /dev/null
@@ -0,0 +1,164 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.stub.internal;
+
+import java.util.ArrayList;
+import java.util.concurrent.ConcurrentHashMap;
+import java.net.UnknownHostException;
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.CacheListenerAddException;
+import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.clustering.services.IClusterServicesCommon;
+import org.opendaylight.controller.clustering.services.ICoordinatorChangeAware;
+import org.opendaylight.controller.clustering.services.IListenRoleChange;
+import org.opendaylight.controller.clustering.services.ListenRoleChangeAddException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Dictionary;
+import java.util.Collections;
+import java.util.HashSet;
+import org.apache.felix.dm.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+abstract public class ClusterManagerCommon implements IClusterServicesCommon {
+    protected String containerName = "";
+    protected static final Logger logger = LoggerFactory
+            .getLogger(ClusterManagerCommon.class);
+    private InetAddress loopbackAddress;
+    private ConcurrentMap<String, ConcurrentMap<?, ?>> caches = new ConcurrentHashMap<String, ConcurrentMap<?, ?>>();
+
+    protected ClusterManagerCommon() throws UnknownHostException {
+        loopbackAddress = InetAddress.getByName("127.0.0.1");
+    }
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init(Component c) {
+        Dictionary props = c.getServiceProperties();
+        if (props != null) {
+            this.containerName = (String) props.get("containerName");
+            logger.debug("Running containerName:" + this.containerName);
+        } else {
+            // In the Global instance case the containerName is empty
+            this.containerName = "";
+        }
+    }
+
+    /**
+     * Function called by the dependency manager when any of the required
+     * dependencies are going away
+     *
+     */
+    void destroy() {
+        // Clear the caches, will restart on the new life
+        this.caches.clear();
+    }
+
+    @Override
+    public ConcurrentMap<?, ?> createCache(String cacheName,
+            Set<IClusterServices.cacheMode> cMode) throws CacheExistException,
+            CacheConfigException {
+        ConcurrentMap<?, ?> res = this.caches.get(cacheName);
+        if (res == null) {
+            res = new ConcurrentHashMap();
+            this.caches.put(cacheName, res);
+            return res;
+        }
+        throw new CacheExistException();
+    }
+
+    @Override
+    public ConcurrentMap<?, ?> getCache(String cacheName) {
+        return this.caches.get(cacheName);
+    }
+
+    @Override
+    public void destroyCache(String cacheName) {
+        this.caches.remove(cacheName);
+    }
+
+    @Override
+    public boolean existCache(String cacheName) {
+        return (this.caches.get(cacheName) != null);
+    }
+
+    @Override
+    public Set<String> getCacheList() {
+        return this.caches.keySet();
+    }
+
+    @Override
+    public Properties getCacheProperties(String cacheName) {
+        return null;
+    }
+
+    @Override
+    public void tbegin() throws NotSupportedException, SystemException {
+    }
+
+    @Override
+    public void tcommit() throws RollbackException, HeuristicMixedException,
+            HeuristicRollbackException, java.lang.SecurityException,
+            java.lang.IllegalStateException, SystemException {
+    }
+
+    @Override
+    public void trollback() throws java.lang.IllegalStateException,
+            java.lang.SecurityException, SystemException {
+    }
+
+    @Override
+    public Transaction tgetTransaction() throws SystemException {
+        return null;
+    }
+
+    @Override
+    public List<InetAddress> getClusteredControllers() {
+        List<InetAddress> res = new ArrayList<InetAddress>();
+        res.add(loopbackAddress);
+        return res;
+    }
+
+    @Override
+    public InetAddress getMyAddress() {
+        return loopbackAddress;
+    }
+
+    @Override
+    public InetAddress getCoordinatorAddress() {
+        return loopbackAddress;
+    }
+
+    @Override
+    public boolean amICoordinator() {
+        return true;
+    }
+}
diff --git a/opendaylight/clustering/stub/src/test/java/org/opendaylight/controller/clustering/stub/internal/TestClusteringStub.java b/opendaylight/clustering/stub/src/test/java/org/opendaylight/controller/clustering/stub/internal/TestClusteringStub.java
new file mode 100644 (file)
index 0000000..af1daae
--- /dev/null
@@ -0,0 +1,202 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   TestClusteringStub.java
+ *
+ * @brief  Unit tests for the stub implementation of clustering,
+ * needed only to run the integration tests
+ *
+ * Unit tests for the stub implementation of clustering,
+ * needed only to run the integration tests
+ */
+package org.opendaylight.controller.clustering.stub.internal;
+
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import java.net.UnknownHostException;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+import org.opendaylight.controller.clustering.stub.internal.ClusterGlobalManager;
+
+public class TestClusteringStub {
+    @Test
+    public void testStub1() {
+        IClusterGlobalServices c = null;
+        ClusterGlobalManager cm = null;
+        try {
+            cm = new ClusterGlobalManager();
+            c = (IClusterGlobalServices) cm;
+        } catch (UnknownHostException un) {
+            // Don't expect this assertion, so if happens signal a
+            // failure in the testcase
+            Assert.assertTrue(false);
+        }
+
+        // Make sure the stub cluster manager is allocated
+        Assert.assertTrue(cm != null);
+        Assert.assertTrue(c != null);
+
+        // ========================================
+        // Now start testing the several aspects of it.
+        // ========================================
+
+        // Allocate few caches
+        ConcurrentMap<String, Integer> c1 = null;
+        ConcurrentMap<String, Integer> c2 = null;
+        ConcurrentMap<String, Integer> c3 = null;
+        try {
+            c1 = (ConcurrentMap<String, Integer>) c.createCache("c1", null);
+        } catch (CacheExistException cee) {
+            // Don't expect this assertion, so if happens signal a
+            // failure in the testcase
+            Assert.assertTrue(false);
+        } catch (CacheConfigException cce) {
+            // Don't expect this assertion, so if happens signal a
+            // failure in the testcase
+            Assert.assertTrue(false);
+        }
+
+        // Put some data to it
+        c1.put("FOO", 1);
+        c1.put("BAZ", 2);
+        c1.put("BAR", 3);
+
+        try {
+            c1 = (ConcurrentMap<String, Integer>) c.createCache("c1", null);
+        } catch (CacheExistException cee) {
+            // This exception should be raised because the cache
+            // already exists
+            Assert.assertTrue(true);
+        } catch (CacheConfigException cce) {
+            // Don't expect this assertion, so if happens signal a
+            // failure in the testcase
+            Assert.assertTrue(false);
+        }
+
+        // Make sure this cache is retrieved
+        c1 = (ConcurrentMap<String, Integer>) c.getCache("c1");
+        Assert.assertTrue(c1 != null);
+
+        // Now make sure the data exists
+        Integer res = null;
+        res = c1.get("FOO");
+        Assert.assertTrue(res != null);
+        res = c1.get("BAR");
+        Assert.assertTrue(res != null);
+        res = c1.get("BAZ");
+        Assert.assertTrue(res != null);
+
+        // Now create yet another two caches
+        try {
+            c2 = (ConcurrentMap<String, Integer>) c.createCache("c2", null);
+            c3 = (ConcurrentMap<String, Integer>) c.createCache("c3", null);
+        } catch (CacheExistException cee) {
+            // Don't expect this assertion, so if happens signal a
+            // failure in the testcase
+            Assert.assertTrue(false);
+        } catch (CacheConfigException cce) {
+            // Don't expect this assertion, so if happens signal a
+            // failure in the testcase
+            Assert.assertTrue(false);
+        }
+
+        // Make sure the caches exist
+        Assert.assertTrue(c2 != null);
+        Assert.assertTrue(c3 != null);
+
+        // Put some fake data
+        c2.put("FOO", 11);
+        c2.put("BAZ", 22);
+        c2.put("BAR", 33);
+
+        c3.put("FOOBAR", 110);
+
+        // Test for cache existance
+        Assert.assertTrue(c.existCache("c1"));
+        Assert.assertTrue(c.existCache("c2"));
+        Assert.assertTrue(c.existCache("c3"));
+
+        // Get the Cache List
+        Set<String> caches = c.getCacheList();
+        Assert.assertTrue(caches != null);
+
+        // Check if the cachelist is correct
+        System.out.println("cache size:" + caches.size());
+        Assert.assertTrue(caches.size() == 3);
+        Assert.assertTrue(caches.contains("c1"));
+        Assert.assertTrue(caches.contains("c2"));
+        Assert.assertTrue(caches.contains("c3"));
+
+        // Check that the utility API for the cluster are working too
+        Assert.assertTrue(c.getCoordinatorAddress() != null);
+        Assert.assertTrue(c.getClusteredControllers() != null);
+        // This a one man-show
+        Assert.assertTrue(c.getClusteredControllers().size() == 1);
+        Assert.assertTrue(c.getMyAddress() != null);
+        // Make sure i'm the coordinator
+        Assert.assertTrue(c.amICoordinator());
+
+        // Now destroy some caches make sure they are gone
+        c.destroyCache("c1");
+        Assert.assertTrue(!c.existCache("c1"));
+        caches = c.getCacheList();
+        Assert.assertTrue(caches.size() == 2);
+
+        // Now recreate the cache, make sure a different one is
+        // retrieved, which should be empty
+        try {
+            c1 = (ConcurrentMap<String, Integer>) c.createCache("c1", null);
+        } catch (CacheExistException cee) {
+            // This exception should be raised because the cache
+            // already exists
+            Assert.assertTrue(true);
+        } catch (CacheConfigException cce) {
+            // Don't expect this assertion, so if happens signal a
+            // failure in the testcase
+            Assert.assertTrue(false);
+        }
+        c1 = (ConcurrentMap<String, Integer>) c.getCache("c1");
+        Assert.assertTrue(c1 != null);
+        Assert.assertTrue(c1.keySet().size() == 0);
+        caches = c.getCacheList();
+        Assert.assertTrue(caches.size() == 3);
+
+        // Now destroy the cache manager and make sure things are
+        // clean
+        cm.destroy();
+        caches = c.getCacheList();
+        Assert.assertTrue(caches.size() == 0);
+
+        // Now to re-create two caches and make sure they exists, but
+        // are different than in previous life
+        try {
+            c2 = (ConcurrentMap<String, Integer>) c.createCache("c2", null);
+            c3 = (ConcurrentMap<String, Integer>) c.createCache("c3", null);
+        } catch (CacheExistException cee) {
+            // Don't expect this assertion, so if happens signal a
+            // failure in the testcase
+            Assert.assertTrue(false);
+        } catch (CacheConfigException cce) {
+            // Don't expect this assertion, so if happens signal a
+            // failure in the testcase
+            Assert.assertTrue(false);
+        }
+        Assert.assertTrue(c2 != null);
+        Assert.assertTrue(c3 != null);
+        caches = c.getCacheList();
+        Assert.assertTrue(caches.size() == 2);
+        Assert.assertTrue(c2.keySet().size() == 0);
+        Assert.assertTrue(c3.keySet().size() == 0);
+    }
+}
diff --git a/opendaylight/clustering/test/pom.xml b/opendaylight/clustering/test/pom.xml
new file mode 100644 (file)
index 0000000..7834a65
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.0-SNAPSHOT</version>
+    <relativePath>../../commons/opendaylight</relativePath>
+  </parent>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>clustering.test</artifactId>
+  <version>0.4.0-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <build>
+    <plugins>
+      <plugin>
+       <groupId>org.apache.felix</groupId>
+       <artifactId>maven-bundle-plugin</artifactId>
+       <version>2.3.6</version>
+       <extensions>true</extensions>
+       <configuration>
+         <instructions>
+           <Import-Package>
+             org.slf4j,
+              javax.transaction,
+              org.eclipse.osgi.framework.console,
+              ch.qos.logback.classic,
+              org.opendaylight.controller.clustering.services
+            </Import-Package>
+            <Service-Component>
+              OSGI-INF/component.xml
+            </Service-Component>
+         </instructions>
+       </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>clustering.services</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/ComplexClass.java b/opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/ComplexClass.java
new file mode 100644 (file)
index 0000000..076ec05
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.test.internal;
+
+import java.io.Serializable;
+
+public class ComplexClass implements IComplex, Serializable {
+    private String identity;
+
+    public ComplexClass(String i) {
+        this.identity = i;
+    }
+
+    @Override
+    public String whoAmI() {
+        return ("ComplexClass_" + this.identity);
+    }
+
+    @Override
+    public void IAm(String s) {
+        this.identity = s;
+    }
+}
diff --git a/opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/ComplexClass1.java b/opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/ComplexClass1.java
new file mode 100644 (file)
index 0000000..fda2ff1
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.test.internal;
+
+import java.io.Serializable;
+
+public class ComplexClass1 implements IComplex, Serializable {
+    private String identity;
+
+    public ComplexClass1(String i) {
+        this.identity = i;
+    }
+
+    @Override
+    public String whoAmI() {
+        return ("ComplexClass1_" + this.identity);
+    }
+
+    @Override
+    public void IAm(String s) {
+        this.identity = s;
+    }
+}
diff --git a/opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/ComplexContainer.java b/opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/ComplexContainer.java
new file mode 100644 (file)
index 0000000..adc062d
--- /dev/null
@@ -0,0 +1,49 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.test.internal;
+
+import java.io.Serializable;
+
+public class ComplexContainer implements Serializable {
+    private IComplex f;
+    private IComplex f1;
+    private Integer state;
+
+    public ComplexContainer(String i, Integer s) {
+        this.state = s;
+        this.f = new ComplexClass(i);
+        this.f1 = new ComplexClass1(i);
+    }
+
+    public String getIdentity() {
+        if (this.f != null && this.f1 != null) {
+            return ("[" + f.whoAmI() + "]-[" + f1.whoAmI() + "]");
+        }
+        return "<NOTSET>";
+    }
+
+    public void setIdentity(String i) {
+        if (this.f != null) {
+            this.f.IAm(i);
+        }
+        if (this.f1 != null) {
+            this.f1.IAm(i);
+        }
+    }
+
+    public Integer getState() {
+        return this.state;
+    }
+
+    @Override
+    public String toString() {
+        return ("{ID:" + this.getIdentity() + ",STATE:" + this.state + "}");
+    }
+}
diff --git a/opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/IComplex.java b/opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/IComplex.java
new file mode 100644 (file)
index 0000000..c1d5c31
--- /dev/null
@@ -0,0 +1,16 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.test.internal;
+
+public interface IComplex {
+    String whoAmI();
+
+    void IAm(String s);
+}
diff --git a/opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/LoggingListener.java b/opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/LoggingListener.java
new file mode 100644 (file)
index 0000000..4f5d432
--- /dev/null
@@ -0,0 +1,40 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.test.internal;
+
+import org.opendaylight.controller.clustering.services.IGetUpdates;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LoggingListener implements IGetUpdates<Integer, StringContainer> {
+    protected static Logger logger = LoggerFactory
+            .getLogger(LoggingListener.class);
+
+    @Override
+    public void entryCreated(Integer key, String containerName,
+            String cacheName, boolean originLocal) {
+        logger.debug(" Cache entry with key " + key + " created in cache "
+                + cacheName);
+    }
+
+    @Override
+    public void entryUpdated(Integer key, StringContainer new_value,
+            String containerName, String cacheName, boolean originLocal) {
+        logger.debug(" Cache entry with key " + key + " modified to value "
+                + new_value + "  in cache " + cacheName);
+    }
+
+    @Override
+    public void entryDeleted(Integer key, String containerName,
+            String cacheName, boolean originLocal) {
+        logger.debug(" Cache entry with key " + key + " removed in cache "
+                + cacheName);
+    }
+}
diff --git a/opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/SimpleClient.java b/opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/SimpleClient.java
new file mode 100644 (file)
index 0000000..3e9717f
--- /dev/null
@@ -0,0 +1,646 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.test.internal;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import org.eclipse.osgi.framework.console.CommandInterpreter;
+import org.eclipse.osgi.framework.console.CommandProvider;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.CacheListenerAddException;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.clustering.services.IGetUpdates;
+import org.opendaylight.controller.clustering.services.IListenRoleChange;
+import org.opendaylight.controller.clustering.services.ListenRoleChangeAddException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SimpleClient implements CommandProvider {
+    protected static Logger logger = LoggerFactory
+            .getLogger(SimpleClient.class);
+    IClusterServices icluster;
+    DoListenRoleChanged doListen;
+
+    public void _tbegin(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        try {
+            this.icluster.tbegin();
+            ci.println("Transaction Open "
+                    + this.icluster.tgetTransaction().toString());
+        } catch (Exception e) {
+            ci.println("Caught exception during transaction begin: " + e);
+        }
+    }
+
+    public void _tcommit(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        try {
+            ci.println("Committing transaction ....."
+                    + this.icluster.tgetTransaction().toString());
+            this.icluster.tcommit();
+            ci.println("Transaction Committed");
+        } catch (Exception e) {
+            ci.println("Caught exception during transaction commit: " + e);
+        }
+    }
+
+    public void _trollback(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        try {
+            ci.println("Rolling back transaction ....."
+                    + this.icluster.tgetTransaction().toString());
+            this.icluster.trollback();
+            ci.println("Transaction Rolled Back");
+        } catch (Exception e) {
+            ci.println("Caught exception during transaction rollback: " + e);
+        }
+    }
+
+    public void _cacheinfo(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        String containerName = ci.nextArgument();
+        if (containerName == null) {
+            ci.println("containerName not supplied");
+            return;
+        }
+        String cacheName = ci.nextArgument();
+        if (cacheName == null) {
+            ci.println("Cache not supplied");
+            return;
+        }
+        if (!this.icluster.existCache(containerName, cacheName)) {
+            ci.println("\tCache " + cacheName + " doesn't exists");
+            return;
+        }
+        ci.println("\tInfo for cache " + cacheName + " on container "
+                + containerName);
+        Properties p = this.icluster.getCacheProperties(containerName,
+                cacheName);
+        if (p != null) {
+            for (String key : p.stringPropertyNames()) {
+                ci.println("\t\t" + key + " = " + p.getProperty(key));
+            }
+        }
+    }
+
+    public void _setLogLevel(CommandInterpreter ci) {
+        String loggerName = ci.nextArgument();
+        if (loggerName == null) {
+            ci.println("Logger Name not supplied");
+            return;
+        }
+        String loggerLevel = ci.nextArgument();
+        if (loggerLevel == null) {
+            ci.println("Logger Level not supplied");
+            return;
+        }
+
+        ch.qos.logback.classic.Logger l = (ch.qos.logback.classic.Logger) LoggerFactory
+                .getLogger(loggerName);
+        ch.qos.logback.classic.Level level = ch.qos.logback.classic.Level
+                .toLevel(loggerLevel);
+        if (level == null) {
+            ci.println("Level not understood");
+            return;
+        }
+        l.setLevel(level);
+    }
+
+    private String retrieveLogLevel(ch.qos.logback.classic.Logger l) {
+        if (l == null) {
+            return ("Logger not supplied");
+        }
+        ch.qos.logback.classic.Level level = l.getLevel();
+        if (level == null) {
+            return ("Logger " + l.getName() + " at unknown level");
+        } else {
+            return ("Logger " + l.getName() + " at level " + l.getLevel()
+                    .toString());
+        }
+    }
+
+    public void _getLogLevel(CommandInterpreter ci) {
+        String loggerName = ci.nextArgument();
+        ch.qos.logback.classic.LoggerContext lc = (ch.qos.logback.classic.LoggerContext) LoggerFactory
+                .getILoggerFactory();
+        if (lc != null) {
+            for (ch.qos.logback.classic.Logger l : lc.getLoggerList()) {
+                if (loggerName == null || l.getName().startsWith(loggerName)) {
+                    ci.println(retrieveLogLevel(l));
+                }
+            }
+        }
+    }
+
+    public void _create(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        String containerName = ci.nextArgument();
+        if (containerName == null) {
+            ci.println("containerName not supplied");
+            return;
+        }
+        String cacheName = ci.nextArgument();
+        if (cacheName == null) {
+            ci.println("Cache not supplied");
+            return;
+        }
+        try {
+            if (cacheName.startsWith("T-")) {
+                this.icluster.createCache(containerName, cacheName, EnumSet
+                        .of(IClusterServices.cacheMode.TRANSACTIONAL));
+            } else {
+                this.icluster.createCache(containerName, cacheName, EnumSet
+                        .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+            }
+        } catch (CacheExistException ce) {
+            ci
+                    .println("\nCache already exits - destroy and recreate if needed");
+            return;
+        } catch (CacheConfigException cfe) {
+            ci.println("\nCache configured with contrasting parameters");
+            return;
+        }
+
+        if (this.icluster.existCache(containerName, cacheName)) {
+            ci.println(cacheName + " has been created on container "
+                    + containerName);
+        }
+    }
+
+    public void _destroy(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        String containerName = ci.nextArgument();
+        if (containerName == null) {
+            ci.println("containerName not supplied");
+            return;
+        }
+        String cacheName = ci.nextArgument();
+        if (cacheName == null) {
+            ci.println("Cache not supplied");
+            return;
+        }
+        if (this.icluster.existCache(containerName, cacheName)) {
+            this.icluster.destroyCache(containerName, cacheName);
+            ci.println(cacheName + " has been destroyed");
+        }
+    }
+
+    public void _listen(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        String containerName = ci.nextArgument();
+        if (containerName == null) {
+            ci.println("containerName not supplied");
+            return;
+        }
+        String cacheName = ci.nextArgument();
+        if (cacheName == null) {
+            ci.println("Cache not supplied");
+            return;
+        }
+        try {
+            this.icluster.addListener(containerName, cacheName,
+                    new LoggingListener());
+            ci.println("cache " + cacheName + " on container " + containerName
+                    + " is begin monitored for updates");
+        } catch (CacheListenerAddException clae) {
+            ci.println("Couldn't attach the listener to cache " + cacheName
+                    + " on container " + containerName);
+        }
+    }
+
+    public void _unlisten(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        String containerName = ci.nextArgument();
+        if (containerName == null) {
+            ci.println("containerName not supplied");
+            return;
+        }
+        String cacheName = ci.nextArgument();
+        if (cacheName == null) {
+            ci.println("Cache not supplied");
+            return;
+        }
+
+        Set<IGetUpdates<?, ?>> listeners = this.icluster.getListeners(
+                containerName, cacheName);
+        for (IGetUpdates<?, ?> l : listeners) {
+            this.icluster.removeListener(containerName, cacheName, l);
+        }
+        ci.println(cacheName + " is no longer being monitored for updates");
+    }
+
+    public void _listcaches(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        String containerName = ci.nextArgument();
+        if (containerName == null) {
+            ci.println("containerName not supplied");
+            return;
+        }
+
+        // For user's convenience, let's return the sorted cache list
+        List<String> sortedCacheList = new ArrayList<String>(this.icluster
+                .getCacheList(containerName));
+        java.util.Collections.sort(sortedCacheList);
+        for (String cacheName : sortedCacheList) {
+            ci.println("\t" + cacheName);
+        }
+    }
+
+    public void _put(CommandInterpreter ci) {
+        ConcurrentMap<Integer, StringContainer> c;
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        String containerName = ci.nextArgument();
+        if (containerName == null) {
+            ci.println("containerName not supplied");
+            return;
+        }
+        String cacheName = ci.nextArgument();
+        if (cacheName == null) {
+            ci.println("Cache not supplied");
+            return;
+        }
+        String sKey = ci.nextArgument();
+        String sValue = ci.nextArgument();
+        if (sKey == null) {
+            ci.println("Key not supplied");
+            return;
+        }
+        if (sValue == null) {
+            ci.println("Value not supplied");
+            return;
+        }
+        Integer key = null;
+        try {
+            key = Integer.valueOf(sKey);
+        } catch (NumberFormatException nfe) {
+            ci.println("Key is not a valid integer: " + sKey);
+        }
+
+        c = (ConcurrentMap<Integer, StringContainer>) this.icluster.getCache(
+                containerName, cacheName);
+        if (c != null) {
+            ci.println("\nAdd mapping " + key + " = " + sValue);
+            c.put(key, new StringContainer(sValue));
+        } else {
+            ci.println("Cache " + cacheName + " on container " + containerName
+                    + " not existant!");
+        }
+    }
+
+    public void _remove(CommandInterpreter ci) {
+        ConcurrentMap<Integer, StringContainer> c;
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        String containerName = ci.nextArgument();
+        if (containerName == null) {
+            ci.println("containerName not supplied");
+            return;
+        }
+        String cacheName = ci.nextArgument();
+        if (cacheName == null) {
+            ci.println("Cache not supplied");
+            return;
+        }
+        String sKey = ci.nextArgument();
+        if (sKey == null) {
+            ci.println("Key not supplied");
+            return;
+        }
+        Integer key = null;
+        try {
+            key = Integer.valueOf(sKey);
+        } catch (NumberFormatException nfe) {
+            ci.println("Key is not a valid integer: " + sKey);
+        }
+        c = (ConcurrentMap<Integer, StringContainer>) this.icluster.getCache(
+                containerName, cacheName);
+        if (c != null) {
+            ci.println("\nDelete key " + key);
+            c.remove(key);
+        } else {
+            ci.println("Cache " + cacheName + " on container " + containerName
+                    + " not existant!");
+        }
+    }
+
+    public void _dumper(CommandInterpreter ci) {
+        ConcurrentMap c;
+        String containerName = ci.nextArgument();
+        if (containerName == null) {
+            ci.println("containerName not supplied");
+            return;
+        }
+        String cacheName = ci.nextArgument();
+        if (cacheName == null) {
+            ci.println("Cache not supplied");
+            return;
+        }
+        c = (ConcurrentMap) this.icluster.getCache(containerName, cacheName);
+        if (c != null) {
+            for (Object e : c.entrySet()) {
+                Map.Entry entry = (Map.Entry) e;
+                Object v = entry.getValue();
+                String res = "<NOT KNOWN>";
+                if (v != null) {
+                    res = v.toString();
+                }
+                ci.println("Element " + entry.getKey() + "(hashCode="
+                        + entry.getKey().hashCode() + ") has value = (" + res
+                        + ")");
+            }
+        } else {
+            ci.println("Cache " + cacheName + " on container " + containerName
+                    + " not existant!");
+        }
+    }
+
+    public void _get(CommandInterpreter ci) {
+        ConcurrentMap<Integer, StringContainer> c;
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        String containerName = ci.nextArgument();
+        if (containerName == null) {
+            ci.println("containerName not supplied");
+            return;
+        }
+        String cacheName = ci.nextArgument();
+        if (cacheName == null) {
+            ci.println("Cache not supplied");
+            return;
+        }
+        String sKey = ci.nextArgument();
+        if (sKey == null) {
+            ci.println("Key not supplied");
+            return;
+        }
+        Integer key = null;
+        try {
+            key = Integer.valueOf(sKey);
+        } catch (NumberFormatException nfe) {
+            ci.println("Key is not a valid integer: " + sKey);
+        }
+        c = (ConcurrentMap<Integer, StringContainer>) this.icluster.getCache(
+                containerName, cacheName);
+        if (c != null) {
+            ci.println("\nGet key (" + key + ")=(" + c.get(key) + ")");
+        } else {
+            ci.println("Cache " + cacheName + " on container " + containerName
+                    + " not existant!");
+        }
+    }
+
+    public void _getRole(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        String role = "Active";
+        if (this.icluster.amIStandby()) {
+            role = "Standby";
+        }
+        ci.println("My role is: " + role);
+    }
+
+    public void _getActive(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        ci.println("Current active address is "
+                + this.icluster.getActiveAddress());
+    }
+
+    public void _listenActive(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        this.doListen = new DoListenRoleChanged();
+        try {
+            this.icluster.listenRoleChange(this.doListen);
+        } catch (ListenRoleChangeAddException e) {
+            ci.println("Exception while registering the listener");
+            return;
+        }
+        ci.println("Register listenRoleChanges");
+    }
+
+    public void _unlistenActive(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        if (this.doListen != null) {
+            this.icluster.unlistenRoleChange(this.doListen);
+            ci.println("Unregistered Active notifications");
+        }
+    }
+
+    class DoListenRoleChanged implements IListenRoleChange {
+        public void newActiveAvailable() {
+            logger.debug("New Active is available");
+        }
+    }
+
+    public void _putComplex(CommandInterpreter ci) {
+        ConcurrentMap<StringContainer, ComplexContainer> c;
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        String containerName = ci.nextArgument();
+        if (containerName == null) {
+            ci.println("containerName not supplied");
+            return;
+        }
+        String cacheName = ci.nextArgument();
+        if (cacheName == null) {
+            ci.println("Cache not supplied");
+            return;
+        }
+        String key = ci.nextArgument();
+        if (key == null) {
+            ci.println("Key not supplied (String)");
+            return;
+        }
+        String valueIdentity = ci.nextArgument();
+        if (valueIdentity == null) {
+            ci.println("Value for Identity not supplied (String)");
+            return;
+        }
+        String sValueState = ci.nextArgument();
+        if (sValueState == null) {
+            ci.println("Value for State not supplied (Integer)");
+            return;
+        }
+        Integer valueState = null;
+        try {
+            valueState = Integer.valueOf(sValueState);
+        } catch (NumberFormatException nfe) {
+            ci.println("Value State is not a valid integer: " + sValueState);
+            return;
+        }
+        c = (ConcurrentMap<StringContainer, ComplexContainer>) this.icluster
+                .getCache(containerName, cacheName);
+        if (c != null) {
+            c.put(new StringContainer(key), new ComplexContainer(valueIdentity,
+                    valueState));
+            ci.println("\nPut in key (" + key + ")={String:" + valueIdentity
+                    + ",Integer:" + valueState + "}");
+        } else {
+            ci.println("Cache " + cacheName + " on container " + containerName
+                    + " not existant!");
+        }
+    }
+
+    public void _updateComplex(CommandInterpreter ci) {
+        ConcurrentMap<StringContainer, ComplexContainer> c;
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        String containerName = ci.nextArgument();
+        if (containerName == null) {
+            ci.println("containerName not supplied");
+            return;
+        }
+        String cacheName = ci.nextArgument();
+        if (cacheName == null) {
+            ci.println("Cache not supplied");
+            return;
+        }
+        String key = ci.nextArgument();
+        if (key == null) {
+            ci.println("Key not supplied (String)");
+            return;
+        }
+        String valueIdentity = ci.nextArgument();
+        if (valueIdentity == null) {
+            ci.println("Value for Identity not supplied (String)");
+            return;
+        }
+        c = (ConcurrentMap<StringContainer, ComplexContainer>) this.icluster
+                .getCache(containerName, cacheName);
+        if (c != null) {
+            StringContainer k = new StringContainer(key);
+            ComplexContainer v = c.get(k);
+            if (v != null) {
+                v.setIdentity(valueIdentity);
+                ci.println("\nUpdate key (" + key + ")={String:"
+                        + valueIdentity + "}");
+
+                // IMPORTANT ON UPDATING ANY FIELD OF THE CHILD MAKE
+                // SURE TO PUT THE NEW VALUE IN THE CACHE ELSE THE
+                // VALUE WILL NOT PROPAGATE!!
+                c.put(k, v);
+            } else {
+                ci.println("\nCannot Update key (" + key
+                        + ") doesn't exist in the database");
+            }
+        } else {
+            ci.println("Cache " + cacheName + " on container " + containerName
+                    + " not existant!");
+        }
+    }
+
+    public void setIClusterServices(IClusterServices i) {
+        this.icluster = i;
+        logger.debug("IClusterServices set");
+    }
+
+    public void unsetIClusterServices(IClusterServices i) {
+        if (this.icluster == i) {
+            this.icluster = null;
+            logger.debug("IClusterServices UNset");
+        }
+    }
+
+    public void startUp() {
+        logger.debug("Started clustering test plugin");
+    }
+
+    public void shutDown() {
+        logger.debug("Stopped clustering test plugin");
+    }
+
+    @Override
+    public String getHelp() {
+        StringBuffer help = new StringBuffer();
+        help.append("---Clustering Service Testing---\n");
+        help.append("\tput              - Put a key,value in the cache\n");
+        help.append("\tremove           - Delete a key from the cache\n");
+        help.append("\tget              - Get a key from the cache\n");
+        help.append("\tdumper           - Dump the cache\n");
+        help
+                .append("\tcacheinfo        - Dump the configuration for a cache\n");
+        help.append("\ttbegin           - Transaction begin\n");
+        help.append("\ttcommit          - Transaction Commit\n");
+        help.append("\ttrollback        - Transaction Rollback\n");
+        help.append("\tlistcaches       - List all the Caches\n");
+        help.append("\tlisten           - Listen to cache updates\n");
+        help.append("\tunlisten         - UNListen to cache updates\n");
+        help.append("\tlistenActive     - Listen to Active updates\n");
+        help.append("\tunlistenActive   - UNListen to Active updates\n");
+        help.append("\tdestroy          - Destroy a cache\n");
+        help.append("\tcreate           - Create a cache\n");
+        help.append("\tgetRole          - Tell if active or standby\n");
+        help.append("\tgetActive        - Report the IP address of Active\n");
+        help
+                .append("\tputComplex       - Fill a more complex data structure\n");
+        help
+                .append("\tupdateComplex    - Update the value of a more complex data structure\n");
+        help
+                .append("\tgetLogLevel      - Get the loglevel for the logger specified\n");
+        help
+                .append("\tsetLogLevel      - Set the loglevel for the logger specified\n");
+        return help.toString();
+    }
+}
diff --git a/opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/StringContainer.java b/opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/StringContainer.java
new file mode 100644 (file)
index 0000000..39ef1b0
--- /dev/null
@@ -0,0 +1,55 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.clustering.test.internal;
+
+import java.io.Serializable;
+
+public class StringContainer implements Serializable {
+    private String mystring;
+
+    public StringContainer() {
+        this.mystring = null;
+    }
+
+    public StringContainer(String s) {
+        setMystring(s);
+    }
+
+    public String getMystring() {
+        return mystring;
+    }
+
+    public void setMystring(String mystring) {
+        this.mystring = mystring;
+    }
+
+    // Return the hashCode of the containing string
+    @Override
+    public int hashCode() {
+        if (this.mystring != null) {
+            return this.mystring.hashCode();
+        }
+        return 0;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof StringContainer) {
+            StringContainer o = (StringContainer) obj;
+            return this.mystring.equals(o.getMystring());
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return "{" + this.mystring + "}";
+    }
+}
diff --git a/opendaylight/clustering/test/src/main/resources/OSGI-INF/component.xml b/opendaylight/clustering/test/src/main/resources/OSGI-INF/component.xml
new file mode 100644 (file)
index 0000000..df0e388
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" 
+               activate="startUp" 
+               deactivate="shutDown" 
+               name="org.opendaylight.controller.clustering.test.internal.SimpleClient">
+  <implementation class="org.opendaylight.controller.clustering.test.internal.SimpleClient"/>
+  
+  <service>
+    <!-- Exports, can be multiple-->
+    <provide interface="org.eclipse.osgi.framework.console.CommandProvider"/>    
+  </service>
+  
+  <!-- Imports, can be multiple -->
+  <reference name="IClusterServices" 
+             bind="setIClusterServices" 
+             unbind="unsetIClusterServices" 
+             cardinality="1..1" 
+             interface="org.opendaylight.controller.clustering.services.IClusterServices"/>
+</scr:component>
diff --git a/opendaylight/clustering/test/src/test/java/org/opendaylight/controller/clustering/test/internal/TestClusteringTest.java b/opendaylight/clustering/test/src/test/java/org/opendaylight/controller/clustering/test/internal/TestClusteringTest.java
new file mode 100644 (file)
index 0000000..fa00c7f
--- /dev/null
@@ -0,0 +1,67 @@
+\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.controller.clustering.test.internal;\r
+\r
+\r
+import org.junit.Assert;\r
+import org.junit.Test;\r
+\r
+import junit.framework.TestCase;\r
+\r
+public class TestClusteringTest extends TestCase {\r
+\r
+       @Test\r
+       public void testComplexClass() {\r
+               ComplexClass cc = new ComplexClass("cplxc1");\r
+               Assert.assertTrue(cc.whoAmI().equals("ComplexClass_cplxc1"));\r
+               cc.IAm("cplxc2");\r
+               Assert.assertTrue(cc.whoAmI().equals("ComplexClass_cplxc2"));\r
+       }\r
+               \r
+       @Test\r
+       public void testComplexClass1() {\r
+               ComplexClass1 cc1 = new ComplexClass1("cplxc1a");\r
+               Assert.assertTrue(cc1.whoAmI().equals("ComplexClass1_cplxc1a"));\r
+               cc1.IAm("cplxc1b");\r
+               Assert.assertTrue(cc1.whoAmI().equals("ComplexClass1_cplxc1b"));\r
+       }\r
+               \r
+               \r
+       @Test\r
+       public void testComplexContainer() {\r
+               ComplexContainer cplxcontnr1 = new ComplexContainer("cct1", 5);\r
+               Assert.assertTrue(cplxcontnr1.getIdentity().equals("[ComplexClass_cct1]-[ComplexClass1_cct1]"));\r
+               Assert.assertTrue(cplxcontnr1.getState() == 5);\r
+               \r
+               cplxcontnr1.setIdentity("cct2");\r
+               Assert.assertTrue(cplxcontnr1.getIdentity().equals("[ComplexClass_cct2]-[ComplexClass1_cct2]"));\r
+               \r
+               Assert.assertTrue(cplxcontnr1.toString().equals(\r
+                               "{ID:[ComplexClass_cct2]-[ComplexClass1_cct2],STATE:5}"));\r
+       }\r
+               \r
+       @Test\r
+       public void testStringContainer() {\r
+               StringContainer strcontainer1 = new StringContainer();\r
+               Assert.assertTrue(strcontainer1.getMystring() == null);\r
+               Assert.assertTrue(strcontainer1.hashCode() == 0);\r
+               \r
+               StringContainer strcontainer2 = new StringContainer("foo");\r
+               Assert.assertTrue(strcontainer2.getMystring() != null);\r
+               Assert.assertTrue(strcontainer2.hashCode() != 0);\r
+               \r
+               strcontainer1.setMystring("foo");\r
+               Assert.assertTrue(strcontainer2.equals(strcontainer1));\r
+               \r
+               Assert.assertTrue(strcontainer2.toString().equals("{foo}"));\r
+       }\r
+               \r
+\r
+}\r
diff --git a/opendaylight/commons/opendaylight/logback.xml b/opendaylight/commons/opendaylight/logback.xml
new file mode 100644 (file)
index 0000000..043ceef
--- /dev/null
@@ -0,0 +1,12 @@
+<configuration scan="true">
+  
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n</pattern>
+    </encoder>
+  </appender>
+  
+  <root level="error">
+    <appender-ref ref="STDOUT" />
+  </root>
+</configuration>
diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml
new file mode 100644 (file)
index 0000000..39f100d
--- /dev/null
@@ -0,0 +1,831 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <prerequisites>
+    <maven>3.0</maven>
+  </prerequisites>
+  <!-- The sitebuildsettings-pom.xml contains the specific settings
+       for a site on which the build can be performed so it will
+       contain for instance reference to the local Maven proxy/host
+       server or the local sonar etc. -->
+  <parent>
+    <groupId>sitebuildsettings</groupId>
+    <artifactId>sitebuildsettings</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <relativePath>../../../sitebuildsettings-pom.xml</relativePath>
+  </parent>
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>commons.opendaylight</artifactId>
+  <version>1.4.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+  <properties>
+    <siteplugin>3.2</siteplugin>
+    <projectinfo>2.6</projectinfo>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <compiler.version>2.3.2</compiler.version>
+    <surefire.version>2.13</surefire.version>
+    <exam.version>3.0.0</exam.version>
+    <url.version>1.5.0</url.version>
+    <enunciate.version>1.26.2</enunciate.version>
+    <sonar.branch>${user.name}-private-view</sonar.branch>
+    <sonar.skippedModules>org.openflow.openflowj,net.sf.jung2</sonar.skippedModules>
+    <logback.version>1.0.9</logback.version>
+    <slf4j.version>1.7.2</slf4j.version>
+    <jackson.version>1.9.8</jackson.version>
+    <spring.version>3.1.3.RELEASE</spring.version>
+    <spring-security.version>3.1.3.RELEASE</spring-security.version>
+    <jersey.version>1.17</jersey.version>
+    <virgo.version>3.6.0.RELEASE</virgo.version>
+    <geminiweb.version>2.2.0.RELEASE</geminiweb.version>
+  </properties>
+
+  <pluginRepositories>
+    <pluginRepository>
+      <id>central2</id>
+      <name>central2</name>
+      <url>${nexusproxy}/repositories/central2/</url>
+    </pluginRepository>
+  </pluginRepositories>
+
+  <profiles>
+    <profile>
+      <id>viewbuild</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+      </activation>
+      <properties>
+        <build.suffix>${project.version}</build.suffix>
+      </properties>
+    </profile>
+    <profile>
+      <id>jenkins</id>
+      <activation>
+        <property>
+          <name>BUILDSUFFIX</name>
+        </property>
+      </activation>
+      <properties>
+        <build.suffix>${BUILDSUFFIX}</build.suffix>
+      </properties>
+    </profile>
+    <profile>
+      <id>fastreassembly</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-dependency-plugin</artifactId>
+            <version>2.4</version>
+            <executions>
+              <execution>
+                <id>copyfastreassembly</id>
+                <phase>install</phase>
+                <goals>
+                  <goal>copy</goal>
+                </goals>
+                <configuration>
+                  <artifactItems>
+                    <artifactItem>
+                      <groupId>${project.groupId}</groupId>
+                      <artifactId>${project.artifactId}</artifactId>
+                      <version>${project.version}</version>
+                      <destFileName>${project.groupId}.${project.artifactId}-${project.version}.jar</destFileName>
+                    </artifactItem>
+                  </artifactItems>
+                  <outputDirectory>${fastreassembly.directory}</outputDirectory>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+  <repositories>
+    <!-- EBR release -->
+    <!-- http://repository.springsource.com/maven/bundles/release -->
+    <repository>
+      <id>ebr-bundles-release</id>
+      <name>ebr-bundles-release</name>
+      <url>${nexusproxy}/repositories/ebr-bundles-release/</url>
+    </repository>
+    <!-- EBR external -->
+    <!-- http://repository.springsource.com/maven/bundles/external -->
+    <repository>
+      <id>ebr-bundles-external</id>
+      <name>ebr-bundles-external</name>
+      <url>${nexusproxy}/repositories/ebr-bundles-external/</url>
+    </repository>
+    <!-- Maven repo2 mirror -->
+    <!-- http://repo2.maven.org/maven2 -->
+    <repository>
+      <id>central2</id>
+      <name>central2</name>
+      <url>${nexusproxy}/repositories/central2/</url>
+    </repository>
+    <!-- Maven repo1 mirror -->
+    <!-- http://repo1.maven.org/maven2 -->
+    <repository>
+      <id>central</id>
+      <name>central</name>
+      <url>${nexusproxy}/repositories/central/</url>
+    </repository>
+    <!-- Pax mirror -->
+    <!-- https://oss.sonatype.org/content/repositories/ops4j-releases -->
+    <repository>
+      <id>ops4j-releases</id>
+      <name>ops4j-releases</name>
+      <url>${nexusproxy}/repositories/ops4j-releases/</url>
+    </repository>
+    <!-- Third Packages hosted in local maven because not available in
+         other places -->
+    <repository>
+      <id>thirdparty</id>
+      <name>thirdparty</name>
+      <url>${nexusproxy}/repositories/thirdparty/</url>
+    </repository>
+    <!-- Jboss mirror -->
+    <!-- https://repository.jboss.org/nexus/content/repositories/releases -->
+    <repository>
+      <id>jboss.releases</id>
+      <name>jboss.releases</name>
+      <url>${nexusproxy}/repositories/jboss.releases/</url>
+    </repository>
+    <!-- OpenDayLight Released artifact -->
+    <repository>
+      <id>opendaylight-release</id>
+      <name>opendaylight-release</name>
+      <url>${nexusproxy}/repositories/opendaylight.release/</url>
+    </repository>
+    <!-- OpenDayLight Snapshot artifact -->
+    <repository>
+      <id>opendaylight-snapshot</id>
+      <name>opendaylight-snapshot</name>
+      <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
+    </repository>
+  </repositories>
+  <distributionManagement>
+    <!-- OpenDayLight Released artifact -->
+    <repository>
+      <id>${opendaylightID}-release</id>
+      <url>${nexusproxy}/repositories/opendaylight.release/</url>
+    </repository>
+    <!-- OpenDayLight Snapshot artifact -->
+    <snapshotRepository>
+      <id>${opendaylightID}-snapshot</id>
+      <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
+    </snapshotRepository>
+    <!-- Site deployment -->
+    <site>
+      <id>website</id>
+      <url>${sitedeploy}</url>
+    </site>
+  </distributionManagement>
+
+  <reporting>
+    <excludeDefaults>true</excludeDefaults>
+    <outputDirectory>${project.build.directory}/site</outputDirectory>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-project-info-reports-plugin</artifactId>
+        <version>${projectinfo}</version>
+        <configuration>
+          <dependencyDetailsEnabled>false</dependencyDetailsEnabled>
+          <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
+        </configuration>
+        <reportSets>
+          <reportSet>
+            <reports>
+              <report>index</report>
+              <report>project-team</report>
+              <report>license</report>
+              <report>mailing-list</report>
+              <report>plugin-management</report>
+              <report>cim</report>
+              <report>issue-tracking</report>
+              <report>scm</report>
+              <report>summary</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jxr-plugin</artifactId>
+        <version>2.3</version>
+        <configuration>
+          <aggregate>true</aggregate>
+          <linkJavadoc>true</linkJavadoc>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <version>2.10</version>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <version>2.8.1</version>
+        <configuration>
+          <doclet>org.jboss.apiviz.APIviz</doclet>
+          <docletArtifact>
+            <groupId>org.jboss.apiviz</groupId>
+            <artifactId>apiviz</artifactId>
+            <version>1.3.2.GA</version>
+          </docletArtifact>
+          <finalName>${project.artifactId}-${build.suffix}</finalName>
+          <useStandardDocletOptions>true</useStandardDocletOptions>
+          <charset>UTF-8</charset>
+          <encoding>UTF-8</encoding>
+          <docencoding>UTF-8</docencoding>
+          <breakiterator>true</breakiterator>
+          <version>true</version>
+          <author>true</author>
+          <keywords>true</keywords>
+          <excludePackageNames>*.internal:edu.uci.*</excludePackageNames>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>properties-maven-plugin</artifactId>
+        <version>1.0-alpha-2</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>set-system-properties</goal>
+            </goals>
+            <configuration>
+              <properties>
+                <property>
+                  <name>logback.configurationFile</name>
+                  <value>${project.parent.relativePath}/logback.xml</value>
+                </property>
+              </properties>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>com.googlecode.maven-java-formatter-plugin</groupId>
+        <artifactId>maven-java-formatter-plugin</artifactId>
+        <version>0.3.1</version>
+        <configuration>
+          <compilerSource>1.6</compilerSource>
+          <compilerCompliance>1.6</compilerCompliance>
+          <compilerTargetPlatform>1.6</compilerTargetPlatform>
+          <configFile>${project.parent.relativePath}/sun_coding_style.xml</configFile>
+        </configuration>
+      </plugin>
+    </plugins>
+    <pluginManagement>
+      <plugins>
+        <!-- Ignore/Execute plugin execution -->
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>properties-maven-plugin</artifactId>
+                    <versionRange>[0.0,)</versionRange>
+                    <goals>
+                      <goal>set-system-properties</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.codehaus.enunciate</groupId>
+          <artifactId>maven-enunciate-plugin</artifactId>
+          <version>${enunciate.version}</version>
+          <configuration>
+            <configFile>enunciate.xml</configFile>
+          </configuration>
+          <executions>
+            <execution>
+              <goals>
+                <goal>docs</goal>
+              </goals>
+            </execution>
+          </executions>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>${compiler.version}</version>
+          <configuration>
+            <source>1.6</source>
+            <target>1.6</target>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-javadoc-plugin</artifactId>
+          <version>2.8.1</version>
+          <configuration>
+            <doclet>org.jboss.apiviz.APIviz</doclet>
+            <docletArtifact>
+              <groupId>org.jboss.apiviz</groupId>
+              <artifactId>apiviz</artifactId>
+              <version>1.3.2.GA</version>
+            </docletArtifact>
+            <finalName>${project.artifactId}-${build.suffix}</finalName>
+            <useStandardDocletOptions>true</useStandardDocletOptions>
+            <charset>UTF-8</charset>
+            <encoding>UTF-8</encoding>
+            <docencoding>UTF-8</docencoding>
+            <breakiterator>true</breakiterator>
+            <version>true</version>
+            <author>true</author>
+            <keywords>true</keywords>
+            <excludePackageNames>net.sf.jnetlib.*:cern.*:corejava:*.internal:edu.uci.*</excludePackageNames>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-jxr-plugin</artifactId>
+          <version>2.3</version>
+          <configuration>
+            <aggregate>true</aggregate>
+            <linkJavadoc>true</linkJavadoc>
+            <javadocDir>target/apidocs</javadocDir>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <version>${slf4j.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>${slf4j.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>log4j-over-slf4j</artifactId>
+      <version>${slf4j.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-core</artifactId>
+      <version>${logback.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <version>${logback.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.jackson</groupId>
+      <artifactId>jackson-mapper-asl</artifactId>
+      <version>${jackson.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.jackson</groupId>
+      <artifactId>jackson-core-asl</artifactId>
+      <version>${jackson.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.jackson</groupId>
+      <artifactId>jackson-jaxrs</artifactId>
+      <version>${jackson.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.jettison</groupId>
+      <artifactId>jettison</artifactId>
+      <version>1.3.3</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>2.3</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-fileupload</groupId>
+      <artifactId>commons-fileupload</artifactId>
+      <version>1.2.2</version>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>javax.servlet</artifactId>
+      <version>3.0.0.v201112011016</version>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>javax.servlet.jsp</artifactId>
+      <version>2.2.0.v201112011158</version>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.ds</artifactId>
+      <version>1.4.0.v20120522-1841</version>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.util</artifactId>
+      <version>1.0.400.v20120522-2049</version>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.osgi.services</artifactId>
+      <version>3.3.100.v20120522-1822</version>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.osgi</artifactId>
+      <version>3.8.1.v20120830-144521</version>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.apache.felix.gogo.command</artifactId>
+      <version>0.8.0.v201108120515</version>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.apache.felix.gogo.runtime</artifactId>
+      <version>0.8.0.v201108120515</version>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.apache.felix.gogo.shell</artifactId>
+      <version>0.8.0.v201110170705</version>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.cm</artifactId>
+      <version>1.0.400.v20120522-1841</version>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.console</artifactId>
+      <version>1.0.0.v20120522-1841</version>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.launcher</artifactId>
+      <version>1.3.0.v20120522-1813</version>
+    </dependency>
+    <!-- Gemini Web -->
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.gemini.web.core</artifactId>
+      <version>${geminiweb.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.gemini.web.extender</artifactId>
+      <version>${geminiweb.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.gemini.web.tomcat</artifactId>
+      <version>${geminiweb.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.virgo.kernel.equinox.extensions</artifactId>
+      <version>${virgo.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.virgo.util.common</artifactId>
+      <version>${virgo.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.virgo.util.io</artifactId>
+      <version>${virgo.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.virgo.util.math</artifactId>
+      <version>${virgo.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.virgo.util.osgi</artifactId>
+      <version>${virgo.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.virgo.util.osgi.manifest</artifactId>
+      <version>${virgo.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.virgo.util.parser.manifest</artifactId>
+      <version>${virgo.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.dependencymanager</artifactId>
+      <version>3.1.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.dependencymanager.shell</artifactId>
+      <version>3.0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <version>2.1</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.spec.javax.transaction</groupId>
+      <artifactId>jboss-transaction-api_1.1_spec</artifactId>
+      <version>1.0.1.Final</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.fileinstall</artifactId>
+      <version>3.1.6</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+      <version>3.1</version>
+    </dependency>
+    <dependency>
+      <groupId>virgomirror</groupId>
+      <artifactId>org.eclipse.jdt.core.compiler.batch</artifactId>
+      <version>3.8.0.I20120518-2145</version>
+    </dependency>
+    <dependency>
+      <groupId>eclipselink</groupId>
+      <artifactId>javax.persistence</artifactId>
+      <version>2.0.4.v201112161009</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.activation</artifactId>
+      <version>1.1.0.v201211130549</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.annotation</artifactId>
+      <version>1.1.0.v201209060031</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.ejb</artifactId>
+      <version>3.1.1.v201204261316</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.el</artifactId>
+      <version>2.2.0.v201108011116</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.mail.glassfish</artifactId>
+      <version>1.4.1.v201108011116</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.xml.rpc</artifactId>
+      <version>1.1.0.v201005080400</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.catalina</artifactId>
+      <version>7.0.32.v201211201336</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.catalina.ha</artifactId>
+      <version>7.0.32.v201211201952</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.catalina.tribes</artifactId>
+      <version>7.0.32.v201211201952</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.coyote</artifactId>
+      <version>7.0.32.v201211201952</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.el</artifactId>
+      <version>7.0.32.v201211081135</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.jasper</artifactId>
+      <version>7.0.32.v201211201952</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.juli.extras</artifactId>
+      <version>7.0.32.v201211081135</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.tomcat.api</artifactId>
+      <version>7.0.32.v201211081135</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.tomcat.util</artifactId>
+      <version>7.0.32.v201211201952</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.servlet.jsp.jstl</artifactId>
+      <version>1.2.0.v201105211821</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.servlet.jsp.jstl.impl</artifactId>
+      <version>1.2.0.v201210211230</version>
+    </dependency>
+    <!-- Add Pax Exam -->
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-container-native</artifactId>
+      <version>${exam.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-junit4</artifactId>
+      <version>${exam.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-link-mvn</artifactId>
+      <version>${exam.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.url</groupId>
+      <artifactId>pax-url-aether</artifactId>
+      <version>${url.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.asm</artifactId>
+      <version>${spring.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.aop</artifactId>
+      <version>${spring.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.context</artifactId>
+      <version>${spring.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.context.support</artifactId>
+      <version>${spring.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.core</artifactId>
+      <version>${spring.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.beans</artifactId>
+      <version>${spring.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.expression</artifactId>
+      <version>${spring.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.web</artifactId>
+      <version>${spring.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.aopalliance</groupId>
+      <artifactId>com.springsource.org.aopalliance</artifactId>
+      <version>1.0.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.web.servlet</artifactId>
+      <version>${spring.version}</version>
+    </dependency>
+    <!-- Spring security -->
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-config</artifactId>
+      <version>${spring-security.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-core</artifactId>
+      <version>${spring-security.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-web</artifactId>
+      <version>${spring-security.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-taglibs</artifactId>
+      <version>${spring-security.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.transaction</artifactId>
+      <version>${spring-security.version}</version>
+    </dependency>
+    <!-- Visual VM hook -->
+    <dependency>
+      <groupId>org.ow2.chameleon.management</groupId>
+      <artifactId>chameleon-mbeans</artifactId>
+      <version>1.0.0</version>
+    </dependency>
+    <!-- Jersey for JAXRS -->
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-core</artifactId>
+      <version>${jersey.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-server</artifactId>
+      <version>${jersey.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-client</artifactId>
+      <version>${jersey.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-json</artifactId>
+      <version>${jersey.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey.contribs</groupId>
+      <artifactId>jersey-spring</artifactId>
+      <version>${jersey.version}</version>
+      <exclusions>
+        <exclusion>
+          <groupId>org.springframework</groupId>
+          <artifactId>spring</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.springframework</groupId>
+          <artifactId>spring-aop</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.springframework</groupId>
+          <artifactId>spring-core</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.springframework</groupId>
+          <artifactId>spring-web</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.springframework</groupId>
+          <artifactId>spring-beans</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.springframework</groupId>
+          <artifactId>spring-context</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/opendaylight/commons/opendaylight/sun_coding_style.xml b/opendaylight/commons/opendaylight/sun_coding_style.xml
new file mode 100644 (file)
index 0000000..f4516b9
--- /dev/null
@@ -0,0 +1,291 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<profiles version="12">
+<profile kind="CodeFormatterProfile" name="SunCodingStyle" version="12">
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
+<setting id="org.eclipse.jdt.core.compiler.source" value="1.7"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="8"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.7"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
+</profile>
+</profiles>
diff --git a/opendaylight/distribution/opendaylight/opendaylight-application.launch b/opendaylight/distribution/opendaylight/opendaylight-application.launch
new file mode 100644 (file)
index 0000000..5de9bae
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/sal"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"/>
+<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;sourceLookupDirector&gt;&#10;&lt;sourceContainers duplicates=&quot;false&quot;&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;switchmanager.northbound&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;commons.northbound&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;configuration&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;configuration.implementation&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;containermanager&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;flowprogrammer.northbound&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;forwarding.staticrouting.northbound&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;hosttracker&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;hosttracker.northbound&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;protocol_plugins.openflow&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;statistics.northbound&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;subnets.northbound&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;topology.northbound&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;containermanager.implementation&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;devices.web&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;flows.web&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;samples.simpleforwarding&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;topology.web&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;troubleshoot.web&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;clustering.services&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;mactracker&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;sal&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;slicemanager&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;switchmanager&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;topologymanager&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;arphandler&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;clustering.services-implementation&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;clustering.test&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;configuration.web&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;forwarding.ipswitch&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;forwarding.staticrouting&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;forwardingrulesmanager&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;home.web&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;monitor&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;northboundtest&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;onep.topology.southbound&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;openflowj&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;protocol_plugin.openflow&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;routing.dijkstra_implementation&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;sal.implementation&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;slicemanager.implementation&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;statisticsmanager&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;tifmgr&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;usermanager&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;web&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;/sourceContainers&gt;&#10;&lt;/sourceLookupDirector&gt;&#10;"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
+</listAttribute>
+<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/distribution.opendaylight/target/distribution.opendaylight-0.1.0-SNAPSHOT-osgipackage/opendaylight/lib/org.eclipse.equinox.launcher-1.3.0.v20120522-1813.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/distribution.opendaylight/target/distribution.opendaylight-0.1.0-SNAPSHOT-osgipackage/opendaylight/lib/org.eclipse.virgo.kernel.equinox.extensions-3.6.0.RELEASE.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/distribution.opendaylight/target/distribution.opendaylight-0.1.0-SNAPSHOT-osgipackage/opendaylight/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.m2e.launchconfig.classpathProvider"/>
+<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.equinox.launcher.Main"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-console -consoleLog"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="sal"/>
+<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.m2e.launchconfig.sourcepathProvider"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Djava.io.tmpdir=${workspace_loc:distribution.opendaylight/target/distribution.opendaylight-0.1.0-SNAPSHOT-osgipackage/opendaylight}/work/tmp -Dosgi.install.area=${workspace_loc:distribution.opendaylight/target/distribution.opendaylight-0.1.0-SNAPSHOT-osgipackage} -Dosgi.configuration.area=${workspace_loc:distribution.opendaylight/target/distribution.opendaylight-0.1.0-SNAPSHOT-osgipackage/opendaylight}/configuration -Dosgi.frameworkClassPath=file:${workspace_loc:distribution.opendaylight/target/distribution.opendaylight-0.1.0-SNAPSHOT-osgipackage/opendaylight}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar,file:${workspace_loc:distribution.opendaylight/target/distribution.opendaylight-0.1.0-SNAPSHOT-osgipackage/opendaylight}/lib/org.eclipse.virgo.kernel.equinox.extensions-3.6.0.RELEASE.jar,file:${workspace_loc:distribution.opendaylight/target/distribution.opendaylight-0.1.0-SNAPSHOT-osgipackage/opendaylight}/lib/org.eclipse.equinox.launcher-1.3.0.v20120522-1813.jar -Dosgi.framework=file:${workspace_loc:distribution.opendaylight/target/distribution.opendaylight-0.1.0-SNAPSHOT-osgipackage/opendaylight}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:distribution.opendaylight/target/distribution.opendaylight-0.1.0-SNAPSHOT-osgipackage/opendaylight}"/>
+</launchConfiguration>
diff --git a/opendaylight/distribution/opendaylight/opendaylight-assembleit-fast.launch b/opendaylight/distribution/opendaylight/opendaylight-assembleit-fast.launch
new file mode 100644 (file)
index 0000000..b6a2b49
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
+<stringAttribute key="M2_GOALS" value="clean install"/>
+<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
+<booleanAttribute key="M2_OFFLINE" value="false"/>
+<stringAttribute key="M2_PROFILES" value="fastreassembly"/>
+<listAttribute key="M2_PROPERTIES">
+<listEntry value="fastreassembly.directory=${workspace_loc:/distribution.opendaylight/target/distribution.opendaylight-0.1.0-SNAPSHOT-osgipackage/opendaylight/plugins}"/>
+</listAttribute>
+<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
+<booleanAttribute key="M2_SKIP_TESTS" value="false"/>
+<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx768m -XX:MaxPermSize=256m"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${selected_resource_loc}"/>
+</launchConfiguration>
diff --git a/opendaylight/distribution/opendaylight/opendaylight-assembleit-noclean.launch b/opendaylight/distribution/opendaylight/opendaylight-assembleit-noclean.launch
new file mode 100644 (file)
index 0000000..9de0422
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
+<stringAttribute key="M2_GOALS" value="install"/>
+<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
+<booleanAttribute key="M2_OFFLINE" value="false"/>
+<stringAttribute key="M2_PROFILES" value=""/>
+<listAttribute key="M2_PROPERTIES"/>
+<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
+<booleanAttribute key="M2_SKIP_TESTS" value="true"/>
+<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx768m -XX:MaxPermSize=256m"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/distribution.opendaylight}"/>
+</launchConfiguration>
diff --git a/opendaylight/distribution/opendaylight/opendaylight-assembleit-skiput.launch b/opendaylight/distribution/opendaylight/opendaylight-assembleit-skiput.launch
new file mode 100644 (file)
index 0000000..de02206
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
+<stringAttribute key="M2_GOALS" value="clean install"/>
+<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
+<booleanAttribute key="M2_OFFLINE" value="false"/>
+<stringAttribute key="M2_PROFILES" value=""/>
+<listAttribute key="M2_PROPERTIES">
+<listEntry value="maven.test.skip=true"/>
+</listAttribute>
+<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
+<booleanAttribute key="M2_SKIP_TESTS" value="false"/>
+<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx768m -XX:MaxPermSize=256m"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/distribution.opendaylight}"/>
+</launchConfiguration>
diff --git a/opendaylight/distribution/opendaylight/opendaylight-assembleit-sonar.launch b/opendaylight/distribution/opendaylight/opendaylight-assembleit-sonar.launch
new file mode 100644 (file)
index 0000000..077592c
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
+<stringAttribute key="M2_GOALS" value="clean install sonar:sonar"/>
+<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
+<booleanAttribute key="M2_OFFLINE" value="false"/>
+<stringAttribute key="M2_PROFILES" value=""/>
+<listAttribute key="M2_PROPERTIES">
+<listEntry value="maven.test.skip=true"/>
+</listAttribute>
+<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
+<booleanAttribute key="M2_SKIP_TESTS" value="false"/>
+<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx768m -XX:MaxPermSize=256m"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/distribution.opendaylight}"/>
+</launchConfiguration>
diff --git a/opendaylight/distribution/opendaylight/opendaylight-assembleit.launch b/opendaylight/distribution/opendaylight/opendaylight-assembleit.launch
new file mode 100644 (file)
index 0000000..550de32
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
+<stringAttribute key="M2_GOALS" value="clean install"/>
+<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
+<booleanAttribute key="M2_OFFLINE" value="false"/>
+<stringAttribute key="M2_PROFILES" value=""/>
+<listAttribute key="M2_PROPERTIES"/>
+<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
+<booleanAttribute key="M2_SKIP_TESTS" value="false"/>
+<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx768m -XX:MaxPermSize=256m"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/distribution.opendaylight}"/>
+</launchConfiguration>
diff --git a/opendaylight/distribution/opendaylight/opendaylight-sonar-fast.launch b/opendaylight/distribution/opendaylight/opendaylight-sonar-fast.launch
new file mode 100644 (file)
index 0000000..6de99e1
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
+<stringAttribute key="M2_GOALS" value="sonar:sonar"/>
+<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
+<booleanAttribute key="M2_OFFLINE" value="false"/>
+<stringAttribute key="M2_PROFILES" value=""/>
+<listAttribute key="M2_PROPERTIES"/>
+<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
+<booleanAttribute key="M2_SKIP_TESTS" value="false"/>
+<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx768m -XX:MaxPermSize=256m"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${selected_resource_loc}"/>
+</launchConfiguration>
diff --git a/opendaylight/distribution/opendaylight/opendaylight-sonar.launch b/opendaylight/distribution/opendaylight/opendaylight-sonar.launch
new file mode 100644 (file)
index 0000000..a664272
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
+<stringAttribute key="M2_GOALS" value="sonar:sonar"/>
+<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
+<booleanAttribute key="M2_OFFLINE" value="false"/>
+<stringAttribute key="M2_PROFILES" value=""/>
+<listAttribute key="M2_PROPERTIES"/>
+<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
+<booleanAttribute key="M2_SKIP_TESTS" value="false"/>
+<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx768m -XX:MaxPermSize=256m"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/distribution.opendaylight}"/>
+</launchConfiguration>
diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml
new file mode 100644 (file)
index 0000000..3ec92d3
--- /dev/null
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <prerequisites>
+    <maven>3.0</maven>
+  </prerequisites>
+
+  <scm>
+    <connection>scm:svn:https://wwwin-svn-sjc.cisco.com/eng/csdncontroller/trunk/</connection>
+    <developerConnection>scm:svn:https://wwwin-svn-sjc.cisco.com/eng/csdncontroller/trunk/</developerConnection>
+  </scm>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.0-SNAPSHOT</version>
+    <relativePath>../../commons/opendaylight</relativePath>
+  </parent>
+
+  <repositories>
+    <!-- To get SVNKit -->
+    <repository>
+      <id>svnkit-snapshots</id>
+      <name>svnkit-snapshots</name>
+      <url>${nexusproxy}/repositories/svnkit-snapshots/</url>
+    </repository>
+  </repositories>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>distribution.opendaylight</artifactId>
+  <version>0.1.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  <modules>
+    <module>../../clustering/services</module>
+    <module>../../clustering/services_implementation</module>
+    <module>../../clustering/stub</module>
+    <module>../../clustering/test</module>
+    <module>../../../third-party/openflowj</module>
+    <module>../../../third-party/net.sf.jung2</module>
+    <module>../../../third-party/jersey-servlet</module>
+    
+    <!-- SAL bundles -->
+    <module>../../sal/api</module>
+    <module>../../sal/implementation</module>
+
+    <!-- Debug and logging -->
+    <module>../../logging/bridge</module>
+  </modules>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>buildnumber-maven-plugin</artifactId>
+        <version>1.2</version>
+        <executions>
+          <execution>
+            <phase>validate</phase>
+            <goals>
+              <goal>create</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <doCheck>false</doCheck>
+          <doUpdate>false</doUpdate>
+          <providerImplementations>
+            <svn>javasvn</svn>
+          </providerImplementations>
+          <revisionOnScmFailure>VersionUnknown</revisionOnScmFailure>
+        </configuration>
+        <dependencies>
+          <dependency>
+            <groupId>com.google.code.maven-scm-provider-svnjava</groupId>
+            <artifactId>maven-scm-provider-svnjava</artifactId>
+            <version>2.0.5</version>
+          </dependency>
+          <dependency>
+            <groupId>org.tmatesoft.svnkit</groupId>
+            <artifactId>svnkit</artifactId>
+            <version>1.7.4-v1</version>
+          </dependency>
+          <dependency>
+            <groupId>org.apache.maven.scm</groupId>
+            <artifactId>maven-scm-provider-svn-commons</artifactId>
+            <version>1.7</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>2.3</version>
+        <executions>
+          <execution>
+            <id>distro-assembly</id>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+            <configuration>
+              <descriptors>
+                <descriptor>src/assemble/bin.xml</descriptor>
+              </descriptors>
+              <finalName>${project.artifactId}-${build.suffix}</finalName>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/opendaylight/distribution/opendaylight/src/assemble/bin.xml b/opendaylight/distribution/opendaylight/src/assemble/bin.xml
new file mode 100644 (file)
index 0000000..3c163fd
--- /dev/null
@@ -0,0 +1,108 @@
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" 
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+  <id>osgipackage</id>
+  <formats>
+    <format>dir</format>
+    <format>zip</format>
+  </formats>
+  <includeBaseDirectory>false</includeBaseDirectory>
+  <moduleSets>
+    <moduleSet>
+      <excludes>
+        <exclude>org.opendaylight.controller.thirdparty:org.openflow.openflowj</exclude>
+        <exclude>org.opendaylight.controller:clustering.stub</exclude>
+               <exclude>org.opendaylight.controller:logging.bridge</exclude>
+      </excludes>
+      <binaries>
+        <outputDirectory>opendaylight/plugins</outputDirectory>
+        <outputFileNameMapping>
+          ${module.groupId}.${module.artifactId}-${module.version}${dashClassifier?}.${module.extension}
+        </outputFileNameMapping>
+        <unpack>false</unpack>
+        <includeDependencies>false</includeDependencies>
+      </binaries>
+    </moduleSet>
+       <moduleSet>
+         <includes>
+               <include>org.opendaylight.controller:logging.bridge</include>
+         </includes>
+         <binaries>
+               <outputDirectory>opendaylight/lib</outputDirectory>
+               <outputFileNameMapping>
+                 ${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}
+               </outputFileNameMapping>
+               <unpack>false</unpack>
+               <includeDependencies>false</includeDependencies>
+         </binaries>
+       </moduleSet>
+  </moduleSets>
+  <dependencySets>
+    <dependencySet>
+      <outputDirectory>opendaylight/plugins</outputDirectory>
+      <excludes>
+        <exclude>equinoxSDK381:org.eclipse.osgi</exclude>
+        <exclude>equinoxSDK381:org.eclipse.equinox.console</exclude>
+        <exclude>equinoxSDK381:org.eclipse.equinox.launcher</exclude>
+        <exclude>equinoxSDK381:org.eclipse.equinox.ds</exclude>
+        <exclude>equinoxSDK381:org.eclipse.equinox.util</exclude>
+        <exclude>equinoxSDK381:org.eclipse.osgi.services</exclude>
+        <exclude>virgomirror:org.eclipse.jdt.core.compiler.batch</exclude>
+        <exclude>org.apache.felix:org.apache.felix.fileinstall</exclude>
+        <exclude>geminiweb:org.eclipse.virgo.kernel.equinox.extensions</exclude>
+               <exclude>org.slf4j:slf4j-api</exclude>
+               <exclude>ch.qos.logback:logback-core</exclude>
+               <exclude>ch.qos.logback:logback-classic</exclude>
+      </excludes>
+      <outputFileNameMapping>
+        ${artifact.groupId}.${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}      
+      </outputFileNameMapping>
+      <unpack>false</unpack>
+      <scope>runtime</scope>
+      <useTransitiveDependencies>false</useTransitiveDependencies>
+    </dependencySet>
+    <dependencySet>
+      <outputDirectory>opendaylight/lib</outputDirectory>
+      <includes>
+        <include>equinoxSDK381:org.eclipse.osgi</include>
+        <include>equinoxSDK381:org.eclipse.equinox.console</include>
+        <include>equinoxSDK381:org.eclipse.equinox.launcher</include>
+        <include>equinoxSDK381:org.eclipse.equinox.ds</include>
+        <include>equinoxSDK381:org.eclipse.equinox.util</include>
+        <include>equinoxSDK381:org.eclipse.osgi.services</include>
+        <include>virgomirror:org.eclipse.jdt.core.compiler.batch</include>
+        <include>org.apache.felix:org.apache.felix.fileinstall</include>
+        <include>geminiweb:org.eclipse.virgo.kernel.equinox.extensions</include>
+               <include>org.slf4j:slf4j-api</include>
+               <include>ch.qos.logback:logback-core</include>
+               <include>ch.qos.logback:logback-classic</include>
+      </includes>
+      <useTransitiveDependencies>false</useTransitiveDependencies>
+      <outputFileNameMapping>
+        ${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}      
+      </outputFileNameMapping>
+      <unpack>false</unpack>
+      <scope>runtime</scope>
+    </dependencySet>
+  </dependencySets>
+  <fileSets>
+    <fileSet>
+      <directory>
+        src/main/resources/
+      </directory>
+      <excludes>
+        <exclude>version.properties</exclude>
+      </excludes>
+      <outputDirectory>
+        opendaylight/
+      </outputDirectory>
+    </fileSet>
+  </fileSets>
+  <files>
+    <file>
+      <source>src/main/resources/version.properties</source>
+      <outputDirectory>opendaylight</outputDirectory>
+      <filtered>true</filtered>
+    </file>
+  </files>
+</assembly>
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini
new file mode 100644 (file)
index 0000000..1b3d1ec
--- /dev/null
@@ -0,0 +1,41 @@
+osgi.bundles=\
+       reference\:file\:../lib/org.apache.felix.fileinstall-3.1.6.jar@1:start,\
+       reference\:file\:../lib/org.eclipse.jdt.core.compiler.batch-3.8.0.I20120518-2145.jar@1:start,\
+       reference\:file\:../lib/org.eclipse.equinox.ds-1.4.0.v20120522-1841.jar@2:start,\
+       reference\:file\:../lib/org.eclipse.equinox.util-1.0.400.v20120522-2049.jar@2:start,\
+       reference\:file\:../lib/org.eclipse.osgi.services-3.3.100.v20120522-1822@2:start,\
+       reference\:file\:../lib/org.eclipse.equinox.console-1.0.0.v20120522-1841.jar@start,\
+       reference\:file\:../lib/slf4j-api-1.7.2.jar@1:start,\
+       reference\:file\:../lib/logback-classic-1.0.9.jar@1:start,\
+       reference\:file\:../lib/logback-core-1.0.9.jar@1:start,\
+        reference\:file\:../lib/logging.bridge-0.4.0-SNAPSHOT@1:start
+
+# Set Default start level for framework
+osgi.bundles.defaultStartLevel=4
+# Extra packages to import from the boot class loader
+org.osgi.framework.system.packages.extra=sun.reflect,sun.reflect.misc,sun.misc
+# This is not Eclipse App
+eclipse.ignoreApp=true
+# Don't shutdown equinox if the eclipse App has ended, 
+# which is our case because we are not running any eclipse application
+osgi.noShutdown=true
+# Clean any cached data on restart of the framework
+osgi.clean=true
+# Extend the framework to avoid the resources to be presented with
+# a URL of type bundleresource: but to be presented as file:
+osgi.hook.configurators.include=org.eclipse.virgo.kernel.equinox.extensions.hooks.ExtensionsHookConfigurator
+# Directory from where the fileinstall will monitor for new bundles
+felix.fileinstall.dir=./plugins
+# Immediately learn new bundles at startup
+felix.fileinstall.noInitialDelay=true
+# Auto start the bundles at level 4
+felix.fileinstall.start.level=4
+# Avoid to auto-install following bundles, that means those need 
+# to be started manually or in other way like osgi.bundles
+felix.fileinstall.filter=^(?!org.apache.felix.fileinstall).*
+
+# logback configuration
+logback.configurationFile=configuration/logback.xml
+
+# Embedded Tomcat configuration File
+org.eclipse.gemini.web.tomcat.config.path=configuration/tomcat-server.xml
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/context.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/context.xml
new file mode 100644 (file)
index 0000000..85bba5a
--- /dev/null
@@ -0,0 +1 @@
+<Context crossContext="true"/>
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml
new file mode 100644 (file)
index 0000000..3c3f788
--- /dev/null
@@ -0,0 +1,55 @@
+<configuration scan="true">
+
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n</pattern>
+    </encoder>
+  </appender>
+  <appender name="opendaylight.log" class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>logs/opendaylight.log</file>
+
+    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+      <fileNamePattern>logs/opendaylight.%d.log.zip</fileNamePattern>
+      <maxHistory>1</maxHistory>
+    </rollingPolicy>
+
+    <encoder>
+      <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{35} - %msg%n</pattern>
+    </encoder>
+  </appender>
+
+  <root level="error">
+    <appender-ref ref="STDOUT" />
+    <appender-ref ref="opendaylight.log" />
+  </root>
+
+  <!--  Base log level  -->
+  <logger name="org.opendaylight.controller" level="INFO"/>
+
+  <!-- OSGi logging bridge -->
+  <logger name="org.opendaylight.controller.logging.bridge" level="WARN"/>
+
+  <!-- Openflow Protocol Plugin -->
+  <logger name="org.opendaylight.controller.protocol_plugin.openflow" level="INFO"/>
+  <logger name="org.opendaylight.controller.protocol_plugin.openflow.internal.DiscoveryService" level="INFO"/>
+  <logger name="org.opendaylight.controller.protocol_plugin.openflow.internal.InventoryService" level="INFO"/>
+  <logger name="org.opendaylight.controller.protocol_plugin.openflow.internal.InventoryServiceShim" level="INFO"/>
+  <logger name="org.opendaylight.controller.protocol_plugin.openflow.internal.TopologyServices" level="INFO"/>
+  <logger name="org.opendaylight.controller.protocol_plugin.openflow.internal.TopologyServiceShim" level="INFO"/>
+  <!-- SAL  -->
+  <logger name="org.opendaylight.controller.sal" level="INFO"/>
+  <logger name="org.opendaylight.controller.sal.implementation" level="INFO"/>
+  <logger name="org.opendaylight.controller.sal.implementation.internal.Inventory" level="INFO"/>
+  <logger name="org.opendaylight.controller.sal.implementation.internal.Topology" level="INFO"/>
+  <!-- Functional Modules -->
+  <logger name="org.opendaylight.controller.arphandler" level="INFO"/>
+  <logger name="org.opendaylight.controller.hosttracker" level="INFO"/>
+  <logger name="org.opendaylight.controller.routing" level="INFO"/>
+  <logger name="org.opendaylight.controller.forwardingrulesmanager" level="INFO"/>
+  <logger name="org.opendaylight.controller.forwarding.ipswitch" level="INFO"/>
+  <logger name="org.opendaylight.controller.switchmanager" level="INFO"/>
+  <logger name="org.opendaylight.controller.topologymanager" level="INFO"/>
+  <logger name="org.opendaylight.controller.usermanager" level="INFO"/>
+  <!-- Web modules -->
+  <logger name="org.opendaylight.controller.web" level="INFO"/>        
+</configuration>
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/tomcat-server.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/tomcat-server.xml
new file mode 100644 (file)
index 0000000..42199b7
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<Server>
+  <!--APR library loader. Documentation at /docs/apr.html -->
+  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
+  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
+  <Listener className="org.apache.catalina.core.JasperListener" />
+  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
+  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
+  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
+  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
+
+  <Service name="Catalina">
+    <Connector port="8080" protocol="HTTP/1.1"
+               connectionTimeout="20000"
+               redirectPort="8443" />
+
+<!-- 
+       Please remove the comments around the following Connector tag to enable HTTPS Authentication support.
+       Remember to add a valid keystore in the configuration folder.
+       More info : http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration 
+-->
+ <!-- 
+    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
+               maxThreads="150" scheme="https" secure="true"
+               clientAuth="false" sslProtocol="TLS"
+               keystoreFile="configuration/keystore"
+               keystorePass="changeit"/>
+ -->
+
+    <Engine name="Catalina" defaultHost="localhost">
+      <Host name="localhost" appBase=""
+            unpackWARs="false" autoDeploy="false"
+            deployOnStartup="false" createDirs="false">
+
+        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
+                       prefix="web_access_log_" suffix=".txt" resolveHosts="false"
+                       rotatable="true" fileDateFormat="yyyy-MM"
+                       pattern="%{yyyy-MM-dd HH:mm:ss.SSS z}t - [%a] - %r"/>
+               
+      </Host>
+    </Engine>
+  </Service>
+</Server>
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/run.bat b/opendaylight/distribution/opendaylight/src/main/resources/run.bat
new file mode 100644 (file)
index 0000000..79a00f3
--- /dev/null
@@ -0,0 +1,22 @@
+@ECHO OFF
+SETLOCAL
+SETLOCAL ENABLEDELAYEDEXPANSION
+IF EXIST "%JAVA_HOME%" (
+               set basedir=%~dp0
+REM       Now set the classpath:
+                set cp="!basedir!lib\org.eclipse.osgi-3.8.1.v20120830-144521.jar;!basedir!lib\org.eclipse.virgo.kernel.equinox.extensions-3.6.0.RELEASE.jar;!basedir!lib\org.eclipse.equinox.launcher-1.3.0.v20120522-1813.jar"
+
+REM       Now set framework classpath
+               set fwcp="file:\!basedir!lib\org.eclipse.osgi-3.8.1.v20120830-144521.jar,file:\!basedir!lib\org.eclipse.virgo.kernel.equinox.extensions-3.6.0.RELEASE.jar,file:\!basedir!lib\org.eclipse.equinox.launcher-1.3.0.v20120522-1813.jar"
+
+REM echo cp: %cp%
+REM echo fwcp: %fwcp%
+
+REM echo %JAVA_HOME%\bin\java.exe %* -Djava.io.tmpdir=!basedir!work\tmp -Dosgi.install.area=!basedir! -Dosgi.configuration.area=!basedir!configuration -Dosgi.frameworkClassPath=%fwcp% -Dosgi.framework=file:\!basedir!lib\org.eclipse.osgi-3.8.1.v20120830-144521.jar -classpath %cp% org.eclipse.equinox.launcher.Main -console -consoleLog
+"%JAVA_HOME%\bin\java.exe" %* -Djava.io.tmpdir="!basedir!work\tmp" -Dosgi.install.area=!basedir! -Dosgi.configuration.area="!basedir!configuration" -Dosgi.frameworkClassPath=!fwcp! -Dosgi.framework="file:\!basedir!lib\org.eclipse.osgi-3.8.1.v20120830-144521.jar" -classpath !cp! org.eclipse.equinox.launcher.Main -console -consoleLog
+
+) ELSE (
+    ECHO JAVA_HOME environment variable is not set
+    PAUSE
+)
+ENDLOCAL
\ No newline at end of file
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/run.sh b/opendaylight/distribution/opendaylight/src/main/resources/run.sh
new file mode 100755 (executable)
index 0000000..74cadae
--- /dev/null
@@ -0,0 +1,70 @@
+#!/bin/bash
+
+[[ -z ${JAVA_HOME} ]] && echo "Need to set JAVA_HOME environment variable" && exit -1;
+[[ ! -x ${JAVA_HOME}/bin/java ]] && echo "Cannot find an executable \
+JVM at path ${JAVA_HOME}/bin/java check your JAVA_HOME" && exit -1;
+
+platform='unknown'
+unamestr=`uname`
+if [[ "$unamestr" == 'Linux' ]]; then
+   platform='linux'
+elif [[ "$unamestr" == 'Darwin' ]]; then
+   platform='osx'
+fi
+
+if [[ $platform == 'linux' ]]; then
+   fullpath=`readlink -f $0`
+elif [[ $platform == 'osx' ]]; then
+   TARGET_FILE=$0
+   cd `dirname $TARGET_FILE`
+   TARGET_FILE=`basename $TARGET_FILE`
+
+   # Iterate down a (possible) chain of symlinks
+   while [ -L "$TARGET_FILE" ]
+   do
+       TARGET_FILE=`readlink $TARGET_FILE`
+       cd `dirname $TARGET_FILE`
+       TARGET_FILE=`basename $TARGET_FILE`
+   done
+
+   # Compute the canonicalized name by finding the physical path
+   # for the directory we're in and appending the target file.
+   PHYS_DIR=`pwd -P`
+   RESULT=$PHYS_DIR/$TARGET_FILE
+   fullpath=$RESULT
+fi
+
+basedir=`dirname ${fullpath}`
+
+########################################
+# Now add to classpath the OSGi JAR
+########################################
+CLASSPATH=${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar
+FWCLASSPATH=file:${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar
+
+########################################
+# Now add the extensions
+########################################
+
+# Extension 1: this is used to be able to convert all the
+# bundleresouce: URL in file: so packages that are not OSGi ready can
+# still work. Notably this is the case for spring classes
+CLASSPATH=${CLASSPATH}:${basedir}/lib/org.eclipse.virgo.kernel.equinox.extensions-3.6.0.RELEASE.jar
+FWCLASSPATH=${FWCLASSPATH},file:${basedir}/lib/org.eclipse.virgo.kernel.equinox.extensions-3.6.0.RELEASE.jar
+
+########################################
+# Now add the launcher
+########################################
+CLASSPATH=${CLASSPATH}:${basedir}/lib/org.eclipse.equinox.launcher-1.3.0.v20120522-1813.jar
+FWCLASSPATH=${FWCLASSPATH},file:${basedir}/lib/org.eclipse.equinox.launcher-1.3.0.v20120522-1813.jar
+
+$JAVA_HOME/bin/java $@ \
+    -Djava.io.tmpdir=${basedir}/work/tmp \
+    -Dosgi.install.area=${basedir} \
+    -Dosgi.configuration.area=${basedir}/configuration \
+    -Dosgi.frameworkClassPath=${FWCLASSPATH} \
+    -Dosgi.framework=file:${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar \
+    -classpath ${CLASSPATH} \
+    org.eclipse.equinox.launcher.Main \
+    -console \
+    -consoleLog
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/version.properties b/opendaylight/distribution/opendaylight/src/main/resources/version.properties
new file mode 100644 (file)
index 0000000..90af49d
--- /dev/null
@@ -0,0 +1,6 @@
+org.opendaylight.controller.version = 0.1
+org.opendaylight.controller.build.scm.version = ${buildNumber}
+org.opendaylight.controller.build.user = ${env.USER}
+org.opendaylight.controller.build.workspace = **********
+org.opendaylight.controller.build.timestamp = ${timestamp}
+org.opendaylight.controller.build.machine = **********
diff --git a/opendaylight/distribution/sdk/pom.xml b/opendaylight/distribution/sdk/pom.xml
new file mode 100644 (file)
index 0000000..51152c9
--- /dev/null
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <prerequisites>
+    <maven>3.0</maven>
+  </prerequisites>
+
+  <scm>
+    <connection>scm:svn:https://wwwin-svn-sjc.cisco.com/eng/csdncontroller/trunk/</connection>
+    <developerConnection>scm:svn:https://wwwin-svn-sjc.cisco.com/eng/csdncontroller/trunk/</developerConnection>
+  </scm>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.0-SNAPSHOT</version>
+    <relativePath>../../commons/opendaylight</relativePath>
+  </parent>
+
+  <repositories>
+    <!-- To get SVNKit -->
+    <repository>
+      <id>svnkit-snapshots</id>
+      <name>svnkit-snapshots</name>
+      <url>${nexusproxy}/repositories/svnkit-snapshots/</url>
+    </repository>
+  </repositories>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>distribution.sdk</artifactId>
+  <version>0.1.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  <modules>
+    <module>../../clustering/services</module>
+    <module>../../sal/api</module>
+  </modules>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>buildnumber-maven-plugin</artifactId>
+        <version>1.2</version>
+        <executions>
+          <execution>
+            <phase>validate</phase>
+            <goals>
+              <goal>create</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <doCheck>false</doCheck>
+          <doUpdate>false</doUpdate>
+          <providerImplementations>
+            <svn>javasvn</svn>
+          </providerImplementations>
+          <revisionOnScmFailure>VersionUnknown</revisionOnScmFailure>
+        </configuration>
+        <dependencies>
+          <dependency>
+            <groupId>com.google.code.maven-scm-provider-svnjava</groupId>
+            <artifactId>maven-scm-provider-svnjava</artifactId>
+            <version>2.0.5</version>
+          </dependency>
+          <dependency>
+            <groupId>org.tmatesoft.svnkit</groupId>
+            <artifactId>svnkit</artifactId>
+            <version>1.7.4-v1</version>
+          </dependency>
+          <dependency>
+            <groupId>org.apache.maven.scm</groupId>
+            <artifactId>maven-scm-provider-svn-commons</artifactId>
+            <version>1.7</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>2.3</version>
+        <executions>
+          <execution>
+            <id>distro-assembly</id>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+            <configuration>
+              <descriptors>
+                <descriptor>src/assemble/bin.xml</descriptor>
+              </descriptors>
+              <finalName>${project.artifactId}-${build.suffix}</finalName>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <version>4.2.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>4.3.0</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/opendaylight/distribution/sdk/src/assemble/bin.xml b/opendaylight/distribution/sdk/src/assemble/bin.xml
new file mode 100644 (file)
index 0000000..bb3c673
--- /dev/null
@@ -0,0 +1,39 @@
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" 
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+  <id>package</id>
+  <formats>
+    <format>dir</format>
+    <format>zip</format>
+  </formats>
+  <includeBaseDirectory>false</includeBaseDirectory>
+  <moduleSets>
+    <moduleSet>
+      <binaries>
+        <outputDirectory>sdk/</outputDirectory>
+        <outputFileNameMapping>
+          ${module.groupId}.${module.artifactId}-${module.version}${dashClassifier?}.${module.extension}
+        </outputFileNameMapping>
+        <unpack>false</unpack>
+        <includeDependencies>false</includeDependencies>
+      </binaries>
+    </moduleSet>
+  </moduleSets>
+  <dependencySets>
+    <dependencySet>
+      <outputDirectory>sdk/</outputDirectory>
+      <includes>
+        <include>org.apache.felix:org.apache.felix.dependencymanager</include>
+        <include>org.osgi:org.osgi.compendium</include>
+        <include>org.osgi:org.osgi.core</include>
+        <include>org.slf4j:slf4j-api</include>
+      </includes>
+      <outputFileNameMapping>
+        ${artifact.groupId}.${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}
+      </outputFileNameMapping>
+      <unpack>false</unpack>
+      <scope>runtime</scope>
+      <useTransitiveDependencies>false</useTransitiveDependencies>
+    </dependencySet>
+  </dependencySets>
+</assembly>
diff --git a/opendaylight/logging/bridge/pom.xml b/opendaylight/logging/bridge/pom.xml
new file mode 100644 (file)
index 0000000..ba0ace7
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.0-SNAPSHOT</version>
+    <relativePath>../../commons/opendaylight</relativePath>
+  </parent>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>logging.bridge</artifactId>
+  <version>0.4.0-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>2.3.6</version>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Import-Package>
+              org.slf4j,
+              org.osgi.framework,
+              org.osgi.service.log
+            </Import-Package>
+            <Bundle-Activator>
+              org.opendaylight.controller.logging.bridge.internal.Activator
+            </Bundle-Activator>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/Activator.java b/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/Activator.java
new file mode 100644 (file)
index 0000000..90908ef
--- /dev/null
@@ -0,0 +1,80 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.logging.bridge.internal;
+
+import org.osgi.service.log.LogEntry;
+import java.util.Enumeration;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.ILoggerFactory;
+import org.osgi.service.log.LogReaderService;
+
+public class Activator implements BundleActivator {
+    private LogListenerImpl listener = null;
+    private Logger log = null;
+
+    @Override
+    public void start(BundleContext context) {
+        // Lets trigger the resolution of the slf4j logger factory
+        ILoggerFactory f = LoggerFactory.getILoggerFactory();
+
+        // Now retrieve a logger for the bridge
+        log = f
+                .getLogger("org.opendaylight.controller.logging.bridge.OSGI2SLF4J");
+
+        if (this.log != null) {
+            this.listener = new LogListenerImpl(log);
+
+            ServiceReference service = null;
+            service = context.getServiceReference(LogReaderService.class
+                    .getName());
+            if (service != null) {
+                LogReaderService reader = (LogReaderService) context
+                        .getService(service);
+                if (reader == null) {
+                    this.log.error("Cannot register the LogListener because "
+                            + "cannot retrive LogReaderService");
+                }
+                reader.addLogListener(this.listener);
+                // Now lets walk all the exiting messages
+                Enumeration<LogEntry> entries = reader.getLog();
+                if (entries != null) {
+                    while (entries.hasMoreElements()) {
+                        LogEntry entry = (LogEntry) entries.nextElement();
+                        this.listener.logged(entry);
+                    }
+                }
+            } else {
+                this.log.error("Cannot register the LogListener because "
+                        + "cannot retrive LogReaderService");
+            }
+        } else {
+            System.err
+                    .println("Could not initialize the logging bridge subsytem");
+        }
+    }
+
+    @Override
+    public void stop(BundleContext context) {
+        ServiceReference service = null;
+        service = context.getServiceReference(LogReaderService.class.getName());
+        if (service != null) {
+            LogReaderService reader = (LogReaderService) service;
+            reader.removeLogListener(this.listener);
+        }
+
+        this.listener = null;
+        this.log = null;
+    }
+}
diff --git a/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/LogListenerImpl.java b/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/LogListenerImpl.java
new file mode 100644 (file)
index 0000000..d3c72b9
--- /dev/null
@@ -0,0 +1,43 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.logging.bridge.internal;
+
+import org.osgi.service.log.LogEntry;
+import org.osgi.service.log.LogListener;
+import org.osgi.service.log.LogService;
+import org.slf4j.Logger;
+
+public class LogListenerImpl implements LogListener {
+    private Logger logger = null;
+
+    public LogListenerImpl(Logger l) {
+        this.logger = l;
+    }
+
+    @Override
+    public void logged(LogEntry entry) {
+        if (this.logger != null) {
+            switch (entry.getLevel()) {
+            case LogService.LOG_DEBUG:
+                this.logger.debug(entry.getMessage());
+                break;
+            case LogService.LOG_INFO:
+                this.logger.info(entry.getMessage());
+                break;
+            case LogService.LOG_WARNING:
+                this.logger.warn(entry.getMessage());
+                break;
+            case LogService.LOG_ERROR:
+                this.logger.error(entry.getMessage());
+                break;
+            }
+        }
+    }
+}
diff --git a/opendaylight/sal/api/pom.xml b/opendaylight/sal/api/pom.xml
new file mode 100644 (file)
index 0000000..9d8c814
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>commons.opendaylight</artifactId>\r
+    <version>1.4.0-SNAPSHOT</version>\r
+    <relativePath>../../commons/opendaylight</relativePath>\r
+  </parent>\r
+\r
+  <groupId>org.opendaylight.controller</groupId>\r
+  <artifactId>sal</artifactId>\r
+  <version>0.4.0-SNAPSHOT</version>\r
+  <packaging>bundle</packaging>\r
+\r
+  <build>\r
+    <plugins>\r
+      <plugin>\r
+        <groupId>org.apache.felix</groupId>\r
+        <artifactId>maven-bundle-plugin</artifactId>\r
+        <version>2.3.6</version>\r
+        <extensions>true</extensions>\r
+        <configuration>\r
+          <instructions>\r
+            <Import-Package>\r
+              org.slf4j,\r
+              org.osgi.framework,\r
+              org.apache.commons.lang3.builder,\r
+              org.apache.felix.dm,\r
+              org.apache.commons.lang3.tuple,\r
+              javax.xml.bind.annotation,\r
+              javax.xml.bind.annotation.adapters\r
+            </Import-Package>\r
+            <Export-Package>\r
+              org.opendaylight.controller.sal.authorization,\r
+                         org.opendaylight.controller.sal.action,\r
+              org.opendaylight.controller.sal.core,\r
+              org.opendaylight.controller.sal.discovery,\r
+              org.opendaylight.controller.sal.topology,\r
+              org.opendaylight.controller.sal.routing,\r
+              org.opendaylight.controller.sal.packet,\r
+              org.opendaylight.controller.sal.packet.address,\r
+              org.opendaylight.controller.sal.utils,\r
+              org.opendaylight.controller.sal.match,\r
+              org.opendaylight.controller.sal.inventory,\r
+              org.opendaylight.controller.sal.flowprogrammer,\r
+              org.opendaylight.controller.sal.reader\r
+            </Export-Package>\r
+          </instructions>\r
+        </configuration>\r
+      </plugin>\r
+    </plugins>\r
+  </build>\r
+  <dependencies>\r
+    <dependency>\r
+      <groupId>junit</groupId>\r
+      <artifactId>junit</artifactId>\r
+      <version>4.8.1</version>\r
+      <scope>test</scope>\r
+    </dependency>\r
+  </dependencies>\r
+</project>\r
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Action.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Action.java
new file mode 100644 (file)
index 0000000..b4f9cb5
--- /dev/null
@@ -0,0 +1,138 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents the generic action to be applied to the matched frame/packet/message
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+@XmlSeeAlso({Controller.class, Drop.class, Flood.class, FloodAll.class, HwPath.class, Loopback.class, Output.class,
+                        PopVlan.class, PushVlan.class, SetDlDst.class, SetDlSrc.class, SetDlType.class, SetNwDst.class, SetNwSrc.class,
+                        SetNwTos.class, SetTpDst.class, SetTpSrc.class, SetVlanCfi.class, SetVlanId.class, SetVlanPcp.class, SwPath.class})
+public abstract class Action {
+    private static final Logger logger = LoggerFactory.getLogger(Action.class);
+    private static boolean debug = false; // Enable to find where in the code an invalid assignment is made
+    @XmlTransient
+    protected ActionType type;
+    private transient boolean isValid = true;
+
+    /* Dummy constructor for JAXB */
+    public Action () {
+    }
+
+    /*
+    public Action (ActionType type, Object value) {
+       this.type = type;
+       this.value = value;
+       this.isValid = true;
+    } */
+
+    /**
+     * Checks if the passed value is in the valid range for this action
+     *
+     * @param value
+     * @return boolean
+     */
+    protected void checkValue(int value) {
+        if (type.isValidTarget(value) == false) {
+            isValid = false;
+            throwValueException(value);
+        }
+    }
+
+    /**
+     * Checks if the passed value is in the valid range for the passed action type
+     * This method is used for complex Action types which are
+     *
+     * @param value
+     * @return boolean
+     */
+    protected void checkValue(ActionType type, int value) {
+        if (type.isValidTarget(value) == false) {
+            isValid = false;
+            throwValueException(value);
+        }
+    }
+
+    /**
+     * Throw and handle the invalid value exception
+     *
+     * @param value
+     * @return void
+     */
+    private void throwValueException(int value) {
+        String error = "Invalid field value assignement. For type: "
+                + type.getId() + " Expected: " + type.getRange() + ", Got: 0x"
+                + Integer.toHexString(value);
+        try {
+            throw new Exception(error);
+        } catch (Exception e) {
+            logger.error(e.getMessage());
+            if (debug) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Returns the type of this action
+     *
+     * @return ActionType
+     */
+    public ActionType getType() {
+        return type;
+    }
+
+    /**
+     * Returns the id of this action
+     *
+     * @return String
+     */
+    public String getId() {
+        return type.getId();
+    }
+
+    /**
+     * Returns whether the Action is valid or not
+     *
+     * @return boolean
+     */
+    public boolean isValid() {
+        return isValid;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return type.toString();
+    }
+
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/ActionType.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/ActionType.java
new file mode 100644 (file)
index 0000000..8582046
--- /dev/null
@@ -0,0 +1,73 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+/**
+ * The enumeration of actions supported by the controller
+ * Each entry has a unique id and the values range for the action element where applicable
+ *
+ *
+ *
+ */
+public enum ActionType {
+    DROP("drop", 0, 0), LOOPBACK("loopback", 0, 0), FLOOD("flood", 0, 0), // regular switching flood (obeys to stp port state)
+    FLOOD_ALL("floodAll", 0, 0), // flood to all ports regardless of stp port state
+    CONTROLLER("controller", 0, 0), INTERFACE("interface", 0, 0), // Interface
+    SW_PATH("software path", 0, 0), // OF Local
+    HW_PATH("harware path", 0, 0), OUTPUT("output", 0, 0xffff), // physical port
+    ENQUEUE("enqueue", 0, 0xffff), SET_DL_SRC("setDlSrc", 0, 0), SET_DL_DST(
+            "setDlDst", 0, 0), SET_VLAN_ID("setVlan", 2, 0xfff), SET_VLAN_PCP(
+            "setVlanPcp", 0, 0x7), SET_VLAN_CFI("setVlanCif", 0, 0x1), POP_VLAN(
+            "stripVlan", 0, 0), // Pop
+    PUSH_VLAN("pushVlan", 0, 0xffff), // Push (the max value only takes into account the TCI portion of the 802.1q header)
+    SET_DL_TYPE("setDlType", 0, 0xffff), // Set ethertype/length field
+    SET_NW_SRC("setNwSrc", 0, 0), SET_NW_DST("setNwDst", 0, 0), SET_NW_TOS(
+            "setNwTos", 0, 0xff), SET_TP_SRC("setTpSrc", 0, 0xffff), SET_TP_DST(
+            "setTpDst", 0, 0xffff), SET_NEXT_HOP("setNextHop", 0, 0);
+
+    private String id;
+    private int minValue;
+    private int maxValue;
+
+    private ActionType(String id, int minValue, int maxValue) {
+        this.id = id;
+        this.minValue = minValue;
+        this.maxValue = maxValue;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public boolean isValidTarget(int value) {
+        return (value >= minValue && value <= maxValue);
+    }
+
+    public String getRange() {
+        return "[0x" + Long.toHexString(minValue) + "-0x"
+                + Long.toHexString(maxValue) + "]";
+    }
+
+    public boolean takesParameter() {
+        switch (this) {
+        case POP_VLAN:
+        case DROP:
+        case SW_PATH:
+        case HW_PATH:
+        case CONTROLLER:
+        case LOOPBACK:
+        case FLOOD:
+        case FLOOD_ALL:
+            return false;
+        default:
+            return true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Controller.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Controller.java
new file mode 100644 (file)
index 0000000..1c7cc7b
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Represents the action of punting the packet to the controller
+ *
+ *
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class Controller extends Action {
+
+    public Controller() {
+        type = ActionType.CONTROLLER;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Drop.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Drop.java
new file mode 100644 (file)
index 0000000..1297a15
--- /dev/null
@@ -0,0 +1,28 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Represent the action of dropping the matched packet
+ *
+ *
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class Drop extends Action {
+    public Drop() {
+        type = ActionType.DROP;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Flood.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Flood.java
new file mode 100644 (file)
index 0000000..4d2436b
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Represents the action of flooding the packet out
+ *
+ *
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class Flood extends Action {
+
+    public Flood() {
+        type = ActionType.FLOOD;
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/FloodAll.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/FloodAll.java
new file mode 100644 (file)
index 0000000..b0f60d4
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Represents the action of flooding the packet out all the physical ports except the input port
+ *
+ *
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class FloodAll extends Action {
+
+    public FloodAll() {
+        type = ActionType.FLOOD_ALL;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/HwPath.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/HwPath.java
new file mode 100644 (file)
index 0000000..fc77867
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Represents the action of sending the packet to the local hardware path for processing
+ *
+ *
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class HwPath extends Action {
+
+    public HwPath() {
+        type = ActionType.HW_PATH;
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Loopback.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Loopback.java
new file mode 100644 (file)
index 0000000..b930eec
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Represents the action of looping the packet back the port it came in from
+ *
+ *
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class Loopback extends Action {
+
+    public Loopback() {
+        type = ActionType.LOOPBACK;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Output.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Output.java
new file mode 100644 (file)
index 0000000..8c23da8
--- /dev/null
@@ -0,0 +1,62 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.opendaylight.controller.sal.core.NodeConnector;
+
+/**
+ * Represents the action of sending the packet out of a physical port
+ *
+ *
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class Output extends Action {
+       @XmlElement
+    private NodeConnector port;
+
+    /* Dummy constructor for JAXB */
+    private Output () {
+    }
+
+    public Output(NodeConnector port) {
+        type = ActionType.OUTPUT;
+        this.port = port;
+        //checkValue(port);
+    }
+
+    public NodeConnector getPort() {
+        return port;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        return EqualsBuilder.reflectionEquals(this, other);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return type + "[" + port.toString() + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/PopVlan.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/PopVlan.java
new file mode 100644 (file)
index 0000000..6ef37fd
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Pop vlan action (strip the outermost 802.1q header)
+ *
+ *
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class PopVlan extends Action {
+
+    public PopVlan() {
+        type = ActionType.POP_VLAN;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/PushVlan.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/PushVlan.java
new file mode 100644 (file)
index 0000000..d50851a
--- /dev/null
@@ -0,0 +1,165 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.opendaylight.controller.sal.utils.EtherTypes;
+
+/**
+ * Insert a 802.1q (outermost) header action
+ * Execute it multiple times to achieve QinQ
+ *
+ * 802.1q = [TPID(16) + TCI(16)]
+ *                     TCI = [PCP(3) + CFI(1) + VID(12)]
+ *
+ *
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class PushVlan extends Action {
+    private int tag; // TPID - 16 bits
+    private int pcp; // PCP - 3 bits
+    private int cfi; // CFI - 1 bit (drop eligible)
+    private int vlanId; // VID - 12 bits
+    private transient int tci; // TCI = [PCP + CFI + VID] - 16 bits
+    private transient int header; // full 802.1q header [TPID + TCI] - 32 bits
+
+    /* Dummy constructor for JAXB */
+    private PushVlan () {
+    }
+
+    public PushVlan(int tag, int pcp, int cfi, int vlanId) {
+        type = ActionType.PUSH_VLAN;
+        this.tag = tag;
+        this.cfi = cfi;
+        this.pcp = pcp;
+        this.vlanId = vlanId;
+        this.tci = createTci();
+        this.header = createHeader();
+        runChecks();
+    }
+
+    public PushVlan(EtherTypes tag, int pcp, int cfi, int vlanId) {
+        type = ActionType.PUSH_VLAN;
+        this.tag = tag.intValue();
+        this.cfi = cfi;
+        this.pcp = pcp;
+        this.vlanId = vlanId;
+        this.tci = createTci();
+        this.header = createHeader();
+        runChecks();
+    }
+
+    private int createTci() {
+        return (pcp & 0x7) << 13 | (cfi & 0x1) << 12 | (vlanId & 0xfff);
+    }
+
+    private int createHeader() {
+        return (tag & 0xffff) << 16 | (pcp & 0x7) << 13 | (cfi & 0x1) << 12
+                | (vlanId & 0xfff);
+    }
+
+    private void runChecks() {
+        checkValue(ActionType.SET_DL_TYPE, tag);
+        checkValue(ActionType.SET_VLAN_PCP, pcp);
+        checkValue(ActionType.SET_VLAN_CFI, cfi);
+        checkValue(ActionType.SET_VLAN_ID, vlanId);
+        checkValue(tci);
+
+        // Run action specific check which cannot be run by parent
+        if (tag != EtherTypes.VLANTAGGED.intValue()
+                && tag != EtherTypes.QINQ.intValue()
+                && tag != EtherTypes.OLDQINQ.intValue()
+                && tag != EtherTypes.CISCOQINQ.intValue()) {
+            // pass a value which will tell fail and tell something about the original wrong value
+            checkValue(ActionType.SET_DL_TYPE, 0xBAD << 16 | tag);
+        }
+    }
+
+    /**
+     * Returns the VID portion of the 802.1q header this action will insert
+     * VID - (12 bits)
+     * @return byte[]
+     */
+    public int getVlanId() {
+        return vlanId;
+    }
+
+    /**
+     * Returns the CFI portion of the 802.1q header this action will insert
+     * CFI - (1 bit)
+     * @return
+     */
+    public int getCfi() {
+        return cfi;
+    }
+
+    /**
+     * Returns the vlan PCP portion of the 802.1q header this action will insert
+     * PCP - (3 bits)
+     * @return byte[]
+     */
+    public int getPcp() {
+        return pcp;
+    }
+
+    /**
+     * Returns the TPID portion of the 802.1q header this action will insert
+     * TPID - (16 bits)
+     */
+    public int getTag() {
+        return tag;
+    }
+
+    /**
+     * Returns the TCI portion of the 802.1q header this action will insert
+     * TCI = [PCP + CFI + VID] - (16 bits)
+     * @return
+     */
+    public int getTci() {
+        return tci;
+    }
+
+    /**
+     * Returns the full 802.1q header this action will insert
+     * header = [TPID + TIC] (32 bits)
+     *
+     * @return int
+     */
+    @XmlElement(name="VlanHeader")
+    public int getHeader() {
+        return header;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        return EqualsBuilder.reflectionEquals(this, other);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return type + "[tag = " + tag + ", pcp = " + pcp + ", cfi = " + cfi
+                + ", vlanId = " + vlanId + "]";
+    }
+
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetDlDst.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetDlDst.java
new file mode 100644 (file)
index 0000000..53c2806
--- /dev/null
@@ -0,0 +1,68 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.opendaylight.controller.sal.utils.HexEncode;
+
+/**
+ * Set destination datalayer address action
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class SetDlDst extends Action {
+    private byte[] address;
+
+    /* Dummy constructor for JAXB */
+    private SetDlDst () {
+    }
+
+    public SetDlDst(byte[] dlAddress) {
+        type = ActionType.SET_DL_DST;
+        this.address = dlAddress.clone();
+    }
+
+    /**
+     * Returns the datalayer address that this action will set
+     *
+     * @return byte[]
+     */
+    public byte[] getDlAddress() {
+        return address.clone();
+    }
+    
+    @XmlElement(name = "address")
+    public String getDlAddressString() {
+        return HexEncode.bytesToHexString(address);
+    }
+    
+    @Override
+    public boolean equals(Object other) {
+        return EqualsBuilder.reflectionEquals(this, other);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return type + "[address = " + HexEncode.bytesToHexString(address) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetDlSrc.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetDlSrc.java
new file mode 100644 (file)
index 0000000..9d31fe2
--- /dev/null
@@ -0,0 +1,72 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.opendaylight.controller.sal.utils.HexEncode;
+
+/**
+ * Set source datalayer address action
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class SetDlSrc extends Action {
+    private byte[] address;
+
+    /* Dummy constructor for JAXB */
+    private SetDlSrc  () {
+    }
+
+    public SetDlSrc(byte[] dlAddress) {
+        type = ActionType.SET_DL_SRC;
+        if (dlAddress != null) {
+            this.address = dlAddress.clone();
+        } else {
+            this.address = null;
+        }
+    }
+
+    /**
+     * Returns the datalayer address that this action will set
+     *
+     * @return byte[]
+     */
+    public byte[] getDlAddress() {
+        return address.clone();
+    }
+
+    @XmlElement(name = "address")
+    public String getDlAddressString() {
+        return HexEncode.bytesToHexString(address);
+    }
+    
+    @Override
+    public boolean equals(Object other) {
+        return EqualsBuilder.reflectionEquals(this, other);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return type + "[address = " + HexEncode.bytesToHexString(address) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetDlType.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetDlType.java
new file mode 100644 (file)
index 0000000..51a24a6
--- /dev/null
@@ -0,0 +1,71 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.opendaylight.controller.sal.utils.EtherTypes;
+
+/**
+ * Set ethertype/length field action
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class SetDlType extends Action {
+       @XmlElement
+    private int dlType;
+
+    /* Dummy constructor for JAXB */
+    private SetDlType () {
+    }
+
+    public SetDlType(int dlType) {
+        type = ActionType.SET_DL_TYPE;
+        this.dlType = dlType;
+        checkValue(dlType);
+    }
+
+    public SetDlType(EtherTypes dlType) {
+        type = ActionType.SET_DL_TYPE;
+        this.dlType = dlType.intValue();
+        checkValue(this.dlType);
+    }
+
+    /**
+     * Returns the ethertype/lenght value that this action will set
+     *
+     * @return byte[]
+     */
+    public int getDlType() {
+        return dlType;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        return EqualsBuilder.reflectionEquals(this, other);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return type + "[dlType = 0x" + Integer.toHexString(dlType) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetNwDst.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetNwDst.java
new file mode 100644 (file)
index 0000000..7db7081
--- /dev/null
@@ -0,0 +1,69 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import java.net.InetAddress;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * Set network destination address action
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class SetNwDst extends Action {
+    InetAddress address;
+
+    /* Dummy constructor for JAXB */
+    private SetNwDst  () {
+    }
+
+    public SetNwDst(InetAddress address) {
+        type = ActionType.SET_NW_DST;
+        this.address = address;
+    }
+
+    /**
+     * Returns the network address this action will set
+     *
+     * @return InetAddress
+     */
+    public InetAddress getAddress() {
+        return address;
+    }
+    
+    @XmlElement (name="address")
+    public String getAddressAsString() {
+       return address.getHostAddress();
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        return EqualsBuilder.reflectionEquals(this, other);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return type + "[address = " + address + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetNwSrc.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetNwSrc.java
new file mode 100644 (file)
index 0000000..3e75e47
--- /dev/null
@@ -0,0 +1,69 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import java.net.InetAddress;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * Set network source address action
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class SetNwSrc extends Action {
+    InetAddress address;
+
+    /* Dummy constructor for JAXB */
+    private SetNwSrc () {
+    }
+
+    public SetNwSrc(InetAddress address) {
+        type = ActionType.SET_NW_SRC;
+        this.address = address;
+    }
+
+    /**
+     * Returns the network address this action will set
+     *
+     * @return InetAddress
+     */
+    public InetAddress getAddress() {
+        return address;
+    }
+
+    @XmlElement (name="address")
+    public String getAddressAsString() {
+       return address.getHostAddress();
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        return EqualsBuilder.reflectionEquals(this, other);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return type + "[address = " + address + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetNwTos.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetNwTos.java
new file mode 100644 (file)
index 0000000..33c96d3
--- /dev/null
@@ -0,0 +1,63 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * Set network TOS action
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class SetNwTos extends Action {
+       @XmlElement
+    private int tos;
+
+    /* Dummy constructor for JAXB */
+    private SetNwTos () {
+    }
+
+    public SetNwTos(int tos) {
+        type = ActionType.SET_NW_TOS;
+        this.tos = tos;
+        checkValue(tos);
+    }
+
+    /**
+     * Returns the network TOS value which the action will set
+     *
+     * @return int
+     */
+    public int getNwTos() {
+        return tos;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        return EqualsBuilder.reflectionEquals(this, other);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return type + "[tos = 0x" + Integer.toHexString(tos) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetTpDst.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetTpDst.java
new file mode 100644 (file)
index 0000000..fb7c824
--- /dev/null
@@ -0,0 +1,62 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * Set destination transport port action
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class SetTpDst extends Action {
+       @XmlElement
+    private int port;
+
+    /* Dummy constructor for JAXB */
+    private SetTpDst () {
+    }
+
+    public SetTpDst(int port) {
+        type = ActionType.SET_TP_DST;
+        this.port = port;
+        checkValue(port);
+    }
+
+    /**
+     * Returns the transport port the action will set
+     * @return
+     */
+    public int getPort() {
+        return port;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        return EqualsBuilder.reflectionEquals(this, other);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return type + "[port = " + port + "]";
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetTpSrc.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetTpSrc.java
new file mode 100644 (file)
index 0000000..20210ad
--- /dev/null
@@ -0,0 +1,63 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * Set source transport port action
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class SetTpSrc extends Action {
+       @XmlElement
+    private int port;
+
+    /* Dummy constructor for JAXB */
+    private SetTpSrc () {
+    }
+
+    public SetTpSrc(int port) {
+        type = ActionType.SET_TP_SRC;
+        this.port = port;
+        checkValue(port);
+    }
+
+    /**
+     * Returns the transport port the action will set
+     * @return
+     */
+    public int getPort() {
+        return port;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        return EqualsBuilder.reflectionEquals(this, other);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return type + "[port = " + port + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetVlanCfi.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetVlanCfi.java
new file mode 100644 (file)
index 0000000..c21430e
--- /dev/null
@@ -0,0 +1,63 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * Set vlan CFI action
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class SetVlanCfi extends Action {
+       @XmlElement
+    private int cfi;
+
+    /* Dummy constructor for JAXB */
+    private SetVlanCfi () {
+    }
+
+    public SetVlanCfi(int cfi) {
+        type = ActionType.SET_VLAN_CFI;
+        this.cfi = cfi;
+        checkValue(cfi);
+    }
+
+    /**
+     * Returns the 802.1q CFI value that this action will set
+     * @return
+     */
+    public int getCfi() {
+        return cfi;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        return EqualsBuilder.reflectionEquals(this, other);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return type + "[cfi = " + Integer.toHexString(cfi) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetVlanId.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetVlanId.java
new file mode 100644 (file)
index 0000000..9c9b364
--- /dev/null
@@ -0,0 +1,64 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * Set vlan id action
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class SetVlanId extends Action {
+       @XmlElement
+    private int vlanId;
+
+       private SetVlanId() {
+               
+       }
+       
+    public SetVlanId(int vlanId) {
+        type = ActionType.SET_VLAN_ID;
+        this.vlanId = vlanId;
+        checkValue(vlanId);
+    }
+
+    /**
+     * Returns the vlan id this action will set
+     *
+     * @return int
+     */
+    public int getVlanId() {
+        return vlanId;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        return EqualsBuilder.reflectionEquals(this, other);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return type + "[vlanId = " + vlanId + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetVlanPcp.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetVlanPcp.java
new file mode 100644 (file)
index 0000000..5c315de
--- /dev/null
@@ -0,0 +1,62 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * Set vlan PCP action
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class SetVlanPcp extends Action {
+       @XmlElement
+    private int pcp;
+
+       private SetVlanPcp() {
+               
+       }
+       
+    public SetVlanPcp(int pcp) {
+        type = ActionType.SET_VLAN_PCP;
+        this.pcp = pcp;
+        checkValue(pcp);
+    }
+
+    /**
+     * Returns the value of the vlan PCP this action will set
+     * @return int
+     */
+    public int getPcp() {
+        return pcp;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        return EqualsBuilder.reflectionEquals(this, other);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return type + "[pcp = " + Integer.toHexString(pcp) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SwPath.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SwPath.java
new file mode 100644 (file)
index 0000000..f30d2ee
--- /dev/null
@@ -0,0 +1,27 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Represents the action of sending the packet to the local software path for processing
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class SwPath extends Action {
+
+    public SwPath() {
+        type = ActionType.SW_PATH;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/AppRole.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/AppRole.java
new file mode 100644 (file)
index 0000000..ae867c5
--- /dev/null
@@ -0,0 +1,44 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.authorization;
+
+import java.io.Serializable;
+
+/**
+ * Represents a user role level in the application space
+ * It contains the role name and the role level in the
+ * application context as specified by {@link AppRoleLevel}
+ */
+public class AppRole implements Serializable {
+    private static final long serialVersionUID = 1L;
+    String name;
+    AppRoleLevel level;
+
+    public AppRole(String name, AppRoleLevel level) {
+        this.name = name;
+        this.level = level;
+    }
+
+    /**
+     * Returns the application role name
+     * @return the string containing the role name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the application role level
+     * @return the application user level
+     */
+    public AppRoleLevel getLevel() {
+        return level;
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/AppRoleLevel.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/AppRoleLevel.java
new file mode 100644 (file)
index 0000000..aa6514c
--- /dev/null
@@ -0,0 +1,46 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.authorization;
+
+import java.io.Serializable;
+
+/**
+ * Represents the application user role levels
+ * This level has meaning only inside the application context
+ * In the controller space such a role will be seen as <code>APPUSER<code>
+ * as specified in {@link UserLevel}
+ */
+public enum AppRoleLevel implements Serializable {
+    APPADMIN(0, "App-Admin", "Application Administrator"), APPUSER(1,
+            "App-User", "Application User"), APPOPERATOR(2, "Network-Operator",
+            "Application Operator"), NOUSER(255, "Unknown User", "Unknown User");
+
+    private int userLevel;
+    private String level;
+    private String prettyLevel;
+
+    private AppRoleLevel(int userlevel, String level, String prettyLevel) {
+        this.userLevel = userlevel;
+        this.level = level;
+        this.prettyLevel = prettyLevel;
+    }
+
+    public int toNumber() {
+        return this.userLevel;
+    }
+
+    public String toString() {
+        return this.level;
+    }
+
+    public String toStringPretty() {
+        return this.prettyLevel;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/AuthResultEnum.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/AuthResultEnum.java
new file mode 100644 (file)
index 0000000..cbcc202
--- /dev/null
@@ -0,0 +1,52 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * Defines the enumerated values for possible results of an Authentication
+ * request made from a AAA client to a AAA server.
+ */
+
+package org.opendaylight.controller.sal.authorization;
+
+import java.io.Serializable;
+
+public enum AuthResultEnum implements Serializable {
+    AUTH_NONE("AUTH_NOT_ATTEMPTED"), AUTH_ACCEPT("AUTHENTICATION_ACCEPTED"), // request accepted
+    AUTH_REJECT("AUTHENTICATION_REJECTED"), // request rejected
+    AUTH_TIMEOUT("AUTHENTICATION_TIMEDOUT"), // request timeout
+    AUTH_USERNAME_EMPTY("AUTHENTICATION_USERNAME_EMPTY"), // user name is empty
+    AUTH_PASSWORD_EMPTY("AUTHENTICATION_PASSWORD_EMPTY"), // password is empty
+    AUTH_SECRET_EMPTY("AUTHENTICATION_SECRET_EMPTY"), // secret is empty
+    AUTH_COMM_ERROR("AUTHENTICATION_COMM_ERROR"), // communication channel problem
+    AUTH_INVALID_ADDR("AUTHENTICATION_INVALID_ADDR"), // invalid network address
+    AUTH_INVALID_PACKET("AUTHENTICATION_INVALID_PACKET"), // invalid packets or malformed attributes
+
+    /*
+     * Local AAA values
+     */
+    AUTH_ACCEPT_LOC("AUTHENTICATION_ACCEPTED"), // request accepted on local database
+    AUTH_REJECT_LOC("AUTHENTICATION_REJECTED"), // request rejected on local database
+    AUTH_INVALID_LOC_USER("INALID_LOCAL_USER"),
+
+    /*
+     * Authorization
+     */
+    AUTHOR_PASS("AUTHORIZATION_PASSED"), AUTHOR_FAIL("AUTHORIZATION_FAILED"), AUTHOR_ERROR(
+            "AUTHORIZATION_SERVER_ERROR");
+
+    private AuthResultEnum(String name) {
+        this.name = name;
+    }
+
+    private String name;
+
+    public String toString() {
+        return name;
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/IResourceAuthorization.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/IResourceAuthorization.java
new file mode 100644 (file)
index 0000000..1609674
--- /dev/null
@@ -0,0 +1,153 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.authorization;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Interface for applications which maintain an authorization
+ * database for their resources. Respective application web bundle
+ * and User Manager make use of this interface to retrieve
+ * authorization information at user or and role level
+ */
+public interface IResourceAuthorization {
+
+    /**
+     * Create a Role name for the application
+     *
+     * @param role     the role name
+     * @param userLevel        the user level in the application context
+     */
+    public void createRole(String role, AppRoleLevel userLevel);
+
+    /**
+     * Return the list of roles configured for the application
+     *
+     * @return the list of roles
+     */
+    public List<String> getRoles();
+
+    /**
+     * Returns the application role level for the specified role
+     * If the role is not known to this application <code>NOUSER<code>
+     * will be returned as specified in {@link AppRoleLevel}
+     *
+     * @param roleName the role name to query
+     * @return the application level of the given role in the application context as specified by {@link AppRoleLevel}
+     *                         if the role is not part of this application's roles, <code>NOUSER<code> is returned
+     */
+    public AppRoleLevel getApplicationRoleLevel(String roleName);
+
+    /**
+     * Returns whether the specified role is part of this application's roles
+     *
+     * @param roleName the role name to test
+     * @return true if the role belongs to this application, false otherwise
+     */
+    public boolean isApplicationRole(String roleName);
+
+    /**
+     * Create a resource group for application
+     *
+     * @param groupName the name for the resource group
+     * @param resources the list of resources for the group
+     */
+    public void createResourceGroup(String groupName, List<Object> resources);
+
+    /**
+     * Removes a resource group
+     *
+     * @param groupName the name of the group
+     */
+    public void removeResourceGroup(String groupName);
+
+    /**
+     * Returns the list of resource groups configured for the application
+     *
+     * @return the list of resource group names
+     */
+    public List<String> getResourceGroups();
+
+    /**
+     * Assign a resource group to a user group (role)
+     *
+     * @param groupName the object expressing the resource group name and the access privilege
+     * @param role the user group (role) name
+     */
+    public void assignResourceGroupToRole(String groupName,
+            Privilege privilege, String role);
+
+    /**
+     * Returns the list of resource groups the given Role is authorized to use
+     * The returning object expresses the resource group name and the access
+     * its privilege for the given user role
+     *
+     * @param role
+     * @return list of resources
+     */
+    public List<ResourceGroup> getAuthorizedGroups(String role);
+
+    /**
+     * Returns the list of resources contained in the given resource group
+     *
+     * @param groupName the resource group name
+     * @return
+     */
+    public List<Object> getResources(String groupName);
+
+    /**
+     * Returns the list of authorized resources for the given role
+     * For each resource only the highest privilege occurrence is returned
+     * @param role
+     * @return the list of Resource
+     */
+    public List<Resource> getAuthorizedResources(String role);
+
+    /*
+     * Per user name API
+     */
+    /**
+     * Returns the controller user role level the passed user name is associated with
+     *
+     * @param userName the user name
+     * @return the user role level as specified in {@link UserLevel}
+     */
+    public UserLevel getUserLevel(String userName);
+
+    /**
+     * Returns the application context user role level the passed user name is associated with
+     *
+     * @param userName the user name
+     * @return the user role level as specified in {@link AppRoleLevel}
+     */
+    public AppRoleLevel getUserApplicationLevel(String userName);
+
+    /**
+     * Returns the list of resources (resource + privilege) associated
+     * with the passed user name for this application context
+     * For each resource only the highest privilege occurrence is returned
+     *
+     * @param userName the user name
+     * @return the list of resources associated with this user name in this application context
+     */
+    public Set<Resource> getAllResourcesforUser(String userName);
+
+    /**
+     * Returns the highest privilege that the user has on the specified
+     * resource in this application context
+     *
+     * @param userName
+     * @param resource
+     * @return
+     */
+    public Privilege getResourcePrivilege(String userName, Object resource);
+
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/Privilege.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/Privilege.java
new file mode 100644 (file)
index 0000000..63babe7
--- /dev/null
@@ -0,0 +1,32 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.authorization;
+
+/**
+ * It represents the group/resource access privilege
+ */
+public enum Privilege {
+    NONE(""), // no privilege
+    READ("r"), // read only
+    USE("u"), // use
+    WRITE("w"); // modify
+
+    private String p;
+
+    private Privilege(String p) {
+        this.p = p;
+    }
+
+    @Override
+    public String toString() {
+        return p;
+    }
+
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/Resource.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/Resource.java
new file mode 100644 (file)
index 0000000..ef8744b
--- /dev/null
@@ -0,0 +1,53 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.authorization;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * It represents the elementary resource along with
+ * the access privilege associated to it
+ */
+public class Resource implements Serializable {
+    private static final long serialVersionUID = 1L;
+    Object resource; // the generic resource
+    Privilege privilege; // read/use/write privilege
+
+    public Resource(Object resource, Privilege privilege) {
+        this.resource = resource;
+        this.privilege = privilege;
+    }
+
+    public Object getResource() {
+        return resource;
+    }
+
+    public Privilege getPrivilege() {
+        return privilege;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "[" + resource + ", " + privilege.toString() + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/ResourceGroup.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/ResourceGroup.java
new file mode 100644 (file)
index 0000000..61e44dd
--- /dev/null
@@ -0,0 +1,63 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.authorization;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * Represents a group of resources along with the privilege associated to it
+ *
+ *
+ *
+ */
+public class ResourceGroup implements Serializable {
+    private static final long serialVersionUID = 1L;
+    private String groupName; // the resource group name
+    private Privilege privilege; // the privilege for this profile on the resource group
+
+    public ResourceGroup(String groupName, Privilege privilege) {
+        this.groupName = groupName;
+        this.privilege = privilege;
+    }
+
+    /**
+     * Returns the name for this resource group
+     * @return
+     */
+    public String getGroupName() {
+        return groupName;
+    }
+
+    /**
+     * Returns the privilege for this group on its resources
+     * @return
+     */
+    public Privilege getPrivilege() {
+        return privilege;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "[" + groupName + ", " + privilege.toString() + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/UserLevel.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/UserLevel.java
new file mode 100644 (file)
index 0000000..a2e1d1c
--- /dev/null
@@ -0,0 +1,46 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.authorization;
+
+import java.io.Serializable;
+
+/**
+ * Describes the user role level in the controller space
+ */
+public enum UserLevel implements Serializable {
+    SYSTEMADMIN(0, "System-Admin", "System Administrator"),    // can do everything
+    NETWORKADMIN(1, "Network-Admin", "Network Administrator"), // can do everything but setting a system admin user profile
+    NETWORKOPERATOR(2, "Network-Operator", "Network Operator"),        // can only see what is configured anywhere
+    CONTAINERUSER(4, "Container-User", "Container User"),              // container context user
+    APPUSER(5, "App-User", "Application User"),                                // application context user
+    NOUSER(255, "Not Authorized", "Not Authorized");
+
+    private int userLevel;
+    private String level;
+    private String prettyLevel;
+
+    private UserLevel(int userlevel, String level, String prettyLevel) {
+        this.userLevel = userlevel;
+        this.level = level;
+        this.prettyLevel = prettyLevel;
+    }
+
+    public int toNumber() {
+        return this.userLevel;
+    }
+
+    public String toString() {
+        return this.level;
+    }
+
+    public String toStringPretty() {
+        return this.prettyLevel;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Actions.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Actions.java
new file mode 100644 (file)
index 0000000..832c956
--- /dev/null
@@ -0,0 +1,99 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+
+/**
+ * @file   Actions.java
+ *
+ * @brief  Class representing actions
+ *
+ * Describes supported actions
+ */
+
+@XmlRootElement
+public class Actions extends Property {
+       private static final long serialVersionUID = 1L;
+    @XmlElement
+    private int actionsValue;
+    
+    public enum ActionType { 
+       OUTPUT_PORT_ACTION(1<<0),
+       VLAN_VID_ACTION(1<<1),
+       VLAN_PCP_ACTION(1<<2),
+       VLAN_STRIP_ACTION(1<<3),
+       DLSRC_ACTION(1<<4),
+       DLDST_ACTION(1<<5),
+       NWSRC_ACTION(1<<6),
+       NWDST_ACTION(1<<7),
+       NWTOS_ACTION(1<<8),
+       TPTSRC_ACTION(1<<9),
+       TPTDST_ACTION(1<<10),
+       ENQUEUE_ACTION(1<<11),
+       VENDOR_ACTION(0xffff);
+       private final int at;
+       ActionType(int val) {
+               this.at = val;
+       }
+       public int getValue() {
+               return at;
+       }
+    }
+    
+    public static final String ActionsPropName = "actions";
+    /**
+     * Construct a actions property
+     *
+     * @param actions the actions value
+     * @return Constructed object
+     */
+    public Actions(int actions) {
+        super(ActionsPropName);
+        this.actionsValue = actions;
+    }
+
+    /*
+     * Private constructor used for JAXB mapping
+     */
+    private Actions() {
+        super(ActionsPropName);
+        this.actionsValue = 0;
+    }
+
+    public Actions clone() {
+        return new Actions(this.actionsValue);
+    }
+    
+    public int getValue() {
+       return this.actionsValue;
+    }
+    
+    
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "Actions[" + ReflectionToStringBuilder.toString(this) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/AdvertisedBandwidth.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/AdvertisedBandwidth.java
new file mode 100644 (file)
index 0000000..b07dc34
--- /dev/null
@@ -0,0 +1,67 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * @file   AdvertisedBandWidth.java
+ *
+ * @brief  Class representing advertised bandwidth
+ *
+ * Describes Advertised Bandwidth which could be of a link or whatever could have
+ * bandwidth as description. It's intended in multiple of bits per
+ * seconds.
+ */
+@XmlRootElement
+@SuppressWarnings("serial")
+public class AdvertisedBandwidth extends Bandwidth {
+       public static final String AdvertisedBandwidthPropName = "advertisedBandwidth";
+       
+       public AdvertisedBandwidth(long value) {
+               super(AdvertisedBandwidthPropName);
+               this.bandwidthValue = value;
+       }
+       
+       /*
+     * Private constructor used for JAXB mapping
+     */
+    private AdvertisedBandwidth() {
+       super(AdvertisedBandwidthPropName);
+               this.bandwidthValue = 0;
+    }
+       
+       public AdvertisedBandwidth clone() {
+               return new AdvertisedBandwidth(this.bandwidthValue);  
+    }
+       
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }   
+    
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("AdvertisedBandWidth[");
+        sb.append(super.toString());
+        sb.append("]");
+        return sb.toString();
+    }
+
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Bandwidth.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Bandwidth.java
new file mode 100644 (file)
index 0000000..32f661c
--- /dev/null
@@ -0,0 +1,117 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * @file   BandWidth.java
+ *
+ * @brief  Class representing bandwidth
+ *
+ * Describe Bandwidth which could be of a link or whatever could have
+ * bandwidth as description. It's intended in multiple of bits per
+ * seconds.
+ */
+@XmlRootElement
+public class Bandwidth extends Property {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement
+    protected long bandwidthValue;
+
+    public static final long BWUNK = 0;
+    public static final long BW1Kbps = (long) Math.pow(10, 3);
+    public static final long BW1Mbps = (long) Math.pow(10, 6);
+    public static final long BW10Mbps = (long) Math.pow(10, 7);
+    public static final long BW100Mbps = (long) Math.pow(10, 8);
+    public static final long BW1Gbps = (long) Math.pow(10, 9);
+    public static final long BW10Gbps = (long) Math.pow(10, 10);
+    public static final long BW40Gbps = 4 * (long) Math.pow(10, 10);
+    public static final long BW100Gbps = (long) Math.pow(10, 11);
+    public static final long BW400Gbps = 4 * (long) Math.pow(10, 11);
+    public static final long BW1Tbps = (long) Math.pow(10, 12);
+    public static final long BW1Pbps = (long) Math.pow(10, 15);
+
+    public static final String BandwidthPropName = "bandwidth";
+
+    /*
+     * Private constructor used for JAXB mapping
+     */
+    private Bandwidth() {
+        super(BandwidthPropName);
+        this.bandwidthValue = BWUNK;
+        ;
+    }
+
+    public Bandwidth(long bandwidth) {
+        super(BandwidthPropName);
+        this.bandwidthValue = bandwidth;
+    }
+
+    public Bandwidth(int bandwidth) {
+        super(BandwidthPropName);
+        this.bandwidthValue = (long) bandwidth;
+    }
+
+    public Bandwidth(short bandwidth) {
+        super(BandwidthPropName);
+        this.bandwidthValue = (long) bandwidth;
+    }
+    
+    public Bandwidth(String name) {
+        super(name);
+    }
+
+    public Bandwidth clone() {
+        return new Bandwidth(this.bandwidthValue);
+    }
+
+    public long getValue() {
+        return this.bandwidthValue;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("BandWidth[");
+        if (this.bandwidthValue == 0) {
+            sb.append("UnKnown");
+        } else if (this.bandwidthValue < BW1Kbps) {
+            sb.append(this.bandwidthValue + "bps");
+        } else if (this.bandwidthValue < BW1Mbps) {
+            sb.append(Long.toString(this.bandwidthValue / BW1Kbps) + "Kbps");
+        } else if (this.bandwidthValue < BW1Gbps) {
+            sb.append(Long.toString(this.bandwidthValue / BW1Mbps) + "Mbps");
+        } else if (this.bandwidthValue < BW1Tbps) {
+            sb.append(Long.toString(this.bandwidthValue / BW1Gbps) + "Gbps");
+        } else if (this.bandwidthValue < BW1Pbps) {
+            sb.append(Long.toString(this.bandwidthValue / BW1Tbps) + "Tbps");
+        }
+
+        sb.append("]");
+        return sb.toString();
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Buffers.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Buffers.java
new file mode 100644 (file)
index 0000000..9324806
--- /dev/null
@@ -0,0 +1,75 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+
+/**
+ * @file   Buffers.java
+ *
+ * @brief  Class representing buffers
+ *
+ * Describes supported buffers (#packets)
+ */
+@XmlRootElement
+public class Buffers extends Property {
+       private static final long serialVersionUID = 1L;
+    @XmlElement
+    private int buffersValue;
+    
+    public static final String BuffersPropName = "buffers";
+    
+    /**
+     * Construct a Buffers property
+     *
+     * @param buffers the Buffers 
+     * @return Constructed object
+     */
+    public Buffers(int buffers) {
+        super(BuffersPropName);
+        this.buffersValue = buffers;
+    }
+
+    /*
+     * Private constructor used for JAXB mapping
+     */
+    private Buffers() {
+        super(BuffersPropName);
+        this.buffersValue = 0;
+    }
+
+    public Buffers clone() {
+        return new Buffers(this.buffersValue);
+    }
+
+    public int getValue() {
+        return this.buffersValue;
+    }
+    
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "Buffers[" + ReflectionToStringBuilder.toString(this) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Capabilities.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Capabilities.java
new file mode 100644 (file)
index 0000000..b239ed4
--- /dev/null
@@ -0,0 +1,92 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+
+/**
+ * @file   Capabilities.java
+ *
+ * @brief  Class representing capabilities
+ *
+ * Describes supported capabilities
+ */
+@XmlRootElement
+public class Capabilities extends Property {
+       private static final long serialVersionUID = 1L;
+    @XmlElement
+    private int capabilitiesValue;
+    
+    public enum CapabilitiesType { 
+       FLOW_STATS_CAPABILITY(1<<0),
+       TABLE_STATS_CAPABILITY(1<<1),
+       PORT_STATS_CAPABILITY(1<<2),
+       STP_CAPABILITY(1<<3),
+       RSVD_CAPABILITY(1<<4),
+       IP_REASSEM_CAPABILITY(1<<5),
+       QUEUE_STATS_CAPABILITY(1<<6),
+       ARP_MATCH_IP_CAPABILITY(1<<7);
+       private final int ct;
+       CapabilitiesType(int val) {
+               this.ct = val;
+       }
+       public int getValue() {
+               return ct;
+       }
+    }
+   
+    public static final String CapabilitiesPropName = "capabilities";
+    /**
+     * Construct a Capabilities property
+     *
+     * @param capabilities the Capabilities value
+     * @return Constructed object
+     */
+    public Capabilities(int capabilities) {
+        super(CapabilitiesPropName);
+        this.capabilitiesValue = capabilities;
+    }
+
+    /*
+     * Private constructor used for JAXB mapping
+     */
+    private Capabilities() {
+        super(CapabilitiesPropName);
+        this.capabilitiesValue = 0;
+    }
+
+    public Capabilities clone() {
+        return new Capabilities(this.capabilitiesValue);
+    }
+
+    public int getValue() {
+       return this.capabilitiesValue;
+    }
+    
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "Capabilities[" + ReflectionToStringBuilder.toString(this) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ComponentActivatorAbstractBase.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ComponentActivatorAbstractBase.java
new file mode 100644 (file)
index 0000000..d04e67b
--- /dev/null
@@ -0,0 +1,464 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+/**
+ * @file   ComponentActivatorAbstractBase.java
+ *
+ * @brief  Abstract class which need to be subclassed in order to
+ * track and register dependencies per-container
+ *
+ * Abstract class which need to be subclassed in order to
+ * track and register dependencies per-container
+ *
+ */
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentStateListener;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.ServiceDependency;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract class which need to be subclassed in order to track and
+ * register dependencies per-container
+ *
+ */
+abstract public class ComponentActivatorAbstractBase implements
+        BundleActivator, IContainerAware {
+    Logger logger = LoggerFactory
+            .getLogger(ComponentActivatorAbstractBase.class);
+    private ServiceRegistration containerAwareRegistration;
+    private DependencyManager dm;
+    private ConcurrentMap<ImmutablePair<String, Object>, Component> dbInstances = (ConcurrentMap<ImmutablePair<String, Object>, Component>) new ConcurrentHashMap<ImmutablePair<String, Object>, Component>();
+    private ConcurrentMap<Object, Component> dbGlobalInstances = (ConcurrentMap<Object, Component>) new ConcurrentHashMap<Object, Component>();
+
+    /**
+     * Abstract method that MUST be implemented by the derived class
+     * that wants to activate the Component bundle in a container. Here
+     * customization for the component are expected
+     */
+    abstract protected void init();
+
+    /**
+     * Abstract method that MUST be implemented by the derived class
+     * that wants to DE-activate the Component bundle in a container. Here
+     * customization for the component are expected
+     */
+    abstract protected void destroy();
+
+    /**
+     * Method which tells how many implementations are supported by
+     * the bundle. This way we can tune the number of components
+     * created.
+     *
+     *
+     * @return The list of implementations the bundle will support,
+     * this will be used to decide how many components need to be
+     * created per-container
+     */
+    protected Object[] getImplementations() {
+        return null;
+    }
+
+    /**
+     * Method which tells how many Global implementations are
+     * supported by the bundle. This way we can tune the number of
+     * components created. This components will be created ONLY at the
+     * time of bundle startup and will be destroyed only at time of
+     * bundle destruction, this is the major difference with the
+     * implementation retrieved via getImplementations where all of
+     * them are assumed to be in a container!
+     *
+     *
+     * @return The list of implementations the bundle will support,
+     * in Global version
+     */
+    protected Object[] getGlobalImplementations() {
+        return null;
+    }
+
+    /**
+     * Configure the dependency for a given instance inside a container
+     *
+     * @param c Component assigned for this instance, this will be
+     * what will be used for configuration
+     * @param imp implementation to be configured
+     * @param containerName container on which the configuration happens
+     */
+    protected void configureInstance(Component c, Object imp,
+            String containerName) {
+        // do nothing by default
+    }
+
+    /**
+     * Configure the dependency for a given instance Global
+     *
+     * @param c Component assigned for this instance, this will be
+     * what will be used for configuration
+     * @param imp implementation to be configured
+     * @param containerName container on which the configuration happens
+     */
+    protected void configureGlobalInstance(Component c, Object imp) {
+        // Do nothing by default
+    }
+
+    // Private class used to listen to state transition so we can
+    // implement the necessary logic to call "started" and "stopping"
+    // methods on the component. Right now the framework natively
+    // support only the call of:
+    // - "init": Called after dependency are satisfied
+    // - "start": Called after init but before services are registered
+    // - "stop": Called after services are unregistered but before the
+    // component is going to be destroyed
+    // - "destroy": Called to destroy the component.
+    // There is still a need for two notifications:
+    // - "started" method to be called after "start" and after the
+    // services has been registered in the OSGi service registry
+    // - "stopping" method to be called before "stop" method and
+    // before the services of the component are removed from OSGi
+    // service registry
+    class ListenerComponentStates implements ComponentStateListener {
+        @Override
+        public void starting(Component component) {
+            // do nothing
+        }
+
+        @Override
+        public void started(Component component) {
+            if (component == null) {
+                return;
+            }
+            component.invokeCallbackMethod(new Object[] { component
+                    .getService() }, "started", new Class[][] {
+                    { Component.class }, {} }, new Object[][] { { component },
+                    {} });
+        }
+
+        @Override
+        public void stopped(Component component) {
+            if (component == null) {
+                return;
+            }
+            component.invokeCallbackMethod(new Object[] { component
+                    .getService() }, "stopping", new Class[][] {
+                    { Component.class }, {} }, new Object[][] { { component },
+                    {} });
+        }
+
+        @Override
+        public void stopping(Component component) {
+            // do nothing
+        }
+    }
+
+    /**
+     * Method of IContainerAware called when a new container is available
+     *
+     * @param containerName Container being created
+     */
+    @Override
+    public void containerCreate(String containerName) {
+        try {
+            Object[] imps = getImplementations();
+            logger.trace("Creating instance " + containerName);
+            if (imps != null) {
+                for (int i = 0; i < imps.length; i++) {
+                    ImmutablePair<String, Object> key = new ImmutablePair<String, Object>(
+                            containerName, imps[i]);
+                    Component c = this.dbInstances.get(key);
+                    if (c == null) {
+                        c = this.dm.createComponent();
+                        c.addStateListener(new ListenerComponentStates());
+                        // Now let the derived class to configure the
+                        // dependencies it wants
+                        configureInstance(c, imps[i], containerName);
+                        // Set the implementation so the component can manage
+                        // its lifecycle
+                        if (c.getService() == null) {
+                            logger
+                                    .trace("Setting implementation to:"
+                                            + imps[i]);
+                            c.setImplementation(imps[i]);
+                        }
+
+                        //Set the service properties to include the containerName
+                        //in the service, that is fundamental for supporting
+                        //multiple services just distinguished via a container
+                        Dictionary<String, String> serviceProps = c
+                                .getServiceProperties();
+                        if (serviceProps != null) {
+                            logger.trace("Adding new property for container");
+                            serviceProps.put("containerName", containerName);
+                        } else {
+                            logger
+                                    .trace("Create a new properties for the service");
+                            serviceProps = new Hashtable<String, String>();
+                            serviceProps.put("containerName", containerName);
+                        }
+                        c.setServiceProperties(serviceProps);
+
+                        // Now add the component to the dependency Manager
+                        // which will immediately start tracking the dependencies
+                        this.dm.add(c);
+
+                        //Now lets keep track in our shadow database of the
+                        //association
+                        this.dbInstances.put(key, c);
+                    } else {
+                        logger
+                                .error("I have been asked again to create an instance "
+                                        + "on: "
+                                        + containerName
+                                        + "for object: "
+                                        + imps[i]
+                                        + "when i already have it!!");
+                    }
+                }
+            }
+        } catch (Exception ex) {
+            logger
+                    .error("During containerDestroy invocation caught exception: "
+                            + ex
+                            + "\nStacktrace:"
+                            + stackToString(ex.getStackTrace()));
+        }
+    }
+
+    @Override
+    public void containerDestroy(String containerName) {
+        try {
+            Object[] imps = getImplementations();
+            logger.trace("Destroying instance " + containerName);
+            if (imps != null) {
+                for (int i = 0; i < imps.length; i++) {
+                    ImmutablePair<String, Object> key = new ImmutablePair<String, Object>(
+                            containerName, imps[i]);
+                    Component c = this.dbInstances.get(key);
+                    if (c != null) {
+                        // Now remove the component from dependency manager,
+                        // which will implicitely stop it first
+                        this.dm.remove(c);
+                    } else {
+                        logger
+                                .error("I have been asked again to remove an instance "
+                                        + "on: "
+                                        + containerName
+                                        + "for object: "
+                                        + imps[i]
+                                        + "when i already have cleared it!!");
+                    }
+
+                    //Now lets remove the association from our shadow
+                    //database so the component can be recycled, this is done
+                    //unconditionally in case of spurious conditions
+                    this.dbInstances.remove(key);
+                }
+            }
+        } catch (Exception ex) {
+            logger
+                    .error("During containerDestroy invocation caught exception: "
+                            + ex
+                            + "\nStacktrace:"
+                            + stackToString(ex.getStackTrace()));
+        }
+    }
+
+    private String stackToString(StackTraceElement[] stack) {
+        if (stack == null) {
+            return "<EmptyStack>";
+        }
+        StringBuffer buffer = new StringBuffer();
+
+        for (int i = 0; i < stack.length; i++) {
+            buffer.append("\n\t" + stack[i].toString());
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Method called by the OSGi framework when the OSGi bundle
+     * starts. The functionality we want to perform here are:
+     *
+     * 1) Register with the OSGi framework, that we are a provider of
+     * IContainerAware service and so in case of startup of a container we
+     * want to be called
+     *
+     * 2) Create data structures that allow to keep track of all the
+     * instances created per-container given the derived class of
+     * ComponentActivatorAbstractBase will act as a Factory manager
+     *
+     * @param context OSGi bundle context to interact with OSGi framework
+     */
+    @Override
+    public void start(BundleContext context) {
+        try {
+            this.dm = new DependencyManager(context);
+
+            logger.trace("Activating");
+
+            // Now create Global components
+            Object[] imps = getGlobalImplementations();
+            if (imps != null) {
+                for (int i = 0; i < imps.length; i++) {
+                    Object key = imps[i];
+                    Component c = this.dbGlobalInstances.get(key);
+                    if (c == null) {
+                        try {
+                            c = this.dm.createComponent();
+                            c.addStateListener(new ListenerComponentStates());
+                            // Now let the derived class to configure the
+                            // dependencies it wants
+                            configureGlobalInstance(c, imps[i]);
+                            // Set the implementation so the component
+                            // can manage its lifesycle
+                            if (c.getService() == null) {
+                                logger.trace("Setting implementation to:"
+                                        + imps[i]);
+                                c.setImplementation(imps[i]);
+                            }
+
+                            // Now add the component to the dependency
+                            // Manager which will immediately start
+                            // tracking the dependencies
+                            this.dm.add(c);
+                        } catch (Exception nex) {
+                            logger.error("During creation of a Global "
+                                    + "instance caught exception: " + nex
+                                    + "\nStacktrace:"
+                                    + stackToString(nex.getStackTrace()));
+                        }
+
+                        //Now lets keep track in our shadow database of the
+                        //association
+                        if (c != null)
+                            this.dbGlobalInstances.put(key, c);
+                    } else {
+                        logger.error("I have been asked again to create an "
+                                + "instance " + " Global for object: "
+                                + imps[i] + "when i already have it!!");
+                    }
+                }
+            }
+
+            // Register with OSGi the provider for the service IContainerAware
+            this.containerAwareRegistration = context.registerService(
+                    IContainerAware.class.getName(), this, null);
+
+            // Now call the derived class init function
+            this.init();
+
+            logger.trace("Activation DONE!");
+        } catch (Exception ex) {
+            logger.error("During Activator start caught exception: " + ex
+                    + "\nStacktrace:" + stackToString(ex.getStackTrace()));
+        }
+    }
+
+    /**
+     * Method called by the OSGi framework when the OSGi bundle
+     * stops. The functionality we want to perform here are:
+     *
+     * 1) Force all the instances to stop and do cleanup and
+     * unreference them so garbage collection can clean them up
+     *
+     * NOTE: UN-Register with the OSGi framework,is not needed because
+     * the framework will automatically do it
+     *
+     * @param context OSGi bundle context to interact with OSGi framework
+     */
+    @Override
+    public void stop(BundleContext context) {
+        try {
+            logger.trace("DE-Activating");
+
+            // Now call the derived class destroy function
+            this.destroy();
+
+            // Now remove all the components tracked for container components
+            for (ImmutablePair<String, Object> key : this.dbInstances.keySet()) {
+                try {
+                    Component c = this.dbInstances.get(key);
+                    if (c != null) {
+                        logger.trace("Remove component on container:"
+                                + key.getLeft() + " Object:" + key.getRight());
+                        this.dm.remove(c);
+                    }
+                } catch (Exception nex) {
+                    logger.error("During removal of a container component "
+                            + "instance caught exception: " + nex
+                            + "\nStacktrace:"
+                            + stackToString(nex.getStackTrace()));
+                }
+                this.dbInstances.remove(key);
+            }
+
+            // Now remove all the components tracked for Global Components
+            for (Object key : this.dbGlobalInstances.keySet()) {
+                try {
+                    Component c = this.dbGlobalInstances.get(key);
+                    if (c != null) {
+                        logger.trace("Remove component for Object:" + key);
+                        this.dm.remove(c);
+                    }
+                } catch (Exception nex) {
+                    logger.error("During removal of a Global "
+                            + "instance caught exception: " + nex
+                            + "\nStacktrace:"
+                            + stackToString(nex.getStackTrace()));
+                }
+
+                this.dbGlobalInstances.remove(key);
+            }
+
+            // Detach Dependency Manager
+            this.dm = null;
+
+            logger.trace("Deactivation DONE!");
+        } catch (Exception ex) {
+            logger.error("During Activator stop caught exception: " + ex
+                    + "\nStacktrace:" + stackToString(ex.getStackTrace()));
+        }
+    }
+
+    /**
+     * Return a ServiceDependency customized ad hoc for slicing, this
+     * essentially the same org.apache.felix.dm.ServiceDependency just
+     * with some filters pre-set
+     *
+     * @param containerName containerName for which we want to create the dependency
+     *
+     * @return a ServiceDependency
+     */
+    protected ServiceDependency createContainerServiceDependency(
+            String containerName) {
+        return (new ContainerServiceDependency(this.dm, containerName));
+    }
+
+    /**
+     * Return a ServiceDependency as provided by Dependency Manager as it's
+     *
+     *
+     * @return a ServiceDependency
+     */
+    protected ServiceDependency createServiceDependency() {
+        return this.dm.createServiceDependency();
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Config.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Config.java
new file mode 100644 (file)
index 0000000..c585aa2
--- /dev/null
@@ -0,0 +1,70 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * The class represents Admin Config status
+ *
+ *
+ */
+@XmlRootElement
+@SuppressWarnings("serial")
+public class Config extends Property {
+    @XmlElement
+    private short configValue;
+
+    public static final short ADMIN_DOWN = 0;
+    public static final short ADMIN_UP = 1;
+    public static final short ADMIN_UNDEF = 0x7fff;
+    public static final String ConfigPropName = "config";
+
+    /*
+     * Private constructor used for JAXB mapping
+     */
+    private Config() {
+        super(ConfigPropName);
+        this.configValue = ADMIN_UNDEF;
+    }
+
+    public Config(short config) {
+        super(ConfigPropName);
+        this.configValue = config;
+    }
+
+    public Config clone() {
+        return new Config(this.configValue);
+    }
+
+    public short getValue() {
+        return this.configValue;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "Config[" + ReflectionToStringBuilder.toString(this) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ConstructionException.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ConstructionException.java
new file mode 100644 (file)
index 0000000..30033a2
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   ConstructionException.java
+ *
+ *
+ * @brief  Describe an exception that is raised when a construction
+ * for a Node/NodeConnector/Edge or any of the SAL basic object fails
+ * because input passed are not valid or compatible
+ *
+ *
+ */
+package org.opendaylight.controller.sal.core;
+
+import java.lang.Exception;
+
+public class ConstructionException extends Exception {
+    private static final long serialVersionUID = 1L;
+
+    public ConstructionException(String message) {
+        super(message);
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ContainerFlow.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ContainerFlow.java
new file mode 100644 (file)
index 0000000..acb3e19
--- /dev/null
@@ -0,0 +1,123 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.opendaylight.controller.sal.action.Action;
+import org.opendaylight.controller.sal.action.SetDlType;
+import org.opendaylight.controller.sal.action.SetNwDst;
+import org.opendaylight.controller.sal.action.SetNwSrc;
+import org.opendaylight.controller.sal.action.SetTpDst;
+import org.opendaylight.controller.sal.action.SetTpSrc;
+import org.opendaylight.controller.sal.flowprogrammer.Flow;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
+
+/**
+ * Express a container flow
+ *
+ *
+ *
+ */
+public class ContainerFlow implements Serializable {
+    private static final long serialVersionUID = 1L;
+    private Match match;
+
+    public ContainerFlow(Match match) {
+        this.match = match;
+    }
+
+    /**
+     * Returns a copy of the Match defined by this Container Flow
+     *
+     * @return Match
+     */
+    public Match getMatch() {
+        return match.clone();
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "Container Flow [" + match.toString() + "]";
+    }
+
+    /**
+     * Returns whether the specified flow is allowed
+     *
+     * @return true if the flow is allowed, false otherwise
+     */
+    public boolean allowsFlow(Flow flow) {
+        Match target = flow.getMatch();
+
+        // Check if flow's match is allowed
+        if (!this.allowsMatch(target)) {
+            return false;
+        }
+
+        // Now check if the flow's actions are not allowed
+        // Create a Match which summarizes the list of actions
+        if (flow.getActions() == null) {
+            return true;
+        }
+        Match actionMatch = new Match();
+        for (Action action : flow.getActions()) {
+            switch (action.getType()) {
+            case SET_DL_TYPE:
+                actionMatch.setField(MatchType.DL_TYPE,
+                        ((Integer) ((SetDlType) action).getDlType())
+                                .shortValue());
+                break;
+            case SET_NW_SRC:
+                actionMatch.setField(MatchType.NW_SRC, ((SetNwSrc) action)
+                        .getAddress());
+                break;
+            case SET_NW_DST:
+                actionMatch.setField(MatchType.NW_DST, ((SetNwDst) action)
+                        .getAddress());
+                break;
+            case SET_TP_SRC:
+                actionMatch.setField(MatchType.TP_SRC,
+                        ((Integer) ((SetTpSrc) action).getPort()).shortValue());
+                break;
+            case SET_TP_DST:
+                actionMatch.setField(MatchType.TP_DST,
+                        ((Integer) ((SetTpDst) action).getPort()).shortValue());
+                break;
+            default:
+                // This action cannot conflict
+            }
+        }
+
+        return this.allowsMatch(actionMatch);
+    }
+
+    /**
+     * Returns whether the specified match is allowed
+     *
+     * @param match    the match to test
+     * @return true if the match is allowed, false otherwise
+     */
+    public boolean allowsMatch(Match target) {
+        return !target.conflictWithFilter(this.match);
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ContainerServiceDependency.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ContainerServiceDependency.java
new file mode 100644 (file)
index 0000000..29e9dfa
--- /dev/null
@@ -0,0 +1,247 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+/**
+ * @file   ContainerServiceDependency.java
+ *
+ * @brief  Class representing a ServiceDependency on a container
+ *
+ * Class representing a ServiceDependency on a container
+ */
+
+import java.util.Dictionary;
+import org.osgi.framework.ServiceReference;
+import org.apache.felix.dm.ServiceDependency;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyActivation;
+import org.apache.felix.dm.DependencyService;
+
+/**
+ * Class representing a ServiceDependency on a container
+ *
+ */
+public class ContainerServiceDependency implements ServiceDependency,
+        DependencyActivation {
+    private ServiceDependency m_dep;
+    private String containerName;
+
+    public ContainerServiceDependency(DependencyManager manager,
+            String containerName) {
+        this.m_dep = manager.createServiceDependency();
+        this.containerName = containerName;
+    }
+
+    private ContainerServiceDependency(ServiceDependency explicitDependency,
+            String containerName) {
+        this.m_dep = explicitDependency;
+        this.containerName = containerName;
+    }
+
+    @Override
+    public ServiceDependency setService(Class serviceName) {
+        this.m_dep.setService(serviceName, "(containerName="
+                + this.containerName + ")");
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setService(Class serviceName, String serviceFilter) {
+        this.m_dep.setService(serviceName, "(&(containerName="
+                + this.containerName + ")" + serviceFilter + ")");
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setService(String serviceFilter) {
+        this.m_dep.setService("(&(containerName=" + this.containerName + ")"
+                + serviceFilter + ")");
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setService(Class serviceName,
+            ServiceReference serviceReference) {
+        this.m_dep.setService(serviceName, serviceReference);
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setDefaultImplementation(Object implementation) {
+        this.m_dep.setDefaultImplementation(implementation);
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setRequired(boolean required) {
+        this.m_dep.setRequired(required);
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setAutoConfig(boolean autoConfig) {
+        this.m_dep.setAutoConfig(autoConfig);
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setAutoConfig(String instanceName) {
+        this.m_dep.setAutoConfig(instanceName);
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setCallbacks(String added, String removed) {
+        this.m_dep.setCallbacks(added, removed);
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setCallbacks(String added, String changed,
+            String removed) {
+        this.m_dep.setCallbacks(added, changed, removed);
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setCallbacks(String added, String changed,
+            String removed, String swapped) {
+        this.m_dep.setCallbacks(added, changed, removed, swapped);
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setCallbacks(Object instance, String added,
+            String removed) {
+        this.m_dep.setCallbacks(instance, added, removed);
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setCallbacks(Object instance, String added,
+            String changed, String removed) {
+        this.m_dep.setCallbacks(instance, added, changed, removed);
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setCallbacks(Object instance, String added,
+            String changed, String removed, String swapped) {
+        this.m_dep.setCallbacks(instance, added, changed, removed, swapped);
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setPropagate(boolean propagate) {
+        this.m_dep.setPropagate(propagate);
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setPropagate(Object instance, String method) {
+        this.m_dep.setPropagate(instance, method);
+        return this;
+    }
+
+    @Override
+    public ServiceDependency setInstanceBound(boolean isInstanceBound) {
+        this.m_dep.setInstanceBound(isInstanceBound);
+        return this;
+    }
+
+    @Override
+    public Dependency createCopy() {
+        return new ContainerServiceDependency((ServiceDependency) this.m_dep
+                .createCopy(), this.containerName);
+    }
+
+    @Override
+    public Dictionary getProperties() {
+        return this.m_dep.getProperties();
+    }
+
+    @Override
+    public boolean isPropagated() {
+        return this.m_dep.isPropagated();
+    }
+
+    @Override
+    public boolean isRequired() {
+        return this.m_dep.isRequired();
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return this.m_dep.isAvailable();
+    }
+
+    @Override
+    public boolean isInstanceBound() {
+        return this.m_dep.isInstanceBound();
+    }
+
+    @Override
+    public boolean isAutoConfig() {
+        return this.m_dep.isAutoConfig();
+    }
+
+    @Override
+    public Class getAutoConfigType() {
+        return this.m_dep.getAutoConfigType();
+    }
+
+    @Override
+    public Object getAutoConfigInstance() {
+        return this.m_dep.getAutoConfigInstance();
+    }
+
+    @Override
+    public String getAutoConfigName() {
+        return this.m_dep.getAutoConfigName();
+    }
+
+    @Override
+    public void invokeAdded(DependencyService service) {
+        this.m_dep.invokeAdded(service);
+    }
+
+    @Override
+    public void invokeRemoved(DependencyService service) {
+        this.m_dep.invokeRemoved(service);
+    }
+
+    @Override
+    public String getName() {
+        return this.m_dep.getName();
+    }
+
+    @Override
+    public String getType() {
+        return this.m_dep.getType();
+    }
+
+    @Override
+    public int getState() {
+        return this.m_dep.getState();
+    }
+
+    @Override
+    public void start(DependencyService service) {
+        DependencyActivation a = (DependencyActivation) this.m_dep;
+        a.start(service);
+    }
+
+    @Override
+    public void stop(DependencyService service) {
+        DependencyActivation a = (DependencyActivation) this.m_dep;
+        a.stop(service);
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Edge.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Edge.java
new file mode 100644 (file)
index 0000000..162a4d4
--- /dev/null
@@ -0,0 +1,142 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   Edge.java
+ *
+ * @brief  Describe an edge in network made of multiple SDN technologies
+ *
+ * Class that describe an Edge connecting two NodeConnector, the edge
+ * is directed because there is the head and the tail concept which
+ * implies a direction.
+ */
+package org.opendaylight.controller.sal.core;
+
+import java.io.Serializable;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ *
+ * Class that describe an Edge connecting two NodeConnector, the edge
+ * is directed because there is the tail and the head concept which
+ * implies a direction.
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class Edge implements Serializable {
+    private static final long serialVersionUID = 1L;
+    @XmlElement
+    private NodeConnector tailNodeConnector;
+    @XmlElement
+    private NodeConnector headNodeConnector;
+
+    /**
+     * Private constructor used for JAXB mapping
+     */
+    private Edge() {
+        this.tailNodeConnector = null;
+        this.headNodeConnector = null;
+    }
+
+    /**
+     * Construct the Edge
+     *
+     * @param tailNodeConnector Tail Node output connector
+     * @param headNodeConnector Head Node input connector
+     *
+     */
+    public Edge(NodeConnector tailNodeConnector, NodeConnector headNodeConnector)
+            throws ConstructionException {
+        if (tailNodeConnector == null || headNodeConnector == null) {
+            throw new ConstructionException(
+                    "Null tail or head NodeConnector supplied");
+        } else {
+            this.tailNodeConnector = tailNodeConnector;
+            this.headNodeConnector = headNodeConnector;
+        }
+    }
+
+    /**
+     * Copy Construct the Edge
+     *
+     * @param src Edge to copy from
+     *
+     */
+    public Edge(Edge src) throws ConstructionException {
+        if (src != null) {
+            this.tailNodeConnector = new NodeConnector(src
+                    .getTailNodeConnector());
+            this.headNodeConnector = new NodeConnector(src
+                    .getHeadNodeConnector());
+        } else {
+            throw new ConstructionException("src supplied was null");
+        }
+    }
+
+    /**
+     * getter of edge
+     *
+     *
+     * @return tail NodeConnector of the edge
+     */
+    public NodeConnector getTailNodeConnector() {
+        return tailNodeConnector;
+    }
+
+    /**
+     * setter for edge
+     *
+     * @param tailNodeConnector NodeConnector to set the tail
+     */
+    public void setTailNodeConnector(NodeConnector tailNodeConnector) {
+        this.tailNodeConnector = tailNodeConnector;
+    }
+
+    /**
+     * getter of edge
+     *
+     *
+     * @return head NodeConnector of the edge
+     */
+    public NodeConnector getHeadNodeConnector() {
+        return headNodeConnector;
+    }
+
+    /**
+     * setter for edge
+     *
+     * @param headNodeConnector NodeConnector to set the head
+     */
+    public void setHeadNodeConnector(NodeConnector headNodeConnector) {
+        this.headNodeConnector = headNodeConnector;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "(" + this.tailNodeConnector + "->" + this.headNodeConnector
+                + ")";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Host.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Host.java
new file mode 100644 (file)
index 0000000..f549086
--- /dev/null
@@ -0,0 +1,108 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.opendaylight.controller.sal.packet.address.DataLinkAddress;
+
+@XmlRootElement(name="host")
+@XmlAccessorType(XmlAccessType.NONE)
+public class Host implements Serializable {
+    private static final long serialVersionUID = 1L;
+    @XmlElement
+    private DataLinkAddress dataLayerAddress;
+    private InetAddress networkAddress;
+
+    public Host() {
+
+    }
+
+    /**
+     * Create an Host representation from the combination Data Link
+     * layer/Network layer address, both are needed to construct the
+     * object. Fake value can also be provided in case are not
+     * existent.
+     *
+     * @param dataLayerAddress Data Link Address for the host
+     * @param networkAddress Network Address for the host
+     *
+     * @return the constructed object
+     */
+    public Host(DataLinkAddress dataLayerAddress, InetAddress networkAddress)
+            throws ConstructionException {
+        if (dataLayerAddress == null) {
+            throw new ConstructionException("Passed null datalink address");
+        }
+        if (networkAddress == null) {
+            throw new ConstructionException("Passed null network address");
+        }
+        this.dataLayerAddress = dataLayerAddress;
+        this.networkAddress = networkAddress;
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param h Host to copy values from
+     *
+     * @return constructed copy
+     */
+    public Host(Host h) throws ConstructionException {
+        if (h == null) {
+            throw new ConstructionException("Passed null host");
+        }
+        this.dataLayerAddress = h.getDataLayerAddress();
+        this.networkAddress = h.getNetworkAddress();
+    }
+
+    /**
+     * @return the dataLayerAddress
+     */
+    public DataLinkAddress getDataLayerAddress() {
+        return this.dataLayerAddress;
+    }
+
+    /**
+     * @return the networkAddress
+     */
+    public InetAddress getNetworkAddress() {
+        return networkAddress;
+    }
+
+    @XmlElement(name = "networkAddress")
+    public String getNetworkAddressAsString() {
+        return networkAddress.getHostAddress();
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "Host[" + ReflectionToStringBuilder.toString(this) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/IContainer.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/IContainer.java
new file mode 100644 (file)
index 0000000..5aeb5c8
--- /dev/null
@@ -0,0 +1,67 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   IContainer.java
+ *
+ * @brief  Interface used to retrieve the status of a given Container
+ *
+ *
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * Interface used to retrieve the status of a given Container
+ */
+public interface IContainer {
+    /**
+     * Returns the Name of the container described
+     *
+     * @return the container Name
+     */
+    public String getName();
+
+    /**
+     * The list of container flows associated with a container
+     *
+     * @return The list of FlowSpecs associated with the container
+     */
+    public List<ContainerFlow> getContainerFlows();
+
+    /**
+     * Return the tag on which a Node is expected to receive traffic
+     * for a given container.
+     *
+     * @param n The node for which we want to get the Tag
+     *
+     * @return the tag on which we expect to receive traffic on a
+     * given Node for a given container
+     */
+    public short getTag(Node n);
+
+    /**
+     * Return an array of all the NodeConnectors that are part of the
+     * container
+     *
+     * @return The array of nodeConnectors part of the container
+     */
+    public Set<NodeConnector> getNodeConnectors();
+
+    /**
+     * Return an array of all the Nodes that are part of a container
+     *
+     * @return The array of Nodes that are part of the container
+     */
+    public Set<Node> getNodes();
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/IContainerAware.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/IContainerAware.java
new file mode 100644 (file)
index 0000000..008ec59
--- /dev/null
@@ -0,0 +1,35 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+/**
+ * @file   IContainerAware.java
+ *
+ * @brief  Define the interface to be called when the Container is being
+ * created/destroyed
+ *
+ *
+ */
+
+public interface IContainerAware {
+    /**
+     * Method invoked to signal that a container is being created
+     *
+     * @param containerName Container being created
+     */
+    public void containerCreate(String containerName);
+
+    /**
+     * Method invoked to signal that a container is being destroyed
+     *
+     * @param containerName Container being destroyed
+     */
+    public void containerDestroy(String containerName);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/IContainerListener.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/IContainerListener.java
new file mode 100644 (file)
index 0000000..8ba62e2
--- /dev/null
@@ -0,0 +1,79 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   IContainerListener.java
+ *
+ * @brief  Set of methods needed to listen to changes in the Container
+ * configuration
+ *
+ * Set of methods needed to listen to changes in the Container
+ * configuration
+ *
+ *
+ */
+package org.opendaylight.controller.sal.core;
+
+/**
+ *
+ * Interface used to retrieve the status of a given Container
+ */
+public interface IContainerListener {
+    /**
+     * Called to notify a change in the tag assigned to a switch
+     *
+     * @param containerName container for which the update has been raised
+     * @param n Node of the tag under notification
+     * @param oldTag previous version of the tag, this differ from the
+     * newTag only if the UpdateType is a modify
+     * @param newTag new value for the tag, different from oldTag only
+     * in case of modify operation
+     * @param t type of update
+     */
+    public void tagUpdated(String containerName, Node n, short oldTag,
+            short newTag, UpdateType t);
+
+    /**
+     * Notification raised when the container flow layout changes
+     *
+     * @param containerName container for which the update has been raised
+     * @param previousFlow previous value of the container flow under
+     * update, differs from the currentFlow only and only if it's an
+     * update operation
+     * @param currentFlow current version of the container flow differs from
+     * the previousFlow only in case of update
+     * @param t type of update
+     */
+    public void containerFlowUpdated(String containerName,
+            ContainerFlow previousFlow, ContainerFlow currentFlow, UpdateType t);
+
+    /**
+     * Notification raised when a NodeConnector is added or removed in
+     * the container.
+     *
+     * @param containerName container for which the update has been raised
+     * @param p NodeConnector being updated
+     * @param t type of modification, but among the types the modify
+     * operation is not expected to be raised because the
+     * nodeConnectors are anyway immutable so this is only used to
+     * add/delete
+     */
+    public void nodeConnectorUpdated(String containerName, NodeConnector p,
+            UpdateType t);
+
+    /**
+     * Notification raised when the container mode has changed
+     * This notification is needed for some bundle in the default container
+     * to cleanup some HW state when switching from non-slicing to
+     * slicing case and vice-versa
+     *
+     * @param t  ADDED when first container is created, REMOVED when last container is removed
+     */
+    public void containerModeUpdated(UpdateType t);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Latency.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Latency.java
new file mode 100644 (file)
index 0000000..a7fd580
--- /dev/null
@@ -0,0 +1,105 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * @file   Latency.java
+ *
+ * @brief  Class representing Latency
+ *
+ * Describe a latency in picoseconds or multiple of its.
+ */
+@XmlRootElement
+public class Latency extends Property {
+    private static final long serialVersionUID = 1L;
+    private long latency;
+
+    public static final long LATENCYUNK = 0;
+    public static final long LATENCY1ns = (long) Math.pow(10, 3);
+    public static final long LATENCY10ns = (long) Math.pow(10, 4);
+    public static final long LATENCY100ns = (long) Math.pow(10, 5);
+    public static final long LATENCY1us = (long) Math.pow(10, 6);
+    public static final long LATENCY10us = (long) Math.pow(10, 7);
+    public static final long LATENCY100us = (long) Math.pow(10, 8);
+    public static final long LATENCY1ms = (long) Math.pow(10, 9);
+    public static final long LATENCY1s = (long) Math.pow(10, 12);
+
+    public static final String LatencyPropName = "latency";
+
+    /*
+     * Private constructor used for JAXB mapping
+     */
+    private Latency() {
+        super(LatencyPropName);
+        this.latency = LATENCYUNK;
+    }
+
+    public Latency(long latency) {
+        super(LatencyPropName);
+        this.latency = latency;
+    }
+
+    public Latency(int latency) {
+        super(LatencyPropName);
+        this.latency = (long) latency;
+    }
+
+    public Latency(short latency) {
+        super(LatencyPropName);
+        this.latency = (long) latency;
+    }
+
+    public Latency clone() {
+        return new Latency(this.latency);
+    }
+
+    public long getValue() {
+        return this.latency;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("Latency[");
+        if (this.latency == 0) {
+            sb.append("UnKnown");
+        } else if (this.latency < LATENCY1ns) {
+            sb.append(this.latency + "psec");
+        } else if (this.latency < LATENCY1us) {
+            sb.append(Long.toString(this.latency / LATENCY1ns) + "nsec");
+        } else if (this.latency < LATENCY1ms) {
+            sb.append(Long.toString(this.latency / LATENCY1us) + "usec");
+        } else if (this.latency < LATENCY1s) {
+            sb.append(Long.toString(this.latency / LATENCY1ms) + "msec");
+        }
+
+        sb.append("]");
+        return sb.toString();
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/MacAddress.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/MacAddress.java
new file mode 100644 (file)
index 0000000..2bfeb46
--- /dev/null
@@ -0,0 +1,94 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+
+/**
+ * The class contains the controller MAC address and node MAC address.
+ *
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class MacAddress extends Property {
+    private static final long serialVersionUID = 1L;
+    @XmlElement
+    private byte[] controllerMacAddress;
+    @XmlElement
+    private byte[] nodeMacAddress;
+    public static final String MacPropName = "macAddress";
+
+    /*
+     * Private constructor used for JAXB mapping
+     */
+    private MacAddress() {
+        super(MacPropName);
+        this.controllerMacAddress = null;
+        this.nodeMacAddress = null;
+    }
+
+       /**
+        * Constructor to create DatalinkAddress property which contains the
+        * controller MAC address and node MAC address. The property will be
+        * attached to a {@link org.opendaylight.controller.sal.core.Node}.
+        * 
+        * @param controllerMacAddress Data Link Address for the controller
+        * @param nodeMacAddress Data Link Address for the node
+        * 
+        * @return the constructed object
+        */
+    public MacAddress(byte[] controllerMacAddress, byte[] nodeMacAddress) {
+        super(MacPropName);
+       
+        this.controllerMacAddress = controllerMacAddress;
+        this.nodeMacAddress = nodeMacAddress;
+    }
+
+    /**
+     * @return the controller MAC address
+     */
+    public byte[] getControllerMacAddress() {
+        return this.controllerMacAddress;
+    }
+
+    /**
+     * @return the node MAC address
+     */
+    public byte[] getNodeMacAddress() {
+        return this.nodeMacAddress;
+    }
+
+    public MacAddress clone() {
+       return new MacAddress(this.controllerMacAddress, this.nodeMacAddress);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "MacAddress[" + ReflectionToStringBuilder.toString(this) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Name.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Name.java
new file mode 100644 (file)
index 0000000..74617c7
--- /dev/null
@@ -0,0 +1,66 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * The class represents the Name property of an element.
+ *
+ *
+ */
+@XmlRootElement
+@SuppressWarnings("serial")
+public class Name extends Property {
+    @XmlElement
+    private String nameValue;
+    public static final String NamePropName = "name";
+
+    /*
+     * Private constructor used for JAXB mapping
+     */
+    private Name() {
+        super(NamePropName);
+        this.nameValue = null;
+    }
+
+    public Name(String name) {
+        super(NamePropName);
+        this.nameValue = name;
+    }
+
+    public Name clone() {
+        return new Name(this.nameValue);
+    }
+
+    public String getValue() {
+        return this.nameValue;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "Name[" + ReflectionToStringBuilder.toString(this) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Node.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Node.java
new file mode 100644 (file)
index 0000000..b199e5c
--- /dev/null
@@ -0,0 +1,439 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   Node.java
+ *
+ * @brief  Describe a generic network element in multiple SDNs technologies
+ *
+ * Describe a generic network element in multiple SDNs technologies. A
+ * Node is identified by the pair (NodeType, NodeID), the nodetype are
+ * needed in order to further specify the nodeID
+ */
+package org.opendaylight.controller.sal.core;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.Set;
+import java.math.BigInteger;
+
+import java.io.Serializable;
+import java.lang.String;
+import java.util.UUID;
+import java.lang.Long;
+import java.lang.Class;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.opendaylight.controller.sal.utils.HexEncode;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
+/**
+ * Describe a generic network element in multiple SDNs technologies. A
+ * Node is identified by the pair (NodeType, NodeID), the nodetype are
+ * needed in order to further specify the nodeID
+ *
+ */
+@XmlAccessorType(XmlAccessType.NONE)
+public class Node implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Enum-like static class created with the purpose of identifing
+     * multiple type of nodes in the SDN network. The type is
+     * necessary to figure out to later on correctly use the
+     * nodeID. Using a static class instead of an Enum so we can add
+     * dynamically new types without changing anything in the
+     * surround.
+     */
+    public static final class NodeIDType {
+        private static final ConcurrentHashMap<String, Class> compatibleType =
+            new ConcurrentHashMap<String, Class>();
+        /**
+         * Identifier for an OpenFlow node
+         */
+        public static String OPENFLOW = "OF";
+        /**
+         * Identifier for a PCEP node
+         */
+        public static String PCEP = "PE";
+        /**
+         * Identifier for a ONEPK node
+         */
+        public static String ONEPK = "PK";
+        /**
+         * Identifier for a node in a non-SDN network
+         */
+        public static String PRODUCTION = "PR";
+
+        // Pre-populated types, just here for convenience and ease of
+        // unit-testing, but certainly those could live also outside.
+        static {
+            compatibleType.put(OPENFLOW, Long.class);
+            compatibleType.put(PCEP, UUID.class);
+            compatibleType.put(ONEPK, String.class);
+            compatibleType.put(PRODUCTION, String.class);
+        }
+
+        /**
+         * Return the type of the class expected for the
+         * NodeID, it's used for validity check in the constructor
+         *
+         * @param nodeType the type of the node we want to check
+         * compatibility for
+         *
+         * @return The Class which is supposed to instantiate the ID
+         * for the NodeID
+         */
+        public static Class<?> getClassType(String nodeType) {
+            return compatibleType.get(nodeType);
+        }
+
+        /**
+         * Returns all the registered nodeIDTypes currently available
+         *
+         * @return The current registered NodeIDTypes
+         */
+        public static Set<String> values() {
+            return compatibleType.keySet();
+        }
+
+        /**
+         * Register a new ID for which Node can be created
+         *
+         * @param type, the new type being registered
+         * @param compatibleID, the type of class to be accepted as ID
+         *
+         * @return true if registered, false otherwise
+         */
+        public static boolean registerIDType(String type,
+                                             Class compatibleID) {
+            if (compatibleType.get(type) != null) {
+                return false;
+            }  else {
+                compatibleType.put(type, compatibleID);
+                return true;
+            }
+        }
+
+        /**
+         * UNRegister a new ID for which Node can be created
+         *
+         * @param type, the type being UN-registered
+         *
+         */
+        public static void unRegisterIDType(String type) {
+            compatibleType.remove(type);
+        }
+    }
+
+    // This is the identity of the Node a (Type,ID) pair!, the full
+    // essence of this class.
+    private Object nodeID;
+    private String nodeType;
+
+    // Shadow value for unmarshalling
+    private String nodeIDString;
+
+    /**
+     * Private constructor used for JAXB mapping
+     */
+    private Node() {
+        this.nodeID = null;
+        this.nodeType = null;
+        this.nodeIDString = null;
+    }
+
+    /**
+     * Constructor for the Node objects, it validate the input so if
+     * the ID passed is not of the type expected accordingly to the
+     * type an exception is raised.
+     *
+     * @param nodeType Type of the node we are building
+     * @param id ID used by the SDN technology to identify the node
+     *
+     */
+    public Node(String nodeType, Object id) throws ConstructionException {
+        if (NodeIDType.getClassType(nodeType) != null &&
+            NodeIDType.getClassType(nodeType).isInstance(id)) {
+            this.nodeType = nodeType;
+            this.nodeID = id;
+        } else {
+            throw new ConstructionException("Type of incoming object:"
+                                            + id.getClass() + " not compatible with expected type:"
+                                            + NodeIDType.getClassType(nodeType));
+        }
+    }
+
+    /**
+     * Copy Constructor for the Node objects.
+     *
+     * @param src type of nodes to copy from
+     *
+     */
+    public Node(Node src) throws ConstructionException {
+        if (src != null) {
+            this.nodeType = src.getType();
+            // Here we can reference the object because that is
+            // supposed to be an immutable identifier as well like a
+            // UUID/Integer and so on, hence no need to create a copy
+            // of it
+            this.nodeID = src.getID();
+        } else {
+            throw
+                new ConstructionException("Null incoming object to copy from");
+        }
+    }
+
+    /**
+     * getter for node type
+     *
+     *
+     * @return The node Type for this Node object
+     */
+    @XmlAttribute(name = "type")
+    public String getType() {
+        return this.nodeType;
+    }
+
+    /**
+     * fill the current object from the string parameters passed, will
+     * be only used by JAXB
+     *
+     * @param typeStr string representing the type of the Node
+     * @param IDStr String representation of the ID
+     */
+    private void fillmeFromString(String typeStr, String IDStr) {
+        if (typeStr == null) {
+            return;
+        }
+
+        if (IDStr == null) {
+            return;
+        }
+
+        this.nodeType = typeStr;
+        if (typeStr.equals(NodeIDType.OPENFLOW)) {
+            this.nodeID = Long.valueOf(HexEncode.stringToLong(IDStr));
+        } else if (typeStr.equals(NodeIDType.ONEPK)) {
+            this.nodeID = IDStr;
+        } else if (typeStr.equals(NodeIDType.PCEP)) {
+            this.nodeID = UUID.fromString(IDStr);
+        } else if (typeStr.equals(NodeIDType.PRODUCTION)) {
+            this.nodeID = IDStr;
+        } else {
+            // We need to lookup via OSGi service registry for an
+            // handler for this
+        }
+    }
+
+    /** 
+     * Private setter for nodeType to be called by JAXB not by anyone
+     * else, Node is immutable
+     * 
+     * @param type of node to be set
+     */
+    private void setType(String type) {
+        this.nodeType = type;
+        if (this.nodeIDString != null) {
+            this.fillmeFromString(type, this.nodeIDString);
+        }
+    }
+
+    /**
+     * getter for node ID
+     *
+     *
+     * @return The node ID for this Node object
+     */
+    public Object getID() {
+        return this.nodeID;
+    }
+
+    /**
+     * Getter for the node ID in string format
+     *
+     * @return The nodeID in string format
+     */
+    @XmlAttribute(name = "id")
+    public String getNodeIDString() {
+        if (this.nodeType.equals(NodeIDType.OPENFLOW)) {
+            return HexEncode.longToHexString((Long) this.nodeID);
+        } else {
+            return this.nodeID.toString();
+        }
+    }
+    
+    /** 
+     * private setter to be used by JAXB
+     * 
+     * @param nodeIDString String representation for NodeID
+     */
+    private void setNodeIDString(String nodeIDString) {
+        this.nodeIDString = nodeIDString;
+        if (this.nodeType != null) {
+            this.fillmeFromString(this.nodeType, nodeIDString);
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder(163841, 56473)
+            .append(nodeType)
+            .append(nodeID)
+            .hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) { return false; }
+        if (obj == this) { return true; }
+        if (obj.getClass() != getClass()) {
+            return false;
+        }
+        Node rhs = (Node)obj;
+        return new EqualsBuilder()
+            .append(this.getType(), rhs.getType())
+            .append(this.getID(), rhs.getID())
+            .isEquals();
+    }
+
+    @Override
+    public String toString() {
+        if (this.nodeType.equals(NodeIDType.OPENFLOW)) {
+            return this.nodeType.toString() + "|"
+                + HexEncode.longToHexString((Long) this.nodeID);
+        } else {
+            return this.nodeType.toString() + "|" + this.nodeID.toString();
+        }
+    }
+
+    /**
+     * Static method to get back a Node from a string
+     *
+     * @param str string formatted in toString mode that can be
+     * converted back to a Node format.
+     *
+     * @return a Node if succed or null if no
+     */
+    public static Node fromString(String str) {
+        if (str == null) {
+            return null;
+        }
+
+        String parts[] = str.split("\\|");
+        if (parts.length != 2) {
+            // Try to guess from a String formatted as a long because
+            // for long time openflow has been prime citizen so lets
+            // keep this legacy for now
+            String numStr = str.toUpperCase();
+
+            Long ofNodeID = null;
+            if (numStr.startsWith("0X")) {
+                // Try as an hex number
+                try {
+                    BigInteger b = new BigInteger(
+                        numStr.replaceFirst("0X", ""), 16);
+                    ofNodeID = Long.valueOf(b.longValue());
+                } catch (Exception ex) {
+                    ofNodeID = null;
+                }
+            } else {
+                // Try as a decimal number
+                try {
+                    BigInteger b = new BigInteger(numStr);
+                    ofNodeID = Long.valueOf(b.longValue());
+                } catch (Exception ex) {
+                    ofNodeID = null;
+                }
+            }
+
+            // Startegy #3 parse as HexLong
+            if (ofNodeID == null) {
+                try {
+                    ofNodeID = Long.valueOf(HexEncode.stringToLong(numStr));
+                } catch (Exception ex) {
+                    ofNodeID = null;
+                }
+            }
+
+            // We ran out of ideas ... return null
+            if (ofNodeID == null) {
+                return null;
+            }
+
+            // Lets return the cooked up NodeID
+            try {
+                return new Node(NodeIDType.OPENFLOW, ofNodeID);
+            } catch (ConstructionException ex) {
+                return null;
+            }
+        }
+
+        String typeStr = parts[0];
+        String IDStr = parts[1];
+
+        return fromString(typeStr, IDStr);
+    }
+
+    /**
+     * Static method to get back a Node from a pair of strings, the
+     * first one being the Type representation, the second one being
+     * the ID string representation, expected to be heavily used in
+     * northbound API.
+     *
+     * @param type, the type of the node we are parsing
+     * @param id, the string representation of the node id
+     *
+     * @return a Node if succed or null if no
+     */
+    public static Node fromString(String typeStr, String IDStr) {
+        if (typeStr == null) {
+            return null;
+        }
+
+        if (IDStr == null) {
+            return null;
+        }
+
+        if (typeStr.equals(NodeIDType.OPENFLOW)) {
+            try {
+                Long ID = Long.valueOf(HexEncode.stringToLong(IDStr));
+                return new Node(typeStr, ID);
+            } catch (Exception ex) {
+                return null;
+            }
+        } else if (typeStr.equals(NodeIDType.ONEPK)) {
+            try {
+                return new Node(typeStr, IDStr);
+            } catch (Exception ex) {
+                return null;
+            }
+        } else if (typeStr.equals(NodeIDType.PCEP)) {
+            try {
+                UUID ID = UUID.fromString(IDStr);
+                return new Node(typeStr, ID);
+            } catch (Exception ex) {
+                return null;
+            }
+        } else if (typeStr.equals(NodeIDType.PRODUCTION)) {
+            try {
+                return new Node(typeStr, IDStr);
+            } catch (Exception ex) {
+                return null;
+            }
+        } else {
+            // We need to lookup via OSGi service registry for an
+            // handler for this
+        }
+        return null;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/NodeConnector.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/NodeConnector.java
new file mode 100644 (file)
index 0000000..bbe952d
--- /dev/null
@@ -0,0 +1,589 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   NodeConnector.java
+ *
+ * @brief  Describe a generic network element attachment points,
+ * attached to one Node, the NodeConnector is formed by the pair
+ * (NodeConnectorType, NodeConnectorID) because each SDN technlogy can
+ * identify an attachment point on the Node in different way.
+ *
+ */
+package org.opendaylight.controller.sal.core;
+
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import java.util.concurrent.ConcurrentHashMap;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlAttribute;
+
+/**
+ * Describe a generic network element attachment points,
+ * attached to one Node, the NodeConnector is formed by the pair
+ * (NodeConnectorType, NodeConnectorID) because each SDN technology can
+ * identify an attachment point on the Node in different way.
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NodeConnector implements Serializable {
+    private static final long serialVersionUID = 1L;
+    public static final Short SPECIALNODECONNECTORID = (short) 0;
+
+    /**
+     * Enumerate the different types of NodeConnectors supported by the class
+     *
+     */
+    public static class NodeConnectorIDType {
+        private static final
+        ConcurrentHashMap<String, ImmutablePair<Class, String>> compatibleType =
+            new ConcurrentHashMap<String, ImmutablePair<Class, String>>();
+        /**
+         * Represent a special port pointing toward the controller,
+         * this is to send data packets toward the controller from
+         * data plane.
+         */
+        public static String CONTROLLER = "CTRL";
+        /**
+         * Special port describing ALL the ports in the system,
+         * should be used for flooding like mechanism but better
+         * to be carefull with it
+         */
+        public static String ALL = "ALL";
+        /**
+         * Describe the local networking stack of the node
+         * on which the packet is destined. Yet another special port
+         */
+        public static String SWSTACK = "SW";
+        /**
+         * Describe a special destination that invoke the
+         * traditional HW forwarding on platforms that has this
+         * provision.
+         */
+        public static String HWPATH = "HW";
+        public static String OPENFLOW = "OF";
+        public static String PCEP = "PE";
+        public static String ONEPK = "PK";
+        public static String OPENFLOW2PCEP = "O2E";
+        public static String PCEP2OPENFLOW = "E2O";
+        public static String OPENFLOW2ONEPK = "O2K";
+        public static String ONEPK2OPENFLOW = "K2O";
+        public static String PCEP2ONEPK = "E2K";
+        public static String ONEPK2PCEP = "K2E";
+        public static String PRODUCTION = "PR";
+
+        // Initialize the map with some well known, even though all of
+        // them could be siting outside of here, but it's convenient
+        // for Unit Testing coverage
+        static {
+            compatibleType.put(CONTROLLER,
+                               new ImmutablePair(Short.class, null));
+            compatibleType.put(ALL,
+                               new ImmutablePair(Short.class, null));
+            compatibleType.put(SWSTACK,
+                               new ImmutablePair(Short.class, null));
+            compatibleType.put(HWPATH,
+                               new ImmutablePair(Short.class, null));
+            compatibleType.put(OPENFLOW,
+                               new ImmutablePair(Short.class,
+                                                 Node.NodeIDType.OPENFLOW));
+            compatibleType.put(PCEP,
+                               new ImmutablePair(Integer.class,
+                                                 Node.NodeIDType.PCEP));
+            compatibleType.put(ONEPK,
+                               new ImmutablePair(String.class,
+                                                 Node.NodeIDType.ONEPK));
+            compatibleType.put(OPENFLOW2PCEP,
+                               new ImmutablePair(Short.class,
+                                                 Node.NodeIDType.OPENFLOW));
+            compatibleType.put(OPENFLOW2ONEPK,
+                               new ImmutablePair(Short.class,
+                                                 Node.NodeIDType.OPENFLOW));
+            compatibleType.put(PCEP2OPENFLOW,
+                               new ImmutablePair(Integer.class,
+                                                 Node.NodeIDType.PCEP));
+            compatibleType.put(PCEP2ONEPK,
+                               new ImmutablePair(Integer.class,
+                                                 Node.NodeIDType.PCEP));
+            compatibleType.put(ONEPK2OPENFLOW,
+                               new ImmutablePair(String.class,
+                                                 Node.NodeIDType.ONEPK));
+            compatibleType.put(ONEPK2PCEP,
+                               new ImmutablePair(String.class,
+                                                 Node.NodeIDType.ONEPK));
+            compatibleType.put(PRODUCTION,
+                               new ImmutablePair(String.class,
+                                                 Node.NodeIDType.PRODUCTION));
+        }
+
+        /**
+         * Return the type of the class expected for the
+         * NodeConnectorID, it's used for validity check in the constructor
+         *
+         * @param type, the type of the NodeConnector for which we
+         * want to retrieve the compatible class to be used as ID.
+         *
+         * @return The Class which is supposed to instantiate the ID
+         * for the NodeConnectorID
+         */
+        public static Class<?> getClassType(String type) {
+            if (compatibleType.get(type) == null) {
+                return null;
+            }
+            return compatibleType.get(type).getLeft();
+        }
+
+        /**
+         * Return the NodeIDType compatible with this NodeConnector,
+         * in fact you cannot attach for example a PCEP NodeConnector
+         * to an OpenFlow Node.
+         *
+         * @param type, the type of the NodeConnector for which we
+         * want to retrieve the compatible class to be used as ID.
+         *
+         * @return The ID of the compatible Node
+         */
+        public static String getCompatibleNode(String type) {
+            if (compatibleType.get(type) == null) {
+                return null;
+            }
+            return compatibleType.get(type).getRight();
+        }
+
+        /**
+         * Register a new ID for which Node can be created
+         *
+         * @param type, the new type being registered
+         * @param compatibleID, the type of class to be accepted as ID
+         * @param compatibleNode, the type of Node with which this
+         * NodeConnector is compatible
+         *
+         * @return true if registered, false otherwise
+         */
+        public static boolean registerIDType(String type,
+                                             Class compatibleID,
+                                             String compatibleNode) {
+            if (compatibleType.get(type) != null) {
+                return false;
+            }  else {
+                compatibleType.put(type, new ImmutablePair(compatibleID,
+                                                           compatibleNode));
+                return true;
+            }
+        }
+
+        /**
+         * UNRegister a new ID for which Node can be created
+         *
+         * @param type, the type being UN-registered
+         *
+         */
+        public static void unRegisterIDType(String type) {
+            compatibleType.remove(type);
+        }
+    }
+
+    // Elements that constitute the NodeConnector
+    private Object nodeConnectorID;
+    private String nodeConnectorType;
+    @XmlElement(name = "node")
+    private Node nodeConnectorNode;
+
+    // Helper field for JAXB
+    private String nodeConnectorIDString;
+
+    /**
+     * Private constructor used for JAXB mapping
+     */
+    private NodeConnector() {
+        this.nodeConnectorIDString = null;
+        this.nodeConnectorID = null;
+        this.nodeConnectorType = null;
+        this.nodeConnectorNode = null;
+    }
+
+    /**
+     * Create a NodeConnector from the component element. The
+     * constructor make sure the NodeConnector type is congruent with
+     * the Node used and also the NodeConnector ID is of type expected
+     *
+     * @param nodeConnectorType Type of the NodeConnector
+     * @param id ID portion of the NodeConnector
+     * @param node Node to which the NodeConnector is attached too
+     *
+     */
+    public NodeConnector(String nodeConnectorType, Object id,
+            Node node) throws ConstructionException {
+        // In case of compatible type being null then assume that this
+        // port can be attached on any node.
+        String compatibleNode =
+            NodeConnectorIDType.getCompatibleNode(nodeConnectorType);
+        if (NodeConnectorIDType.getClassType(nodeConnectorType) != null &&
+            NodeConnectorIDType.getClassType(nodeConnectorType).isInstance(id) &&
+            (compatibleNode == null ||
+             node.getType().equals(compatibleNode))) {
+            this.nodeConnectorType = nodeConnectorType;
+            this.nodeConnectorID = id;
+            this.nodeConnectorNode = node;
+        } else {
+            throw new ConstructionException("Type of incoming object:"
+                    + id.getClass() + " not compatible with expected type:"
+                    + NodeConnectorIDType.getClassType(nodeConnectorType)
+                    + " or Node type incompatible:" + node.getType());
+        }
+    }
+
+    /**
+     * Copy constructor for NodeConnector
+     *
+     * @param src NodeConnector to copy from
+     *
+     */
+    public NodeConnector(NodeConnector src) throws ConstructionException {
+        if (src != null) {
+            this.nodeConnectorType = src.getType();
+            // Here we can reference the object because that is
+            // supposed to be an immutable identifier as well like a
+            // UUID/Integer and so on, hence no need to create a copy
+            // of it
+            this.nodeConnectorID = src.getID();
+            this.nodeConnectorNode = new Node(src.getNode());
+        } else {
+            throw
+                new ConstructionException("Null incoming object to copy from");
+        }
+    }
+
+    /**
+     * getter method for NodeConnector
+     *
+     *
+     * @return the NodeConnectorType of this object
+     */
+    @XmlAttribute(name = "type")
+    public String getType() {
+        return this.nodeConnectorType;
+    }
+
+    /**
+     * fill the current object from the string parameters passed, will
+     * be only used by JAXB
+     *
+     * @param typeStr string representing the type of the Node
+     * @param IDStr String representation of the ID
+     */
+    private void fillmeFromString(String typeStr, String IDStr) {
+        if (typeStr == null) {
+            return;
+        }
+
+        if (IDStr == null) {
+            return;
+        }
+
+        this.nodeConnectorType = typeStr;
+        if (typeStr.equals(NodeConnectorIDType.OPENFLOW) ||
+            typeStr.equals(NodeConnectorIDType.OPENFLOW2ONEPK) ||
+            typeStr.equals(NodeConnectorIDType.OPENFLOW2PCEP)) {
+            try {
+                Short ID = Short.parseShort(IDStr);
+                this.nodeConnectorID = ID;
+            } catch (Exception ex) {
+                return;
+            }
+        } else if (typeStr.equals(NodeConnectorIDType.ONEPK) ||
+                   typeStr.equals(NodeConnectorIDType.ONEPK2OPENFLOW) ||
+                   typeStr.equals(NodeConnectorIDType.ONEPK2PCEP) ||
+                   typeStr.equals(NodeConnectorIDType.PRODUCTION)) {
+            try {
+                this.nodeConnectorID = IDStr;
+            } catch (Exception ex) {
+                return;
+            }
+        } else if (typeStr.equals(NodeConnectorIDType.PCEP) ||
+                   typeStr.equals(NodeConnectorIDType.PCEP2ONEPK) ||
+                   typeStr.equals(NodeConnectorIDType.PCEP2OPENFLOW)) {
+            try {
+                Integer ID = Integer.parseInt(IDStr);
+                this.nodeConnectorID = ID;
+            } catch (Exception ex) {
+                return;
+            }
+        } else {
+            // Lookup via OSGi service registry
+        }
+    }
+
+    /** 
+     * Private setter for nodeConnectorType to be called by JAXB not by anyone
+     * else, NodeConnector is immutable
+     * 
+     * @param type of node to be set
+     */
+    private void setType(String type) {
+        this.nodeConnectorType = type;
+        if (this.nodeConnectorIDString != null) {
+            this.fillmeFromString(type, this.nodeConnectorIDString);
+        }
+    }
+
+    /**
+     * getter method for NodeConnector
+     *
+     *
+     * @return the NodeConnector ID of this object
+     */
+    public Object getID() {
+        return this.nodeConnectorID;
+    }
+
+    /**
+     * getter method for NodeConnector ID in string format.
+     *
+     *
+     * @return the NodeConnector ID of this object in String format
+     */
+    @XmlAttribute(name = "id")
+    public String getNodeConnectorIDString() {
+        return this.nodeConnectorID.toString();
+    }
+
+    /** 
+     * private setter to be used by JAXB
+     * 
+     * @param nodeConnectorIDString String representation for NodeConnectorID
+     */
+    private void setNodeConnectorIDString(String IDStr) {
+        this.nodeConnectorIDString = IDStr;
+        if (this.nodeConnectorType != null) {
+            this.fillmeFromString(this.nodeConnectorType, IDStr);
+        }
+    }
+
+    /**
+     * getter method for NodeConnector
+     *
+     *
+     * @return the Node of this object
+     */
+    public Node getNode() {
+        return this.nodeConnectorNode;
+    }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder(63389, 4951)
+            .append(nodeConnectorType)
+            .append(nodeConnectorID)
+            .append(nodeConnectorNode)
+            .hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) { return false; }
+        if (obj == this) { return true; }
+        if (obj.getClass() != getClass()) {
+            return false;
+        }
+        NodeConnector rhs = (NodeConnector)obj;
+        return new EqualsBuilder()
+            .append(this.getType(), rhs.getType())
+            .append(this.getID(), rhs.getID())
+            .append(this.getNode(), rhs.getNode())
+            .isEquals();
+    }
+
+    @Override
+    public String toString() {
+        return this.getNodeConnectorIdAsString() + "@" + this.nodeConnectorNode;
+    }
+
+    /**
+     * A String representation of the NodeConnector without
+     * the Node context
+     *
+     * @return A String representation of the NodeConnector without
+     * the Node context
+     */
+    public String getNodeConnectorIdAsString() {
+        if (this.nodeConnectorType
+            .equals(NodeConnectorIDType.CONTROLLER) ||
+            this.nodeConnectorType
+            .equals(NodeConnectorIDType.ALL) ||
+            this.nodeConnectorType
+            .equals(NodeConnectorIDType.SWSTACK) ||
+            this.nodeConnectorType
+            .equals(NodeConnectorIDType.HWPATH)) {
+            return this.nodeConnectorType.toString();
+        } else {
+            return this.nodeConnectorType.toString() + "|"
+                    + this.nodeConnectorID.toString();
+        }
+    }
+
+    /**
+     * return a NodeConnector from a string
+     *
+     * @param str String to be parsed in a NodeConnector
+     *
+     * @return the NodeConnector if parse is succesfull, null otherwise
+     */
+    public static NodeConnector fromString(String str) {
+        if (str == null) {
+            return null;
+        }
+        String parts[] = str.split("\\@");
+        if (parts.length != 2) {
+            return null;
+        }
+        // Now get the Node from the Node portion
+        Node n = Node.fromString(parts[1]);
+        if (n == null) {
+            return null;
+        }
+        return fromStringNoNode(parts[0], n);
+    }
+
+    /**
+     * return a NodeConnector from a string not containing explicitely
+     * the Node portion which has to be supplied as parameter
+     *
+     * @param str String to be parsed in a NodeConnector
+     * @param n Node to which the NodeConnector is attached
+     *
+     * @return the NodeConnector if parse is succesfull, null otherwise
+     */
+    public static NodeConnector fromStringNoNode(String str, Node n) {
+        if (str == null) {
+            return null;
+        }
+        String nodeConnectorParts[] = str.split("\\|");
+        if (nodeConnectorParts.length != 2) {
+            // Try to guess from a String formatted as a short because
+            // for long time openflow has been prime citizen so lets
+            // keep this legacy for now
+            String numStr = str.toUpperCase();
+
+            Short ofPortID = null;
+            // Try as an decimal/hex number
+            try {
+                ofPortID = Short.decode(numStr);
+            } catch (Exception ex) {
+                ofPortID = null;
+            }
+
+            // Lets try the special ports we know about
+            if (ofPortID == null) {
+                try {
+                    if (str.equalsIgnoreCase(NodeConnectorIDType.CONTROLLER
+                            .toString())) {
+                        return new NodeConnector(
+                                NodeConnectorIDType.CONTROLLER,
+                                SPECIALNODECONNECTORID, n);
+                    }
+                    if (str.equalsIgnoreCase(NodeConnectorIDType.HWPATH
+                            .toString())) {
+                        return new NodeConnector(NodeConnectorIDType.HWPATH,
+                                SPECIALNODECONNECTORID, n);
+                    }
+                    if (str.equalsIgnoreCase(NodeConnectorIDType.SWSTACK
+                            .toString())) {
+                        return new NodeConnector(NodeConnectorIDType.SWSTACK,
+                                SPECIALNODECONNECTORID, n);
+                    }
+                    if (str
+                            .equalsIgnoreCase(NodeConnectorIDType.ALL
+                                    .toString())) {
+                        return new NodeConnector(NodeConnectorIDType.ALL,
+                                SPECIALNODECONNECTORID, n);
+                    }
+                } catch (ConstructionException ex) {
+                    return null;
+                }
+                return null;
+            }
+
+            // Lets return the cooked up NodeID
+            try {
+                return new NodeConnector(NodeConnectorIDType.OPENFLOW,
+                        ofPortID, n);
+            } catch (ConstructionException ex) {
+                return null;
+            }
+        }
+
+        String typeStr = nodeConnectorParts[0];
+        String IDStr = nodeConnectorParts[1];
+        return fromStringNoNode(typeStr, IDStr, n);
+    }
+
+    /**
+     * return a NodeConnector from a pair (type, ID) in string format
+     * not containing explicitely the Node portion which has to be
+     * supplied as parameter
+     *
+     * @param typeStr type String to be parsed in a NodeConnector
+     * @param IDStr ID String portion to be parsed in a NodeConnector
+     * @param n Node to which the NodeConnector is attached
+     *
+     * @return the NodeConnector if parse is succesfull, null otherwise
+     */
+    public static NodeConnector fromStringNoNode(String typeStr, String IDStr,
+                                                 Node n) {
+        if (typeStr == null) {
+            return null;
+        }
+        if (IDStr == null) {
+            return null;
+        }
+
+        if (typeStr.equals(NodeConnectorIDType.OPENFLOW) ||
+            typeStr.equals(NodeConnectorIDType.OPENFLOW2ONEPK) ||
+            typeStr.equals(NodeConnectorIDType.OPENFLOW2PCEP)) {
+            try {
+                Short ID = Short.parseShort(IDStr);
+                return new NodeConnector(typeStr, ID, n);
+            } catch (Exception ex) {
+                return null;
+            }
+        } else if (typeStr.equals(NodeConnectorIDType.ONEPK) ||
+                   typeStr.equals(NodeConnectorIDType.ONEPK2OPENFLOW) ||
+                   typeStr.equals(NodeConnectorIDType.ONEPK2PCEP) ||
+                   typeStr.equals(NodeConnectorIDType.PRODUCTION)) {
+            try {
+                return new NodeConnector(typeStr, IDStr, n);
+            } catch (Exception ex) {
+                return null;
+            }
+        } else if (typeStr.equals(NodeConnectorIDType.PCEP) ||
+                   typeStr.equals(NodeConnectorIDType.PCEP2ONEPK) ||
+                   typeStr.equals(NodeConnectorIDType.PCEP2OPENFLOW)) {
+            try {
+                Integer ID = Integer.parseInt(IDStr);
+                return new NodeConnector(typeStr, ID, n);
+            } catch (Exception ex) {
+                return null;
+            }
+        } else {
+            // Lookup via OSGi service registry
+        }
+        return null;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Path.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Path.java
new file mode 100644 (file)
index 0000000..5584cd9
--- /dev/null
@@ -0,0 +1,154 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   Path.java
+ *
+ * @brief  Describe a path as a sequence of Edge such that from
+ * each of its Tail Node there is an link to the next Head Node in the sequence
+ *
+ */
+package org.opendaylight.controller.sal.core;
+
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.List;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * Describe a path as a sequence of Edge such that from
+ * each of its Tail Node there is an link to the next Head Node in the
+ * sequence
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class Path implements Serializable {
+    private static final long serialVersionUID = 1L;
+    @XmlElement
+    private List<Edge> edges;
+
+    /**
+     * Private constructor used for JAXB mapping
+     */
+    private Path() {
+        this.edges = null;
+    }
+
+    /**
+     * Construct an object representing a path, the constructor will
+     * check if the passed list of edges is such that for every
+     * consecutive edges the tailnode of the first edge coincide with
+     * the head node of the subsequent in order for connectivity to be there.
+     *
+     * @param edges Edges of the path
+     *
+     */
+    public Path(List<Edge> edges) throws ConstructionException {
+        // Lets check if the list of edges is such that the tail node
+        // of an edge is also the head node of the subsequent one
+        boolean sequential = true;
+        if (edges.size() >= 2) {
+            for (int i = 0; i < edges.size() - 1; i++) {
+                Edge current = edges.get(i);
+                Edge next = edges.get(i + 1);
+                if (!current.getHeadNodeConnector().getNode()
+                        .equals(
+                                next.getTailNodeConnector()
+                                        .getNode())) {
+                    sequential = false;
+                }
+            }
+        } else if (edges.size() == 0) {
+            throw new ConstructionException("Path is empty");
+        }
+
+        if (!sequential) {
+            throw new ConstructionException("Path is not sequential");
+        }
+
+        this.edges = edges;
+    }
+
+    /**
+     * Copy Construct for a path
+     *
+     * @param src Path to copy from
+     *
+     */
+    public Path(Path src) throws ConstructionException {
+        if (src != null) {
+            this.edges = new LinkedList<Edge>(src.getEdges());
+        } else {
+            throw new ConstructionException("src supplied was null");
+        }
+    }
+
+    /**
+     * get the First Node of the path
+     *
+     *
+     * @return The start Node of the Path
+     */
+    public Node getStartNode() {
+        return this.edges.get(0).getTailNodeConnector().getNode();
+    }
+
+    /**
+     * get the Last Node of the path
+     *
+     *
+     * @return The last Node of the Path
+     */
+    public Node getEndNode() {
+        return this.edges.get(this.edges.size() - 1).getHeadNodeConnector()
+                .getNode();
+    }
+
+    /**
+     * getter method for the Path
+     *
+     *
+     * @return Return the list of edges that constitue the Path
+     */
+    public List<Edge> getEdges() {
+        return this.edges;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("[");
+        for (int i = 0; i < this.edges.size(); i++) {
+            if (i != 0) {
+                // add the comma to the previous element
+                sb.append(",");
+            }
+            sb.append(this.edges.get(i).toString());
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/PeerBandwidth.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/PeerBandwidth.java
new file mode 100644 (file)
index 0000000..557e2b3
--- /dev/null
@@ -0,0 +1,66 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * @file   PeerBandWidth.java
+ *
+ * @brief  Class representing peer bandwidth
+ *
+ * Describes peer Bandwidth of peer element. It's intended in multiple of
+ *  bits per seconds.
+ */
+@XmlRootElement
+public class PeerBandwidth extends Bandwidth {
+       private static final long serialVersionUID = 1L;
+       
+       public static final String PeerBandwidthPropName = "peerBandwidth";
+       
+       public PeerBandwidth(long value) {
+               super(PeerBandwidthPropName);
+               this.bandwidthValue = value;
+       }
+       
+       /*
+     * Private constructor used for JAXB mapping
+     */
+    private PeerBandwidth() {
+       super(PeerBandwidthPropName);
+               this.bandwidthValue = 0;
+    }
+
+       public PeerBandwidth clone() {
+               return new PeerBandwidth(this.bandwidthValue);  
+    }
+       
+       @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }  
+    
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("PeerBandWidth[");
+        sb.append(super.toString());
+        sb.append("]");
+        return sb.toString();
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Property.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Property.java
new file mode 100644 (file)
index 0000000..9e4475e
--- /dev/null
@@ -0,0 +1,82 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import java.io.Serializable;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * @file   Property.java
+ *
+ * @brief  Abstract base class for a Property that can be attached to
+ * any sal core element
+ *
+ * Abstract base class for a Property that can be attached to any sal
+ * core element
+ */
+
+/**
+ * Abstract base class for a Property that can be attached to any sal
+ * core element
+ *
+ */
+@XmlRootElement
+@XmlSeeAlso({ Config.class, Name.class, State.class, TimeStamp.class,
+               Latency.class, Bandwidth.class, Tier.class, Actions.class,
+               AdvertisedBandwidth.class, Buffers.class, Capabilities.class,
+               MacAddress.class, PeerBandwidth.class, SupportedBandwidth.class,
+               Tables.class })
+abstract public class Property implements Serializable {
+    private static final long serialVersionUID = 1L;
+    private String name;
+
+    /**
+     * Private constructor used for JAXB mapping
+     */
+    private Property() {
+        this.name = null;
+    }
+
+    protected Property(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    /**
+     * Used to copy the Property in a polymorphic way
+     *
+     *
+     * @return A clone of this Property
+     */
+    abstract public Property clone();
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "Property[" + ReflectionToStringBuilder.toString(this) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/State.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/State.java
new file mode 100644 (file)
index 0000000..693abd8
--- /dev/null
@@ -0,0 +1,70 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * The class represents the State property of an Edge
+ *
+ *
+ */
+@XmlRootElement
+@SuppressWarnings("serial")
+public class State extends Property {
+    @XmlElement
+    private short stateValue;
+
+    public static final short EDGE_DOWN = 0;
+    public static final short EDGE_UP = 1;
+    public static final short EDGE_UNK = 0x7fff;
+    public static final String StatePropName = "state";
+
+    /*
+     * Private constructor used for JAXB mapping
+     */
+    private State() {
+        super(StatePropName);
+        this.stateValue = EDGE_UNK;
+    }
+
+    public State(short state) {
+        super(StatePropName);
+        this.stateValue = state;
+    }
+
+    public State clone() {
+        return new State(this.stateValue);
+    }
+
+    public short getValue() {
+        return this.stateValue;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "State[" + ReflectionToStringBuilder.toString(this) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/SupportedBandwidth.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/SupportedBandwidth.java
new file mode 100644 (file)
index 0000000..969813c
--- /dev/null
@@ -0,0 +1,68 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * @file   SupportedBandWidth.java
+ *
+ * @brief  Class representing supported bandwidth
+ *
+ * Describes Supported Bandwidth which could be of a link or whatever could have
+ * bandwidth as description. It's intended in multiple of bits per
+ * seconds.
+ */
+@XmlRootElement
+public class SupportedBandwidth extends Bandwidth {
+       private static final long serialVersionUID = 1L;
+       public static final String SupportedBandwidthPropName = "supportedBandwidth";
+       
+       public SupportedBandwidth(long value) {
+               super(SupportedBandwidthPropName);
+               this.bandwidthValue = value;
+       }
+       
+       /*
+     * Private constructor used for JAXB mapping
+     */
+    private SupportedBandwidth() {
+       super(SupportedBandwidthPropName);
+               this.bandwidthValue = 0;
+    }
+       
+       public SupportedBandwidth clone() {
+               return new SupportedBandwidth(this.bandwidthValue);  
+    }
+       
+       @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }    
+    
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("SupportedBandWidth[");
+        sb.append(super.toString());
+        sb.append("]");
+        return sb.toString();
+    }
+
+
+}
\ No newline at end of file
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Tables.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Tables.java
new file mode 100644 (file)
index 0000000..4775aa8
--- /dev/null
@@ -0,0 +1,74 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+
+/**
+ * @file   Tables.java
+ *
+ * @brief  Class representing tables
+ *
+ * Describes supported # of datapath tables
+ */
+@XmlRootElement
+public class Tables extends Property {
+       private static final long serialVersionUID = 1L;
+    @XmlElement
+    private byte tablesValue;
+    
+    public static final String TablesPropName = "tables";
+    /**
+     * Construct a Tables property
+     *
+     * @param tables the Tables 
+     * @return Constructed object
+     */
+    public Tables(byte tables) {
+        super(TablesPropName);
+        this.tablesValue = tables;
+    }
+
+    /*
+     * Private constructor used for JAXB mapping
+     */
+    private Tables() {
+        super(TablesPropName);
+        this.tablesValue = 0;
+    }
+
+    public Tables clone() {
+        return new Tables(this.tablesValue);
+    }
+
+    public byte getValue() {
+        return this.tablesValue;
+    }
+    
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "Tables[" + ReflectionToStringBuilder.toString(this) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Tier.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Tier.java
new file mode 100644 (file)
index 0000000..89db9aa
--- /dev/null
@@ -0,0 +1,66 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+
+/**
+ * The class represents the Tier property of a node
+ *
+ *
+ */
+@XmlRootElement
+@SuppressWarnings("serial")
+public class Tier extends Property {
+    @XmlElement
+    private int tierValue;
+    public static final String TierPropName = "tier";
+
+    public Tier(int tier) {
+        super(TierPropName);
+        this.tierValue = tier;
+    }
+
+    /*
+     * Private constructor used for JAXB mapping
+     */
+    private Tier() {
+        super(TierPropName);
+        this.tierValue = 0;
+    }
+
+    public Tier clone() {
+        return new Tier(this.tierValue);
+    }
+
+    public int getValue() {
+        return this.tierValue;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "Tier[" + ReflectionToStringBuilder.toString(this) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/TimeStamp.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/TimeStamp.java
new file mode 100644 (file)
index 0000000..cfdceac
--- /dev/null
@@ -0,0 +1,90 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * @file   TimeStamp.java
+ *
+ * @brief  Class representing a TimeStamp
+ *
+ * A property describing a timestamp based following the rules of
+ * java.util.Date, also given the time stamp represent the time when
+ * something happened, then a name is attached to this property so
+ * to qualify what are we talking about
+ */
+@XmlRootElement
+public class TimeStamp extends Property {
+    private static final long serialVersionUID = 1L;
+    @XmlElement
+    private long timestamp;
+    @XmlElement
+    private String timestampName;
+
+    public static final String TimeStampPropName = "timeStamp";
+
+    /**
+     * Construct a TimeStamp proporty
+     *
+     * @param timestamp the time stampt we want to describe in "epoch"
+     * format following the rules of java.util.Date
+     * @param timestampName A qualifier for the timestamp, for example
+     * "JoinTime" or any even qualifier could come up
+     *
+     * @return Constructed object
+     */
+    public TimeStamp(long timestamp, String timestampName) {
+        super(TimeStampPropName);
+        this.timestamp = timestamp;
+        this.timestampName = timestampName;
+    }
+
+    /*
+     * Private constructor used for JAXB mapping
+     */
+    private TimeStamp() {
+        super(TimeStampPropName);
+        this.timestamp = 0;
+        this.timestampName = null;
+    }
+
+    public TimeStamp clone() {
+        return new TimeStamp(this.timestamp, this.timestampName);
+    }
+
+    public long getValue() {
+        return this.timestamp;
+    }
+
+    public String getTimeStampName() {
+        return this.timestampName;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "TimeStamp[" + ReflectionToStringBuilder.toString(this) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/UpdateType.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/UpdateType.java
new file mode 100644 (file)
index 0000000..84883c6
--- /dev/null
@@ -0,0 +1,37 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+
+/**
+ * @file   UpdateType.java
+ *
+ * @brief  Describes update types
+ *
+ */
+public enum UpdateType {
+    ADDED("added"), REMOVED("removed"), CHANGED("changed");
+
+    private String name;
+
+    UpdateType(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    @Override
+    public String toString() {
+        return "UpdateType[" + ReflectionToStringBuilder.toString(this) + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/discovery/IDiscoveryService.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/discovery/IDiscoveryService.java
new file mode 100644 (file)
index 0000000..3dda38e
--- /dev/null
@@ -0,0 +1,33 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.discovery;
+
+import java.util.Set;
+
+import org.opendaylight.controller.sal.core.Edge;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.UpdateType;
+
+/**
+ * The interface class provides the methods to notify the listener when an edge
+ * is added/deleted/changed
+ */
+public interface IDiscoveryService {
+    /**
+     * The methods is called when an edge is added/deleted/changed
+     *
+     * @param edge                     {@link org.opendaylight.controller.sal.core.Edge} being updated
+     * @param type             {@link org.opendaylight.controller.sal.core.UpdateType}
+     * @param props            set of {@link org.opendaylight.controller.sal.core.Property} like
+     *                                                 {@link org.opendaylight.controller.sal.core.Bandwidth} and/or
+     *                                                 {@link org.opendaylight.controller.sal.core.Latency} etc.
+     */
+    public void notifyEdge(Edge edge, UpdateType type, Set<Property> props);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/flowprogrammer/Flow.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/flowprogrammer/Flow.java
new file mode 100644 (file)
index 0000000..16c85a1
--- /dev/null
@@ -0,0 +1,263 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.flowprogrammer;
+
+import java.net.Inet6Address;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.opendaylight.controller.sal.action.Action;
+import org.opendaylight.controller.sal.action.ActionType;
+import org.opendaylight.controller.sal.action.SetDlType;
+import org.opendaylight.controller.sal.action.SetNwDst;
+import org.opendaylight.controller.sal.action.SetNwSrc;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.utils.EtherTypes;
+
+/**
+ * Represent a flow: match + actions + flow specific properties
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class Flow implements Cloneable {
+    @XmlElement
+    private Match match;
+    @XmlElement
+    private List<Action> actions;
+    @XmlElement
+    private short priority;
+    @XmlElement
+    private short idleTimeout;
+    @XmlElement
+    private short hardTimeout;
+    @XmlElement
+    private long id; // unique identifier for this flow
+
+    public Flow() {
+        match = null;
+        actions = null;
+    }
+
+    public Flow(Match match, List<Action> actions) {
+        if (match.isIPv4() && actionsAreIPv6()) {
+            try {
+                throw new Exception("Conflicting Match and Action list");
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        } else {
+            this.match = match;
+            this.actions = actions;
+        }
+    }
+
+    /**
+     * Return a copy of the Match configured on this flow
+     *
+     * @return
+     */
+    public Match getMatch() {
+        return match.clone();
+    }
+
+    /**
+     * Set the Match for this flow
+     * This operation will overwrite an existing Match if present
+     *
+     * @param match
+     */
+    public void setMatch(Match match) {
+        this.match = match;
+    }
+
+    /**
+     * Returns a copy of the actions list of this flow
+     * @return
+     */
+    public List<Action> getActions() {
+        return (actions == null) ? null : new ArrayList<Action>(actions);
+    }
+
+    /**
+     * Set the actions list for this flow
+     * If a list is already present, it will be
+     * replaced with the passed one. During
+     * addition, only the valid actions will be added
+     * It is a no op if the passed actions is null
+     * An empty actions is a vlaid input
+     *
+     * @param actions
+     */
+    public void setActions(List<Action> actions) {
+        if (actions == null) {
+            return;
+        }
+
+        this.actions = new ArrayList<Action>(actions.size());
+        for (Action action : actions) {
+            if (action.isValid()) {
+                this.actions.add(action);
+            }
+        }
+    }
+
+    /**
+     * Returns whether the Flow is for IPv4 or IPv6
+     * Information is derived from match and actions list
+     *
+     * @return
+     */
+    public boolean isIPv6() {
+        return (match.isIPv6()) ? true : actionsAreIPv6();
+    }
+
+    /**
+     * Returns true if it finds at least one action which is for IPv6
+     * in the list of actions for this Flow
+     *
+     * @return
+     */
+    private boolean actionsAreIPv6() {
+        if (this.actions != null) {
+            for (Action action : actions) {
+                switch (action.getType()) {
+                case SET_NW_SRC:
+                    if (((SetNwSrc) action).getAddress() instanceof Inet6Address) {
+                        return true;
+                    }
+                    break;
+                case SET_NW_DST:
+                    if (((SetNwDst) action).getAddress() instanceof Inet6Address) {
+                        return true;
+                    }
+                    break;
+                case SET_DL_TYPE:
+                    if (((SetDlType) action).getDlType() == EtherTypes.IPv6
+                            .intValue()) {
+                        return true;
+                    }
+                    break;
+                default:
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public Flow clone() {
+        Flow cloned = null;
+        try {
+            cloned = (Flow) super.clone();
+            cloned.match = this.getMatch();
+            cloned.actions = this.getActions();
+        } catch (CloneNotSupportedException e) {
+            e.printStackTrace();
+        }
+        return cloned;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "Flow[match = " + match + ", actions = " + actions
+                + ", priority = " + priority + ", id = " + id
+                + ", idleTimeout = " + idleTimeout + ", hardTimeout = "
+                + hardTimeout + "]";
+    }
+
+    public short getPriority() {
+        return priority;
+    }
+
+    public void setPriority(short priority) {
+        this.priority = priority;
+    }
+
+    public short getIdleTimeout() {
+        return idleTimeout;
+    }
+
+    public void setIdleTimeout(short idleTimeout) {
+        this.idleTimeout = idleTimeout;
+    }
+
+    public short getHardTimeout() {
+        return hardTimeout;
+    }
+
+    public void setHardTimeout(short hardTimeout) {
+        this.hardTimeout = hardTimeout;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    /**
+     * Adds the specified action to the list of action of this flow
+     *
+     * @param action
+     * @return false if the passed action is null or not valid or if it fails to add it
+     */
+    public boolean addAction(Action action) {
+        if (action == null || !action.isValid()) {
+            return false;
+        }
+        return actions.add(action);
+    }
+
+    public boolean removeAction(Action action) {
+        if (action == null) {
+            return false;
+        }
+        return actions.remove(action);
+    }
+
+    /**
+     * remove ALL actions of type actionType from the list of actions of this flow
+     *
+     * @param actionType
+     * @return false if an action of that type is present and it fails to remove it
+     */
+    public boolean removeAction(ActionType actionType) {
+        Iterator<Action> actionIter = this.getActions().iterator();
+        while (actionIter.hasNext()) {
+            Action action = actionIter.next();
+            if (action.getType() == actionType) {
+                if (!this.removeAction(action))
+                    return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/flowprogrammer/IFlowProgrammerService.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/flowprogrammer/IFlowProgrammerService.java
new file mode 100644 (file)
index 0000000..956942c
--- /dev/null
@@ -0,0 +1,50 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.flowprogrammer;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.utils.Status;
+
+/**
+ * Interface for installing/removing flows on a network node
+ *
+ *
+ *
+ */
+public interface IFlowProgrammerService {
+    /**
+     * Add a flow to the network node
+     *
+     * @param node
+     * @param flow
+     */
+    Status addFlow(Node node, Flow flow);
+
+    /**
+     * Modify existing flow on the switch
+     *
+     * @param node
+     * @param flow
+     */
+    Status modifyFlow(Node node, Flow oldflow, Flow newFlow);
+
+    /**
+     * Remove the flow from the network node
+     * @param node
+     * @param flow
+     */
+    Status removeFlow(Node node, Flow flow);
+
+    /**
+     * Remove all flows present on the network node
+     * @param node
+     */
+    Status removeAllFlows(Node node);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/flowprogrammer/IPluginInFlowProgrammerService.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/flowprogrammer/IPluginInFlowProgrammerService.java
new file mode 100644 (file)
index 0000000..1fb99e0
--- /dev/null
@@ -0,0 +1,52 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.flowprogrammer;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.utils.Status;
+
+/**
+ * @file   IPluginOutFlowProgrammer.java
+ *
+ * @brief  Flow programmer interface to be implemented by protocol plugins
+ *
+ *
+ *
+ */
+public interface IPluginInFlowProgrammerService {
+    /**
+     * Add a flow to the network node
+     *
+     * @param node
+     * @param flow
+     */
+       Status addFlow(Node node, Flow flow);
+
+    /**
+     * Modify existing flow on the switch
+     *
+     * @param node
+     * @param flow
+     */
+       Status modifyFlow(Node node, Flow oldFlow, Flow newFlow);
+
+    /**
+     * Remove the flow from the network node
+     * @param node
+     * @param flow
+     */
+       Status removeFlow(Node node, Flow flow);
+
+    /**
+     * Remove all flows present on the network node
+     * @param node
+     */
+       Status removeAllFlows(Node node);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/inventory/IInventoryService.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/inventory/IInventoryService.java
new file mode 100644 (file)
index 0000000..2df6053
--- /dev/null
@@ -0,0 +1,37 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.inventory;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Property;
+
+/**
+ * Interface class that describes methods invoked from application toward SAL to
+ * solicit existing inventory data
+ */
+public interface IInventoryService {
+    /**
+     * The method retrieves all the existing nodes and properties attached
+     *
+     * @return map of {@link org.opendaylight.controller.sal.core.Node} and {@link org.opendaylight.controller.sal.core.Property}
+     */
+    public ConcurrentMap<Node, Map<String, Property>> getNodeProps();
+
+    /**
+     * The method retrieve all the existing nodeConnectors and their properties
+     *
+     * @return map of {@link org.opendaylight.controller.sal.core.NodeConnector} and {@link org.opendaylight.controller.sal.core.Property}
+     */
+    public ConcurrentMap<NodeConnector, Map<String, Property>> getNodeConnectorProps();
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/inventory/IListenInventoryUpdates.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/inventory/IListenInventoryUpdates.java
new file mode 100644 (file)
index 0000000..7dbb593
--- /dev/null
@@ -0,0 +1,46 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.inventory;
+
+import java.util.Set;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.UpdateType;
+
+/**
+ * The interface class provides the methods to notify the upper applications
+ * in regards to any inventory changes.
+ */
+public interface IListenInventoryUpdates {
+    /**
+     * This method is called when some properties of a node are added/deleted/changed.
+     *
+     * @param node                     {@link org.opendaylight.controller.sal.core.Node} being updated
+     * @param type             {@link org.opendaylight.controller.sal.core.UpdateType}
+     * @param props            set of {@link org.opendaylight.controller.sal.core.Property} such as
+     *                                                 {@link org.opendaylight.controller.sal.core.Name} and/or
+     *                                                 {@link org.opendaylight.controller.sal.core.Tier} etc.
+     */
+    public void updateNode(Node node, UpdateType type, Set<Property> props);
+
+    /**
+     * This method is called when some properties of a node connector are added/deleted/changed.
+     *
+     * @param nodeConnector    {@link org.opendaylight.controller.sal.core.NodeConnector} being updated
+     * @param type             {@link org.opendaylight.controller.sal.core.UpdateType}
+     * @param props            set of {@link org.opendaylight.controller.sal.core.Property} such as
+     *                                                 {@link org.opendaylight.controller.sal.core.Name} and/or
+     *                                                 {@link org.opendaylight.controller.sal.core.State} etc.
+     */
+    public void updateNodeConnector(NodeConnector nodeConnector,
+            UpdateType type, Set<Property> props);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/inventory/IPluginInInventoryService.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/inventory/IPluginInInventoryService.java
new file mode 100644 (file)
index 0000000..420f9bb
--- /dev/null
@@ -0,0 +1,39 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.inventory;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Property;
+
+/**
+ * The interface class that describes methods invoked from SAL toward the protocol
+ * plugin to solicit existing inventory data.
+ */
+public interface IPluginInInventoryService {
+    /**
+     * The method retrieves all the existing nodes and properties attached
+     *
+     * @return map of {@link org.opendaylight.controller.sal.core.Node} and {@link org.opendaylight.controller.sal.core.Property}
+     */
+    public ConcurrentMap<Node, Map<String, Property>> getNodeProps();
+
+    /**
+     * The method retrieve all the existing nodeConnectors and their properties
+     *
+     * @param refresh true if it needs to solicit Openflow core; otherwise, retrieve from local cache.
+     * @return map of {@link org.opendaylight.controller.sal.core.NodeConnector} and {@link org.opendaylight.controller.sal.core.Property}
+     */
+    public ConcurrentMap<NodeConnector, Map<String, Property>> getNodeConnectorProps(
+            Boolean refresh);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/inventory/IPluginOutInventoryService.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/inventory/IPluginOutInventoryService.java
new file mode 100644 (file)
index 0000000..6fb9283
--- /dev/null
@@ -0,0 +1,46 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.inventory;
+
+import java.util.Set;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.UpdateType;
+
+/**
+ * The interface class describes Inventory update methods to be implemented by
+ * protocol plugin
+ */
+public interface IPluginOutInventoryService {
+    /**
+     * This method is called when some properties of a node are added/deleted/changed.
+     *
+     * @param node                     {@link org.opendaylight.controller.sal.core.Node} being updated
+     * @param type             {@link org.opendaylight.controller.sal.core.UpdateType}
+     * @param props            set of {@link org.opendaylight.controller.sal.core.Property} such as
+     *                                                 {@link org.opendaylight.controller.sal.core.Name} and/or
+     *                                                 {@link org.opendaylight.controller.sal.core.Tier} etc.
+     */
+    public void updateNode(Node node, UpdateType type, Set<Property> props);
+
+    /**
+     * This method is called when some properties of a node connector are added/deleted/changed.
+     *
+     * @param nodeConnector    {@link org.opendaylight.controller.sal.core.NodeConnector} being updated
+     * @param type             {@link org.opendaylight.controller.sal.core.UpdateType}
+     * @param props            set of {@link org.opendaylight.controller.sal.core.Property} such as
+     *                                                 {@link org.opendaylight.controller.sal.core.Name} and/or
+     *                                                 {@link org.opendaylight.controller.sal.core.State} etc.
+     */
+    public void updateNodeConnector(NodeConnector nodeConnector,
+            UpdateType type, Set<Property> props);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/Match.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/Match.java
new file mode 100644 (file)
index 0000000..a4fc2e9
--- /dev/null
@@ -0,0 +1,343 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.match;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.opendaylight.controller.sal.utils.EtherTypes;
+import org.opendaylight.controller.sal.utils.IPProtocols;
+import org.opendaylight.controller.sal.utils.NetUtils;
+
+/**
+ * Represents the generic match criteria for a network frame/packet/message
+ * It contains a collection of individual field match
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class Match implements Cloneable {
+    private static final Map<MatchType, MatchType> reversableMatches;
+    static {
+        Map<MatchType, MatchType> map = new HashMap<MatchType, MatchType>();
+        map.put(MatchType.DL_SRC, MatchType.DL_DST);
+        map.put(MatchType.DL_DST, MatchType.DL_SRC);
+        map.put(MatchType.NW_SRC, MatchType.NW_DST);
+        map.put(MatchType.NW_DST, MatchType.NW_SRC);
+        map.put(MatchType.TP_SRC, MatchType.TP_DST);
+        map.put(MatchType.TP_DST, MatchType.TP_SRC);
+        reversableMatches = Collections.unmodifiableMap(map);
+    }
+    private Map<MatchType, MatchField> fields;
+    private int matches; // concise way to tell which fields the match is set for (may remove if not needed)
+
+    public Match() {
+        fields = new HashMap<MatchType, MatchField>();
+        matches = 0;
+    }
+
+    public Match(Match match) {
+        fields = new HashMap<MatchType, MatchField>(match.fields);
+        matches = match.matches;
+    }
+
+    /**
+     * Generic setter for frame/packet/message's header fields against which to match
+     * Note: For MAC addresses, please pass the cloned value to this function
+     *
+     * @param type             packet's header field type
+     * @param value    field's value to assign to the match
+     * @param mask             field's bitmask to apply to the match (has to be of the same class type of value)
+     */
+    public void setField(MatchType type, Object value, Object mask) {
+        MatchField field = new MatchField(type, value, mask);
+        if (field.isValid()) {
+            fields.put(type, field);
+            matches |= type.getIndex();
+        }
+    }
+
+    /**
+     * Generic setter for frame/packet/message's header fields against which to match
+     * Note: For MAC addresses, please pass the cloned value to this function
+     *
+     * @param type             packet's header field type
+     * @param value    field's value to assign to the match
+     */
+    public void setField(MatchType type, Object value) {
+        MatchField field = new MatchField(type, value);
+        if (field.isValid()) {
+            fields.put(type, field);
+            matches |= type.getIndex();
+        }
+    }
+
+    /**
+     * Generic setter for frame/packet/message's header field against which to match
+     *
+     * @param field the fields parameters as MAtchField object
+     */
+    public void setField(MatchField field) {
+        if (field.isValid()) {
+            fields.put(field.getType(), field);
+            matches |= field.getType().getIndex();
+        }
+    }
+
+    /**
+     * Generic method to clear a field from the match
+     */
+    public void clearField(MatchType type) {
+        fields.remove(type);
+        matches &= ~type.getIndex();
+    }
+
+    /**
+     * Generic getter for fields against which the match is programmed
+     *
+     * @param type     frame/packet/message's header field type
+     * @return
+     */
+    public MatchField getField(MatchType type) {
+        return fields.get(type);
+    }
+
+    /**
+     * Returns the fields the match is set for in a bitmask fashion
+     * Each bit represents a field the match is configured for
+     *
+     * @return the 32 bit long mask (Refer to {@code}org.opendaylight.controller.sal.match.MatchElement)
+     */
+    @XmlElement
+    public int getMatches() {
+        return matches;
+    }
+
+    /**
+     * Returns the list of MatchType fields the match is set for
+     *
+     * @return List of individual MatchType fields. 
+     */
+    public List<MatchType> getMatchesList() {
+        return new ArrayList<MatchType>(fields.keySet());
+    }
+
+    /**
+     * Returns whether this match is for an IPv6 flow
+     */
+    public boolean isIPv6() {
+        return (isPresent(MatchType.DL_TYPE)
+                && ((Short) getField(MatchType.DL_TYPE).getValue())
+                        .equals(EtherTypes.IPv6.shortValue())
+                || isPresent(MatchType.NW_PROTO)
+                && ((Byte) getField(MatchType.NW_PROTO).getValue())
+                        .equals(IPProtocols.IPV6ICMP.byteValue())
+                || isPresent(MatchType.NW_SRC)
+                && getField(MatchType.NW_SRC).getValue() instanceof Inet6Address || isPresent(MatchType.NW_DST)
+                && getField(MatchType.NW_DST).getValue() instanceof Inet6Address);
+    }
+
+    /**
+     * Returns whether this match is for an IPv4 flow
+     */
+    public boolean isIPv4() {
+        return !isIPv6();
+    }
+
+    /**
+     * Returns whether for the specified field type the match is to be considered "any"
+     * Equivalent to say this match does not care about the value of the specified field
+     *
+     * @param type
+     * @return
+     */
+    public boolean isAny(MatchType type) {
+        //return ((fields.get(type) == null) || (fields.get(type).getBitMask() == 0L));
+        return !fields.containsKey(type);
+    }
+
+    /**
+     * Returns whether a match for the specified field type is configured
+     *
+     * @param type
+     * @return
+     */
+    public boolean isPresent(MatchType type) {
+        return (fields.get(type) != null);
+    }
+
+    @Override
+    public Match clone() {
+        Match cloned = null;
+        try {
+            cloned = (Match) super.clone();
+            cloned.fields = new HashMap<MatchType, MatchField>();
+            for (Entry<MatchType, MatchField> entry : this.fields.entrySet()) {
+                cloned.fields.put(entry.getKey(), entry.getValue().clone());
+            }
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeException(e);
+        }
+        return cloned;
+    }
+
+    /**
+     * Returns a reversed version of this match
+     * For example, in the reversed version the network source and destination
+     * addresses will be exchanged. Non symmetric match field will not be
+     * copied over into the reversed match version, like input port.
+     *
+     * @return
+     */
+    public Match reverse() {
+        // Copy over all fields
+        Match reverse = this.clone();
+
+        // Flip symmetric fields
+        for (Map.Entry<MatchType, MatchType> entry : Match.reversableMatches
+                .entrySet()) {
+            MatchType from = entry.getKey();
+            MatchType to = entry.getValue();
+            if (this.isPresent(from)) {
+                reverse.setField(to, this.getField(from).getValue(), this
+                        .getField(from).getMask());
+            }
+        }
+
+        // Reset asymmetric fields
+        reverse.clearField(MatchType.IN_PORT);
+
+        return reverse;
+    }
+
+    /**
+     * Check whether the current match conflicts with the passed filter match
+     * This match conflicts with the filter if for at least a MatchType defined
+     * in the filter match, the respective MatchFields differ or are not compatible
+     *
+     * For example, Let's suppose the filter has the following MatchFields:
+     * DL_TYPE = 0x800
+     * NW_DST =  172.20.30.110/24
+     *
+     * while this match has the following MatchFields:
+     * NW_DST = 172.20.30.45/24
+     * TP_DST = 80
+     *
+     * Then the function would return false as the two Match are not conflicting
+     *
+     * Note: the mask value is taken into account only for MatchType.NW_SRC and MatchType.NW_DST
+     *
+     * @param match the MAtch describing the filter
+     * @return true if the match is conflicting with the filter, false otherwise
+     */
+    public boolean conflictWithFilter(Match filter) {
+        // Iterate through the MatchType defined in the filter
+        for (MatchType type : filter.getMatchesList()) {
+            if (this.isAny(type)) {
+                continue;
+            }
+
+            MatchField thisField = this.getField(type);
+            MatchField filterField = filter.getField(type);
+
+            switch (type) {
+            case DL_SRC:
+            case DL_DST:
+                if (Arrays.equals((byte[]) thisField.getValue(),
+                        (byte[]) filterField.getValue())) {
+                    return false;
+                }
+                break;
+            case NW_SRC:
+            case NW_DST:
+                InetAddress thisAddress = (InetAddress) thisField.getValue();
+                InetAddress filterAddress = (InetAddress) filterField
+                        .getValue();
+                // Validity check
+                if (thisAddress instanceof Inet4Address
+                        && filterAddress instanceof Inet6Address
+                        || thisAddress instanceof Inet6Address
+                        && filterAddress instanceof Inet4Address) {
+                    return true;
+                }
+                InetAddress thisMask = (InetAddress) filter.getField(type)
+                        .getMask();
+                InetAddress filterMask = (InetAddress) filter.getField(type)
+                        .getMask();
+                // thisAddress has to be in same subnet of filterAddress
+                if (NetUtils.inetAddressConflict(thisAddress, filterAddress,
+                        thisMask, filterMask)) {
+                    return true;
+                }
+                break;
+            default:
+                if (!thisField.getValue().equals(filterField.getValue())) {
+                    return true;
+                }
+            }
+            //TODO: check v4 v6 incompatibility
+        }
+        return false;
+    }
+
+    /**
+     * Merge the current Match fields with the fields of the filter Match
+     * A check is first run to see if this Match is compatible with the
+     * filter Match. If it is not, the merge is not attempted.
+     *
+     *
+     * @param filter
+     * @return
+     */
+    public Match mergeWithFilter(Match filter) {
+        if (!this.conflictWithFilter(filter)) {
+            /*
+             * No conflict with the filter
+             * We can copy over the fields which this match does not have
+             */
+            for (MatchType type : filter.getMatchesList()) {
+                if (this.isAny(type)) {
+                    this.setField(filter.getField(type).clone());
+                }
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "Match[" + fields.values() + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchField.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchField.java
new file mode 100644 (file)
index 0000000..19c365b
--- /dev/null
@@ -0,0 +1,186 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.match;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.opendaylight.controller.sal.utils.HexEncode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents the generic matching field
+ *
+ *
+ *
+ */
+public class MatchField implements Cloneable {
+    private static final Logger logger = LoggerFactory
+            .getLogger(MatchField.class);
+    private MatchType type; // the field we want to match
+    private Object value; // the value of the field we want to match
+    private Object mask; // the value of the mask we want to match on the specified field
+    private transient boolean isValid;
+
+    /**
+     * Mask based match constructor
+     *
+     * @param type
+     * @param value
+     * @param mask   has to be of the same class type of value. A null mask means full match
+     */
+    public MatchField(MatchType type, Object value, Object mask) {
+        this.type = type;
+        this.value = value;
+        this.mask = mask;
+        this.isValid = checkValueType() && checkValues(); // Keep this logic, value checked only if type check is fine
+    }
+
+    /**
+     * Full match constructor
+     *
+     * @param type
+     * @param value
+     */
+    public MatchField(MatchType type, Object value) {
+        this.type = type;
+        this.value = value;
+        this.mask = null;
+        this.isValid = checkValueType() && checkValues(); // Keep this logic, value checked only if type check is fine
+    }
+
+    /**
+     * Returns the value set for this match field
+     *
+     * @return
+     */
+    public Object getValue() {
+        return value;
+    }
+
+    /**
+     * Returns the type field this match field object is for
+     *
+     * @return
+     */
+    public MatchType getType() {
+        return type;
+    }
+
+    /**
+     * Returns the mask value set for this field match
+     * A null mask means this is a full match
+     * @return
+     */
+    public Object getMask() {
+        return mask;
+    }
+
+    /**
+     * Returns the bitmask set for this field match
+     *
+     * @return
+     */
+    public long getBitMask() {
+        return type.getBitMask(mask);
+    }
+
+    /**
+     * Returns whether the field match configuration is valid or not
+     *
+     * @return
+     */
+    public boolean isValid() {
+        return isValid;
+    }
+
+    private boolean checkValueType() {
+        if (type.isCongruentType(value, mask) == false) {
+            String valueClass = (value == null) ? "null" : value.getClass()
+                    .getSimpleName();
+            String maskClass = (mask == null) ? "null" : mask.getClass()
+                    .getSimpleName();
+            String error = "Invalid match field's value or mask types.For field: "
+                    + type.id()
+                    + " Expected:"
+                    + type.dataType().getSimpleName()
+                    + " or equivalent,"
+                    + " Got:(" + valueClass + "," + maskClass + ")";
+            throwException(error);
+            return false;
+        }
+        return true;
+    }
+
+    private boolean checkValues() {
+        if (type.isValid(value, mask) == false) {
+            String maskString = (mask == null) ? "null" : ("0x" + Integer
+                    .toHexString(Integer.parseInt(mask.toString())));
+            String error = "Invalid match field's value or mask assignement.For field: "
+                    + type.id()
+                    + " Expected: "
+                    + type.getRange()
+                    + ", Got:(0x"
+                    + Integer.toHexString(Integer.parseInt(value.toString()))
+                    + "," + maskString + ")";
+
+            throwException(error);
+            return false;
+        }
+        return true;
+    }
+
+    private static void throwException(String error) {
+        try {
+            throw new Exception(error);
+        } catch (Exception e) {
+            logger.error(e.getMessage());
+        }
+    }
+
+    @Override
+    public MatchField clone() {
+        MatchField cloned = null;
+        try {
+            cloned = (MatchField) super.clone();
+            if (value instanceof byte[]) {
+                cloned.value = ((byte[]) this.value).clone();
+                if (this.mask != null) {
+                    cloned.mask = ((byte[]) this.mask).clone();
+                }
+            }
+        } catch (CloneNotSupportedException e) {
+            e.printStackTrace();
+        }
+        return cloned;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        String valueString = (value == null) ? "null"
+                : (value instanceof byte[]) ? HexEncode
+                        .bytesToHexString((byte[]) value) : value.toString();
+        String maskString = (mask == null) ? "null"
+                : (mask instanceof byte[]) ? HexEncode
+                        .bytesToHexString((byte[]) mask) : mask.toString();
+
+        return type + "(" + valueString + "," + maskString + ")";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java
new file mode 100644 (file)
index 0000000..b54dd3b
--- /dev/null
@@ -0,0 +1,193 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.match;
+
+import java.net.InetAddress;
+
+import org.opendaylight.controller.sal.core.NodeConnector;
+
+/**
+ * Represents the binding between the id, the value and mask type and the range values
+ * of the elements type that can be matched on the network frame/packet/message
+ *
+ *
+ *
+ */
+public enum MatchType {
+    IN_PORT("inPort", 1 << 0, NodeConnector.class, 1, 0), DL_SRC("dlSrc",
+            1 << 1, Byte[].class, 0, 0xffffffffffffL), DL_DST("dlDst", 1 << 2,
+            Byte[].class, 0, 0xffffffffffffL), DL_VLAN("dlVlan", 1 << 3,
+            Short.class, 2, 0xfff), // 2 bytes
+    DL_VLAN_PR("dlVlanPriority", 1 << 4, Byte.class, 0, 0x7), // 3 bits
+    DL_OUTER_VLAN("dlOuterVlan", 1 << 5, Short.class, 2, 0xfff), DL_OUTER_VLAN_PR(
+            "dlOuterVlanPriority", 1 << 6, Short.class, 0, 0x7), DL_TYPE(
+            "dlType", 1 << 7, Short.class, 0, 0xffff), // 2 bytes
+    NW_TOS("nwTOS", 1 << 8, Byte.class, 0, 0xff), // 1 byte
+    NW_PROTO("nwProto", 1 << 9, Byte.class, 0, 0xff), // 1 byte
+    NW_SRC("nwSrc", 1 << 10, InetAddress.class, 0, 0), NW_DST("nwDst", 1 << 11,
+            InetAddress.class, 0, 0), TP_SRC("tpSrc", 1 << 12, Short.class, 1,
+            0xffff), // 2 bytes
+    TP_DST("tpDst", 1 << 13, Short.class, 1, 0xffff); // 2 bytes
+
+    private String id;
+    private int index;
+    private Class<?> dataType;
+    private long minValue;
+    private long maxValue;
+
+    private MatchType(String id, int index, Class<?> dataType, long minValue,
+            long maxValue) {
+        this.id = id;
+        this.index = index;
+        this.dataType = dataType;
+        this.minValue = minValue;
+        this.maxValue = maxValue;
+    }
+
+    public String id() {
+        return id;
+    }
+
+    public int getIndex() {
+        return index;
+    }
+
+    public Class<?> dataType() {
+        return dataType;
+    }
+
+    public String getRange() {
+        return "[0x" + Long.toHexString(minValue) + "-0x"
+                + Long.toHexString(maxValue) + "]";
+    }
+
+    /**
+     *  Perform the assignment type validation
+     * @param value
+     * @param mask
+     * @return
+     */
+    public boolean isCongruentType(Object value, Object mask) {
+        // Mask type has to match value type
+        if (mask != null && (mask.getClass() != value.getClass())) {
+            return false;
+        }
+
+        Class<?> e = this.dataType();
+        Class<?> g = value.getClass();
+
+        // This is all what we need, if value type is same of match required type
+        if (g.equals(e)) {
+            return true;
+        }
+
+        // This is for the numeric class vs primitive congruence
+        // For what concerns here, for instance, Integer is congruent to int
+        if (e == Short.class) {
+            return g.equals(short.class);
+        }
+
+        if (e == Integer.class) {
+            return g.equals(int.class);
+        }
+
+        if (e == Byte.class) {
+            return g.equals(byte.class);
+        }
+
+        if (e == Byte[].class) {
+            return g.equals(byte[].class);
+        }
+
+        if (e == InetAddress.class) {
+            return g.getSuperclass().equals(InetAddress.class);
+        }
+        return false;
+    }
+
+    /**
+     * Perform the value and mask range validation
+     * @param value
+     * @param mask
+     * @return
+     */
+    public boolean isValid(Object value, Object mask) {
+        // Skip if main error
+        if (mask != null && (mask.getClass() != value.getClass())) {
+            return false;
+        }
+        // For the complex below types let's skip the value range check for now
+        if (this.dataType == InetAddress.class) {
+            return true;
+        }
+        if (this.dataType() == Byte[].class) {
+            return true;
+        }
+        if (this.dataType() == NodeConnector.class) {
+            return true;
+        }
+
+        int val = 0;
+        int msk = 0;
+        if (value.getClass() == Integer.class || value.getClass() == int.class) {
+            val = ((Integer) value).intValue();
+            msk = (mask != null) ? ((Integer) mask).intValue() : 0;
+
+        } else if (value.getClass() == Short.class
+                || value.getClass() == short.class) {
+            val = ((Short) value).intValue() & 0xffff;
+            msk = (mask != null) ? ((Short) mask).intValue() & 0xffff : 0;
+
+        } else if (value.getClass() == Byte.class
+                || value.getClass() == byte.class) {
+            val = ((Byte) value).intValue() & 0xff;
+            msk = (mask != null) ? ((Byte) mask).intValue() & 0xff : 0;
+        }
+        return ((val >= minValue && val <= maxValue) && (mask == null || (msk >= minValue && msk <= maxValue)));
+
+    }
+
+    /**
+     * Return the mask value in 64 bits bitmask form
+     * @param mask
+     * @return
+     */
+    public long getBitMask(Object mask) {
+        if (this.dataType == InetAddress.class) {
+            //TODO handle Inet v4 and v6 v6 will have a second upper mask
+            return 0;
+        }
+        if (this.dataType() == Byte[].class) {
+            if (mask == null) {
+                return 0xffffffffffffL;
+            }
+            byte mac[] = (byte[]) mask;
+            long bitmask = 0;
+            for (short i = 0; i < 6; i++) {
+                //                             bitmask |= (((long)mac[i] & 0xffL) << (long)((5-i)*8));
+                bitmask |= (((long) mac[i] & 0xffL) << ((5 - i) * 8));
+            }
+            return bitmask;
+        }
+        if (this.dataType == Integer.class || this.dataType == int.class) {
+            return (mask == null) ? this.maxValue : ((Integer) mask)
+                    .longValue();
+
+        }
+        if (this.dataType == Short.class || this.dataType == short.class) {
+            return (mask == null) ? this.maxValue : ((Short) mask).longValue();
+        }
+        if (this.dataType == Byte.class || this.dataType == byte.class) {
+            return (mask == null) ? this.maxValue : ((Byte) mask).longValue();
+
+        }
+        return 0L;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/ARP.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/ARP.java
new file mode 100644 (file)
index 0000000..f3aa35f
--- /dev/null
@@ -0,0 +1,259 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+
+/**
+ * Class that represents the ARP packet objects
+ *
+ *
+ */
+
+public class ARP extends Packet {
+    private static final String HWTYPE = "HardwareType";
+    private static final String PTYPE = "ProtocolType";
+    private static final String HWADDRLENGTH = "HardwareAddressLength";
+    private static final String PADDRLENGTH = "ProtocolAddressLength";
+    private static final String OPCODE = "OpCode";
+    private static final String SENDERHWADDR = "SenderHardwareAddress";
+    private static final String SENDERPADDR = "SenderProtocolAddress";
+    private static final String TARGETHWADDR = "TargetHardwareAddress";
+    private static final String TARGETPADDR = "TargetProtocolAddress";
+
+    public static short HW_TYPE_ETHERNET = (short) 0x1;
+    public static short REQUEST = (short) 0x1;
+    public static short REPLY = (short) 0x2;
+
+    private static Map<String, Pair<Integer, Integer>> fieldCoordinates = new LinkedHashMap<String, Pair<Integer, Integer>>() {
+        private static final long serialVersionUID = 1L;
+        {
+            put(HWTYPE, new ImmutablePair<Integer, Integer>(0, 16));
+            put(PTYPE, new ImmutablePair<Integer, Integer>(16, 16));
+            put(HWADDRLENGTH, new ImmutablePair<Integer, Integer>(32, 8));
+            put(PADDRLENGTH, new ImmutablePair<Integer, Integer>(40, 8));
+            put(OPCODE, new ImmutablePair<Integer, Integer>(48, 16));
+            put(SENDERHWADDR, new ImmutablePair<Integer, Integer>(64, 48));
+            put(SENDERPADDR, new ImmutablePair<Integer, Integer>(112, 32));
+            put(TARGETHWADDR, new ImmutablePair<Integer, Integer>(144, 48));
+            put(TARGETPADDR, new ImmutablePair<Integer, Integer>(192, 32));
+
+        }
+    };
+    private Map<String, byte[]> fieldValues;
+
+    /**
+     * Default constructor that creates and sets the HashMap
+     */
+    public ARP() {
+        super();
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+    }
+
+    /**
+     * Constructor that sets the access level for the packet and
+     * creates and sets the HashMap
+     */
+    public ARP(boolean writeAccess) {
+        super(writeAccess);
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+    }
+
+    /**
+     * Gets the hardware type from the stored ARP header
+     * @return short - the hardwareType
+     */
+    public short getHardwareType() {
+        return (BitBufferHelper.getShort(fieldValues.get(HWTYPE)));
+
+    }
+
+    /**
+     * Gets the protocol type from the stored ARP header
+     * @return short - the protocolType
+     */
+    public short getProtocolType() {
+        return (BitBufferHelper.getShort(fieldValues.get(PTYPE)));
+    }
+
+    /**
+     * Gets the hardware address length from the stored ARP header
+     * @return byte - the protocolAddressLength
+     */
+    public byte getHardwareAddressLength() {
+        return (BitBufferHelper.getByte(fieldValues.get(HWADDRLENGTH)));
+    }
+
+    /**
+     * Get the protocol address length from Protocol header
+     * @return byte - the protocolAddressLength
+     */
+    public byte getProtocolAddressLength() {
+        return (BitBufferHelper.getByte(fieldValues.get(PADDRLENGTH)));
+    }
+
+    /**
+     * Gets the opCode from stored ARP header
+     * @param short - the opCode to set
+     */
+    public short getOpCode() {
+        return (BitBufferHelper.getShort(fieldValues.get(OPCODE)));
+    }
+
+    /**
+     * Gets the sender hardware address from the stored ARP header
+     * @return byte[] - the senderHardwareAddress
+     */
+    public byte[] getSenderHardwareAddress() {
+        return (fieldValues.get(SENDERHWADDR));
+    }
+
+    /**
+     * Gets the IP address from the stored ARP header
+     * @return byte[] - the senderProtocolAddress
+     */
+    public byte[] getSenderProtocolAddress() {
+        return (fieldValues.get(SENDERPADDR));
+    }
+
+    /**
+     * Gets the hardware address from the stored ARP header
+     * @return byte[] - the targetHardwareAddress
+     */
+    public byte[] getTargetHardwareAddress() {
+        return (fieldValues.get(TARGETHWADDR));
+    }
+
+    /**
+     * Sets the hardware Type for the current ARP object instance
+     * @param short - hardwareType the hardwareType to set
+     * @return ARP
+     */
+    public ARP setHardwareType(short hardwareType) {
+        byte[] hwType = BitBufferHelper.toByteArray(hardwareType);
+        fieldValues.put(HWTYPE, hwType);
+        return this;
+    }
+
+    /**
+     * Sets the protocol Type for the current ARP object instance
+     * @param short - the protocolType to set
+     * @return ARP
+     */
+    public ARP setProtocolType(short protocolType) {
+        byte[] protType = BitBufferHelper.toByteArray(protocolType);
+        fieldValues.put(PTYPE, protType);
+        return this;
+    }
+
+    /**
+     * Sets the hardware address length for the current ARP object instance
+     * @param byte - the hardwareAddressLength to set
+     * @return ARP
+     */
+    public ARP setHardwareAddressLength(byte hardwareAddressLength) {
+        byte[] hwAddressLength = BitBufferHelper
+                .toByteArray(hardwareAddressLength);
+        fieldValues.put(HWADDRLENGTH, hwAddressLength);
+        return this;
+    }
+
+    /**
+     * Sets the Protocol address for the current ARP object instance
+     * @param byte - the protocolAddressLength to set
+     * @return ARP
+     */
+    public ARP setProtocolAddressLength(byte protocolAddressLength) {
+        byte[] protocolAddrLength = BitBufferHelper
+                .toByteArray(protocolAddressLength);
+        fieldValues.put(PADDRLENGTH, protocolAddrLength);
+        return this;
+    }
+
+    /**
+     * Sets the opCode for the current ARP object instance
+     * @param short - the opCode to set
+     * @return ARP
+     */
+    public ARP setOpCode(short opCode) {
+        byte[] operationCode = BitBufferHelper.toByteArray(opCode);
+        fieldValues.put(OPCODE, operationCode);
+        return this;
+    }
+
+    /**
+     * Sets the sender hardware address for the current ARP object instance
+     * @param byte[] - the senderHardwareAddress to set
+     * @return ARP
+     */
+    public ARP setSenderHardwareAddress(byte[] senderHardwareAddress) {
+        fieldValues.put(SENDERHWADDR, senderHardwareAddress);
+        return this;
+    }
+
+    /**
+     * Sets the target hardware address for the current ARP object instance
+     * @param byte[] - the targetHardwareAddress to set
+     * @return ARP
+     */
+    public ARP setTargetHardwareAddress(byte[] targetHardwareAddress) {
+        fieldValues.put(TARGETHWADDR, targetHardwareAddress);
+        return this;
+    }
+
+    /**
+     * Sets the target protocol address for the current ARP object instance
+     * @param byte[] - the targetProtocolAddress to set
+     * @return ARP
+     */
+    public ARP setTargetProtocolAddress(byte[] targetProtocolAddress) {
+        fieldValues.put(TARGETPADDR, targetProtocolAddress);
+        return this;
+    }
+
+    /**
+     * Sets the sender protocol address for the current ARP object instance
+     * @param byte[] - senderIP
+     * @return ARP
+     */
+    public ARP setSenderProtocolAddress(byte[] senderIP) {
+        fieldValues.put(SENDERPADDR, senderIP);
+        return this;
+    }
+
+    /**
+     * Gets the target protocol address
+     * @return - byte[] targetProtocolAddress
+     */
+    public byte[] getTargetProtocolAddress() {
+        return fieldValues.get(TARGETPADDR);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/BitBufferHelper.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/BitBufferHelper.java
new file mode 100644 (file)
index 0000000..1c27292
--- /dev/null
@@ -0,0 +1,685 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ *
+ */
+package org.opendaylight.controller.sal.packet;
+
+import java.util.Arrays;
+
+import org.opendaylight.controller.sal.utils.NetUtils;
+
+/**
+ * BitBufferHelper class that provides utility methods to
+ * - fetch specific bits from a serialized stream of bits
+ * - convert bits to primitive data type - like short, int, long
+ * - store bits in specified location in stream of bits
+ * - convert primitive data types to stream of bits
+ *
+ *
+ */
+public abstract class BitBufferHelper {
+
+    public static long ByteMask = 0xFF;
+
+    // Getters
+    // data: array where data are stored
+    // startOffset: bit from where to start reading
+    // numBits: number of bits to read
+    // All this function return an exception if overflow or underflow
+
+    /**
+     * Returns the first byte from the byte array
+     * @param byte[] data
+     * @return byte value
+     */
+    public static byte getByte(byte[] data) {
+        if ((data.length * NetUtils.NumBitsInAByte) > Byte.SIZE) {
+            try {
+                throw new Exception(
+                        "Container is too small for the number of requested bits");
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return (data[0]);
+    }
+
+    /**
+     * Returns the short value for the byte array passed.
+     * Size of byte array is restricted to Short.SIZE
+     * @param byte[] data
+     * @return short value
+     */
+    public static short getShort(byte[] data) {
+        if (data.length > Short.SIZE) {
+            try {
+                throw new Exception(
+                        "Container is too small for the number of requested bits");
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return (short) toNumber(data);
+    }
+
+    /**
+     * Returns the int value for the byte array passed.
+     * Size of byte array is restricted to Integer.SIZE
+     * @param byte[] data
+     * @return int - the integer value of byte array
+     */
+    public static int getInt(byte[] data) {
+        if (data.length > Integer.SIZE) {
+            try {
+                throw new Exception(
+                        "Container is too small for the number of requested bits");
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return (int) toNumber(data);
+    }
+
+    /**
+     * Returns the long value for the byte array passed.
+     * Size of byte array is restricted to Long.SIZE
+     * @param byte[] data
+     * @return long - the integer value of byte array
+     */
+    public static long getLong(byte[] data) {
+        if (data.length > Long.SIZE) {
+            try {
+                throw new Exception(
+                        "Container is too small for the number of requested bits");
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return (long) toNumber(data);
+    }
+
+    /**
+     * Returns the short value for the last numBits of the byte array passed.
+     * Size of numBits is restricted to Short.SIZE
+     * @param byte[] data
+     * @param int - numBits
+     * @return short - the short value of byte array
+     * @throws Exception
+     */
+    public static short getShort(byte[] data, int numBits) throws Exception {
+        if (numBits > Short.SIZE) {
+            try {
+                throw new Exception(
+                        "Container is too small for the number of requested bits");
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        int startOffset = data.length * NetUtils.NumBitsInAByte - numBits;
+        return (short) toNumber(BitBufferHelper.getBits(data, startOffset,
+                numBits), numBits);
+    }
+
+    /**
+     * Returns the int value for the last numBits of the byte array passed.
+     * Size of numBits is restricted to Integer.SIZE
+     * @param byte[] data
+     * @param int - numBits
+     * @return int - the integer value of byte array
+     * @throws Exception
+     */
+    public static int getInt(byte[] data, int numBits) throws Exception {
+        if (numBits > Integer.SIZE) {
+            try {
+                throw new Exception(
+                        "Container is too small for the number of requiested bits");
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        int startOffset = data.length * NetUtils.NumBitsInAByte - numBits;
+        return (int) toNumber(BitBufferHelper.getBits(data, startOffset,
+                numBits), numBits);
+    }
+
+    /**
+     * Returns the long value for the last numBits of the byte array passed.
+     * Size of numBits is restricted to Long.SIZE
+     * @param byte[] data
+     * @param int - numBits
+     * @return long - the integer value of byte array
+     * @throws Exception
+     */
+
+    public static long getLong(byte[] data, int numBits) throws Exception {
+        if (numBits > Long.SIZE) {
+            try {
+                throw new Exception(
+                        "Container is too small for the number of requested bits");
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        if (numBits > data.length * NetUtils.NumBitsInAByte) {
+            try {
+                throw new Exception(
+                        "Trying to read more bits than contained in the data buffer");
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        int startOffset = data.length * NetUtils.NumBitsInAByte - numBits;
+        return toNumber(BitBufferHelper.getBits(data, startOffset, numBits),
+                numBits);
+    }
+
+    /**
+     * Reads the specified number of bits from the passed byte array
+     * starting to read from the specified offset
+     * The bits read are stored in a byte array which size is dictated
+     * by the number of bits to be stored.
+     * The bits are stored in the byte array LSB aligned.
+     *
+     * Ex.
+     * Read 7 bits at offset 10
+     * 0         9 10     16 17
+     * 0101000010 | 0000101 | 1111001010010101011
+     * will be returned as {0,0,0,0,0,1,0,1}
+     *
+     * @param byte[] data
+     * @param int startOffset - offset to start fetching bits from data from
+     * @param int numBits - number of bits to be fetched from data
+     * @return byte [] - LSB aligned bits
+     * @throws Exception
+     */
+    public static byte[] getBits(byte[] data, int startOffset, int numBits)
+            throws Exception {
+
+        int startByteOffset = 0;
+        int valfromcurr, valfromnext;
+        int extranumBits = numBits % NetUtils.NumBitsInAByte;
+        int extraOffsetBits = startOffset % NetUtils.NumBitsInAByte;
+        int numBytes = (numBits % NetUtils.NumBitsInAByte != 0) ? 1 + numBits
+                / NetUtils.NumBitsInAByte : numBits / NetUtils.NumBitsInAByte;
+        byte[] shiftedBytes = new byte[numBytes];
+        startByteOffset = startOffset / NetUtils.NumBitsInAByte;
+        byte[] bytes = new byte[numBytes];
+        if (numBits == 0)
+            return bytes;
+
+        checkExceptions(data, startOffset, numBits);
+
+        if (extraOffsetBits == 0) {
+            if (extranumBits == 0) {
+                System.arraycopy(data, startByteOffset, bytes, 0, numBytes);
+                return bytes;
+            } else {
+                System.arraycopy(data, startByteOffset, bytes, 0, numBytes - 1);
+                bytes[numBytes - 1] = (byte) ((int) data[startByteOffset
+                        + numBytes - 1] & getMSBMask(extranumBits));
+            }
+        } else {
+            int i;
+            for (i = 0; i < numBits / NetUtils.NumBitsInAByte; i++) {
+                // Reading Numbytes starting from offset
+                valfromcurr = (data[startByteOffset + i])
+                        & getLSBMask(NetUtils.NumBitsInAByte - extraOffsetBits);
+                valfromnext = (data[startByteOffset + i + 1])
+                        & getMSBMask(extraOffsetBits);
+                bytes[i] = (byte) (valfromcurr << (extraOffsetBits) | (valfromnext >> (NetUtils.NumBitsInAByte - extraOffsetBits)));
+            }
+            // Now adding the rest of the bits if any
+            if (extranumBits != 0) {
+                if (extranumBits < (NetUtils.NumBitsInAByte - extraOffsetBits)) {
+                    valfromnext = (byte) (data[startByteOffset + i + 1] & ((getMSBMask(extranumBits)) >> extraOffsetBits));
+                    bytes[i] = (byte) (valfromnext << extraOffsetBits);
+                } else if (extranumBits == (NetUtils.NumBitsInAByte - extraOffsetBits)) {
+                    valfromcurr = (data[startByteOffset + i])
+                            & getLSBMask(NetUtils.NumBitsInAByte
+                                    - extraOffsetBits);
+                    bytes[i] = (byte) (valfromcurr << extraOffsetBits);
+                } else {
+                    valfromcurr = (data[startByteOffset + i])
+                            & getLSBMask(NetUtils.NumBitsInAByte
+                                    - extraOffsetBits);
+                    valfromnext = (data[startByteOffset + i + 1])
+                            & (getMSBMask(extranumBits
+                                    - (NetUtils.NumBitsInAByte - extraOffsetBits)));
+                    bytes[i] = (byte) (valfromcurr << (extraOffsetBits) | (valfromnext >> (NetUtils.NumBitsInAByte - extraOffsetBits)));
+                }
+
+            }
+        }
+        // Aligns the bits to LSB
+        shiftedBytes = shiftBitsToLSB(bytes, numBits);
+        return shiftedBytes;
+    }
+
+    // Setters
+    // data: array where data will be stored
+    // input: the data that need to be stored in the data array
+    // startOffset: bit from where to start writing
+    // numBits: number of bits to read
+
+    /**
+     * Bits are expected to be stored in the input byte array from LSB
+     * @param byte[] - data to set the input byte
+     * @param byte - input byte to be inserted
+     * @param startOffset - offset of data[] to start inserting byte from
+     * @param numBits - number of bits of input to be inserted into data[]
+     * @return void
+     * @throws Exception
+     */
+    public static void setByte(byte[] data, byte input, int startOffset,
+            int numBits) throws Exception {
+        byte[] inputByteArray = new byte[1];
+        Arrays.fill(inputByteArray, 0, 1, input);
+        setBytes(data, inputByteArray, startOffset, numBits);
+    }
+
+    /**
+     * Bits are expected to be stored in the input byte array from LSB
+     * @param byte[] - data to set the input byte
+     * @param byte[] - input bytes to be inserted
+     * @param startOffset - offset of data[] to start inserting byte from
+     * @param numBits - number of bits of input to be inserted into data[]
+     * @return void
+     * @throws Exception
+     */
+    public static void setBytes(byte[] data, byte[] input, int startOffset,
+            int numBits) throws Exception {
+        checkExceptions(data, startOffset, numBits);
+        insertBits(data, input, startOffset, numBits);
+    }
+
+    /**
+     * Returns numBits 1's in the MSB position
+     * @param numBits
+     * @return
+     */
+    public static int getMSBMask(int numBits) {
+        int mask = 0;
+        for (int i = 0; i < numBits; i++) {
+            mask = mask | (1 << (7 - i));
+        }
+        return mask;
+    }
+
+    /**
+     * Returns numBits 1's in the LSB position
+     * @param numBits
+     * @return
+     */
+    public static int getLSBMask(int numBits) {
+        int mask = 0;
+        for (int i = 0; i < numBits; i++) {
+            mask = mask | (1 << i);
+        }
+        return mask;
+    }
+
+    /**
+     * Returns the numerical value of the byte array passed
+     * @param byte[] - array
+     * @return long - numerical value of byte array passed
+     */
+    static public long toNumber(byte[] array) {
+        long ret = 0;
+        long length = array.length;
+        int value = 0;
+        for (int i = 0; i < length; i++) {
+            value = array[i];
+            if (value < 0)
+                value += 256;
+            ret = ret
+                    | (long) ((long) value << ((length - i - 1) * NetUtils.NumBitsInAByte));
+        }
+        return ret;
+    }
+
+    /**
+     * Returns the numerical value of the last numBits (LSB bits)
+     * of the byte array passed
+     * @param byte[] - array
+     * @param int - numBits
+     * @return long - numerical value of byte array passed
+     */
+    static public long toNumber(byte[] array, int numBits) {
+        int length = numBits / NetUtils.NumBitsInAByte;
+        int bitsRest = numBits % NetUtils.NumBitsInAByte;
+        int startOffset = array.length - length;
+        long ret = 0;
+        int value = 0;
+
+        value = array[startOffset - 1] & getLSBMask(bitsRest);
+        value = (array[startOffset - 1] < 0) ? (array[startOffset - 1] + 256)
+                : array[startOffset - 1];
+        ret = ret
+                | (value << ((array.length - startOffset) * NetUtils.NumBitsInAByte));
+
+        for (int i = startOffset; i < array.length; i++) {
+            value = array[i];
+            if (value < 0)
+                value += 256;
+            ret = ret
+                    | (long) ((long) value << ((array.length - i - 1) * NetUtils.NumBitsInAByte));
+        }
+
+        return ret;
+    }
+
+    /**
+     * Accepts a number as input and returns its value in byte form
+     * in LSB aligned form
+     * example:        input = 5000 [1001110001000]
+     *         bytes = 19, -120 [00010011] [10001000]
+     * @param Number
+     * @return byte[]
+     *
+     */
+
+    public static byte[] toByteArray(Number input) {
+        Class<? extends Number> dataType = input.getClass();
+        short size = 0;
+        long Lvalue = input.longValue();
+
+        if (dataType == Byte.class || dataType == byte.class)
+            size = Byte.SIZE;
+        else if (dataType == Short.class || dataType == short.class)
+            size = Short.SIZE;
+        else if (dataType == Integer.class || dataType == int.class)
+            size = Integer.SIZE;
+        else if (dataType == Long.class || dataType == long.class)
+            size = Long.SIZE;
+        else
+            throw new IllegalArgumentException(
+                    "Parameter must one of the following: Short/Int/Long\n");
+
+        int length = size / NetUtils.NumBitsInAByte;
+        byte bytes[] = new byte[length];
+
+        /*Getting the bytes from input value*/
+        for (int i = 0; i < length; i++) {
+            bytes[i] = (byte) ((Lvalue >> (NetUtils.NumBitsInAByte * (length
+                    - i - 1))) & ByteMask);
+        }
+        return bytes;
+    }
+
+    /**
+     * Accepts a number as input and returns its value in byte form
+     * in MSB aligned form
+     * example: input = 5000 [1001110001000]
+     *                 bytes = -114, 64 [10011100] [01000000]
+     * @param Number input
+     * @param int numBits - the number of bits to be returned
+     * @return byte[]
+     *
+     */
+    public static byte[] toByteArray(Number input, int numBits) {
+        Class<? extends Number> dataType = input.getClass();
+        short size = 0;
+        long Lvalue = input.longValue();
+
+        if (dataType == Short.class) {
+            size = Short.SIZE;
+        } else if (dataType == Integer.class) {
+            size = Integer.SIZE;
+        } else if (dataType == Long.class) {
+            size = Long.SIZE;
+        } else {
+            throw new IllegalArgumentException(
+                    "Parameter must one of the following: Short/Int/Long\n");
+        }
+
+        int length = size / NetUtils.NumBitsInAByte;
+        byte bytes[] = new byte[length];
+        byte[] inputbytes = new byte[length];
+        byte shiftedBytes[];
+
+        //Getting the bytes from input value
+        for (int i = 0; i < length; i++) {
+            bytes[i] = (byte) ((Lvalue >> (NetUtils.NumBitsInAByte * (length
+                    - i - 1))) & ByteMask);
+        }
+
+        if ((bytes[0] == 0 && dataType == Long.class)
+                || (bytes[0] == 0 && dataType == Integer.class)) {
+            int index = 0;
+            for (index = 0; index < length; ++index) {
+                if (bytes[index] != 0) {
+                    bytes[0] = bytes[index];
+                    break;
+                }
+            }
+            System.arraycopy(bytes, index, inputbytes, 0, length - index);
+            Arrays.fill(bytes, length - index + 1, length - 1, (byte) 0);
+        } else {
+            System.arraycopy(bytes, 0, inputbytes, 0, length);
+        }
+
+        shiftedBytes = shiftBitsToMSB(inputbytes, numBits);
+
+        return shiftedBytes;
+    }
+
+    /**
+     * Takes an LSB aligned byte array and returned the LSB numBits in a MSB aligned byte array
+     *
+     * @param inputbytes
+     * @param numBits
+     * @return
+     */
+    /**
+     * It aligns the last numBits bits to the head of the byte array
+     * following them with numBits % 8 zero bits.
+     *
+     * Example:
+     * For inputbytes = [00000111][01110001] and numBits = 12 it returns:
+     *     shiftedBytes = [01110111][00010000]
+     *
+     * @param byte[] inputBytes
+     * @param int numBits - number of bits to be left aligned
+     * @return byte[]
+     */
+    public static byte[] shiftBitsToMSB(byte[] inputBytes, int numBits) {
+        int numBitstoShiftBy = 0, leadZeroesMSB = 8, numEndRestBits = 0;
+        int size = inputBytes.length;
+        byte[] shiftedBytes = new byte[size];
+        int i;
+
+        for (i = 0; i < Byte.SIZE; i++) {
+            if (((byte) (inputBytes[0] & getMSBMask(i + 1))) != 0) {
+                leadZeroesMSB = i;
+                break;
+            }
+        }
+
+        if (numBits % NetUtils.NumBitsInAByte == 0)
+            numBitstoShiftBy = 0;
+        else
+            numBitstoShiftBy = ((NetUtils.NumBitsInAByte - (numBits % NetUtils.NumBitsInAByte)) < leadZeroesMSB) ? (NetUtils.NumBitsInAByte - (numBits % NetUtils.NumBitsInAByte))
+                    : leadZeroesMSB;
+
+        if (numBitstoShiftBy == 0)
+            return inputBytes;
+
+        if (numBits < NetUtils.NumBitsInAByte) { //inputbytes.length = 1 OR Read less than a byte
+            shiftedBytes[0] = (byte) ((inputBytes[0] & getLSBMask(numBits)) << numBitstoShiftBy);
+        } else {
+            numEndRestBits = NetUtils.NumBitsInAByte
+                    - (inputBytes.length * NetUtils.NumBitsInAByte - numBits - numBitstoShiftBy); //# of bits to read from last byte
+            for (i = 0; i < (size - 1); i++) {
+                if ((i + 1) == (size - 1)) {
+                    if (numEndRestBits > numBitstoShiftBy) {
+                        shiftedBytes[i] = (byte) ((inputBytes[i] << numBitstoShiftBy) | ((inputBytes[i + 1] & getMSBMask(numBitstoShiftBy)) >> (numEndRestBits - numBitstoShiftBy)));
+                        shiftedBytes[i + 1] = (byte) ((inputBytes[i + 1] & getLSBMask(numEndRestBits
+                                - numBitstoShiftBy)) << numBitstoShiftBy);
+                    } else
+                        shiftedBytes[i] = (byte) ((inputBytes[i] << numBitstoShiftBy) | ((inputBytes[i + 1] & getMSBMask(numEndRestBits)) >> (NetUtils.NumBitsInAByte - numEndRestBits)));
+                }
+                shiftedBytes[i] = (byte) ((inputBytes[i] << numBitstoShiftBy) | (inputBytes[i + 1] & getMSBMask(numBitstoShiftBy)) >> (NetUtils.NumBitsInAByte - numBitstoShiftBy));
+            }
+
+        }
+        return shiftedBytes;
+    }
+
+    /**
+     * It aligns the first numBits bits to the right end of the byte array
+     * preceding them with numBits % 8 zero bits.
+     *
+     * Example:
+     * For inputbytes = [01110111][00010000] and numBits = 12 it returns:
+     *     shiftedBytes = [00000111][01110001]
+     *
+     * @param byte[] inputBytes
+     * @param int numBits - number of bits to be right aligned
+     * @return byte[]
+     */
+    public static byte[] shiftBitsToLSB(byte[] inputBytes, int numBits) {
+        int numBytes = inputBytes.length;
+        int numBitstoShift = numBits % NetUtils.NumBitsInAByte;
+        byte[] shiftedBytes = new byte[numBytes];
+        int inputLsb = 0, inputMsb = 0;
+
+        if (numBitstoShift == 0)
+            return inputBytes;
+
+        for (int i = 1; i < numBytes; i++) {
+            inputLsb = inputBytes[i - 1]
+                    & getLSBMask(NetUtils.NumBitsInAByte - numBitstoShift);
+            inputLsb = (inputLsb < 0) ? (inputLsb + 256) : inputLsb;
+            inputMsb = inputBytes[i] & getMSBMask(numBitstoShift);
+            inputMsb = (inputBytes[i] < 0) ? (inputBytes[i] + 256)
+                    : inputBytes[i];
+            shiftedBytes[i] = (byte) ((inputLsb << numBitstoShift) | (inputMsb >> (NetUtils.NumBitsInAByte - numBitstoShift)));
+        }
+        inputMsb = inputBytes[0] & (getMSBMask(numBitstoShift));
+        inputMsb = (inputMsb < 0) ? (inputMsb + 256) : inputMsb;
+        shiftedBytes[0] = (byte) (inputMsb >> (NetUtils.NumBitsInAByte - numBitstoShift));
+        return shiftedBytes;
+    }
+
+    /**
+     * Insert in the data buffer at position dictated by the offset the number
+     * of bits specified from the input data byte array.
+     * The input byte array has the bits stored starting from the LSB
+     *
+     * @param byte[] data
+     * @param byte[] inputdata
+     * @param int startOffset
+     * @param int numBits
+     * @return void
+     */
+    public static void insertBits(byte[] data, byte[] inputdataLSB,
+            int startOffset, int numBits) {
+        byte[] inputdata = shiftBitsToMSB(inputdataLSB, numBits); // Align to MSB the passed byte array
+        int numBytes = numBits / NetUtils.NumBitsInAByte;
+        int startByteOffset = startOffset / NetUtils.NumBitsInAByte;
+        int extraOffsetBits = startOffset % NetUtils.NumBitsInAByte;
+        int extranumBits = numBits % NetUtils.NumBitsInAByte;
+        int RestBits = numBits % NetUtils.NumBitsInAByte;
+        int InputMSBbits = 0, InputLSBbits = 0;
+        int i;
+
+        if (numBits == 0)
+            return;
+
+        if (extraOffsetBits == 0) {
+            if (extranumBits == 0) {
+                numBytes = numBits / NetUtils.NumBitsInAByte;
+                System.arraycopy(inputdata, 0, data, startByteOffset, numBytes);
+            } else {
+                System.arraycopy(inputdata, 0, data, startByteOffset, numBytes);
+                data[startByteOffset + numBytes] = (byte) (data[startByteOffset
+                        + numBytes] | (inputdata[numBytes] & getMSBMask(extranumBits)));
+            }
+        } else {
+            for (i = 0; i < numBytes; i++) {
+                if (i != 0)
+                    InputLSBbits = (inputdata[i - 1] & getLSBMask(extraOffsetBits));
+                InputMSBbits = (byte) (inputdata[i] & (getMSBMask(NetUtils.NumBitsInAByte
+                        - extraOffsetBits)));
+                InputMSBbits = (InputMSBbits >= 0) ? InputMSBbits
+                        : InputMSBbits + 256;
+                data[startByteOffset + i] = (byte) (data[startByteOffset + i]
+                        | (InputLSBbits << (NetUtils.NumBitsInAByte - extraOffsetBits)) | (InputMSBbits >> extraOffsetBits));
+                InputMSBbits = InputLSBbits = 0;
+            }
+            if (RestBits < (NetUtils.NumBitsInAByte - extraOffsetBits)) {
+                if (numBytes != 0)
+                    InputLSBbits = (inputdata[i - 1] & getLSBMask(extraOffsetBits));
+                InputMSBbits = (byte) (inputdata[i] & (getMSBMask(RestBits)));
+                InputMSBbits = (InputMSBbits >= 0) ? InputMSBbits
+                        : InputMSBbits + 256;
+                data[startByteOffset + i] = (byte) ((data[startByteOffset + i])
+                        | (InputLSBbits << (NetUtils.NumBitsInAByte - extraOffsetBits)) | (InputMSBbits >> extraOffsetBits));
+            } else if (RestBits == (NetUtils.NumBitsInAByte - extraOffsetBits)) {
+                if (numBytes != 0)
+                    InputLSBbits = (inputdata[i - 1] & getLSBMask(extraOffsetBits));
+                InputMSBbits = (byte) (inputdata[i] & (getMSBMask(NetUtils.NumBitsInAByte
+                        - extraOffsetBits)));
+                InputMSBbits = (InputMSBbits >= 0) ? InputMSBbits
+                        : InputMSBbits + 256;
+                data[startByteOffset + i] = (byte) (data[startByteOffset + i]
+                        | (InputLSBbits << (NetUtils.NumBitsInAByte - extraOffsetBits)) | (InputMSBbits >> extraOffsetBits));
+            } else {
+                if (numBytes != 0)
+                    InputLSBbits = (inputdata[i - 1] & getLSBMask(extraOffsetBits));
+                InputMSBbits = (byte) (inputdata[i] & (getMSBMask(NetUtils.NumBitsInAByte
+                        - extraOffsetBits)));
+                InputMSBbits = (InputMSBbits >= 0) ? InputMSBbits
+                        : InputMSBbits + 256;
+                data[startByteOffset + i] = (byte) (data[startByteOffset + i]
+                        | (InputLSBbits << (NetUtils.NumBitsInAByte - extraOffsetBits)) | (InputMSBbits >> extraOffsetBits));
+
+                InputLSBbits = (inputdata[i] & (getLSBMask(RestBits
+                        - (NetUtils.NumBitsInAByte - extraOffsetBits)) << (NetUtils.NumBitsInAByte - RestBits)));
+                data[startByteOffset + i + 1] = (byte) (data[startByteOffset
+                        + i + 1] | (InputLSBbits << (NetUtils.NumBitsInAByte - extraOffsetBits)));
+            }
+        }
+    }
+
+    /**
+     * Checks for overflow and underflow exceptions
+     * @param data
+     * @param startOffset
+     * @param numBits
+     * @throws Exception
+     */
+    public static void checkExceptions(byte[] data, int startOffset, int numBits)
+            throws Exception {
+        int endOffsetByte;
+        int startByteOffset;
+        endOffsetByte = startOffset
+                / NetUtils.NumBitsInAByte
+                + numBits
+                / NetUtils.NumBitsInAByte
+                + ((numBits % NetUtils.NumBitsInAByte != 0) ? 1 : ((startOffset
+                        % NetUtils.NumBitsInAByte != 0) ? 1 : 0));
+        startByteOffset = startOffset / NetUtils.NumBitsInAByte;
+
+        if (data == null) {
+            throw new Exception("data[] is null\n");
+        }
+
+        if ((startOffset < 0) || (startByteOffset >= data.length)
+                || (endOffsetByte > data.length) || (numBits < 0)
+                || (numBits > NetUtils.NumBitsInAByte * data.length)) {
+            throw new Exception(
+                    "Illegal arguement/out of bound exception - data.length = "
+                            + data.length + " startOffset = " + startOffset
+                            + " numBits " + numBits);
+        }
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/Ethernet.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/Ethernet.java
new file mode 100644 (file)
index 0000000..0d866d6
--- /dev/null
@@ -0,0 +1,143 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.sal.utils.EtherTypes;
+
+/**
+ * Class that represents the Ethernet frame objects
+ *
+ *
+ */
+public class Ethernet extends Packet {
+    private static final String DMAC = "DestinationMACAddress";
+    private static final String SMAC = "SourceMACAddress";
+    private static final String ETHT = "EtherType";
+
+    // TODO: This has to be outside and it should be possible for osgi
+    // to add new coming packet classes
+    public static Map<Short, Class<? extends Packet>> etherTypeClassMap;
+    static {
+        etherTypeClassMap = new HashMap<Short, Class<? extends Packet>>();
+        etherTypeClassMap.put(EtherTypes.ARP.shortValue(), ARP.class);
+        etherTypeClassMap.put(EtherTypes.IPv4.shortValue(), IPv4.class);
+        etherTypeClassMap.put(EtherTypes.LLDP.shortValue(), LLDP.class);
+    }
+    private static Map<String, Pair<Integer, Integer>> fieldCoordinates = new LinkedHashMap<String, Pair<Integer, Integer>>() {
+        private static final long serialVersionUID = 1L;
+        {
+            put(DMAC, new ImmutablePair<Integer, Integer>(0, 48));
+            put(SMAC, new ImmutablePair<Integer, Integer>(48, 48));
+            put(ETHT, new ImmutablePair<Integer, Integer>(96, 16));
+        }
+    };
+    private Map<String, byte[]> fieldValues;
+
+    /**
+     * Default constructor that creates and sets the HashMap
+     */
+    public Ethernet() {
+        super();
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+    }
+
+    /**
+     * Constructor that sets the access level for the packet and
+     * creates and sets the HashMap
+     */
+    public Ethernet(boolean writeAccess) {
+        super(writeAccess);
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+    }
+
+    @Override
+    public void setHeaderField(String headerField, byte[] readValue) {
+        if (headerField.equals(ETHT)) {
+            payloadClass = etherTypeClassMap.get(BitBufferHelper
+                    .getShort(readValue));
+        }
+        hdrFieldsMap.put(headerField, readValue);
+    }
+
+    /**
+     * Gets the destination MAC address stored
+     * @return byte[] - the destinationMACAddress
+     */
+    public byte[] getDestinationMACAddress() {
+        return fieldValues.get(DMAC);
+    }
+
+    /**
+     * Gets the source MAC address stored
+     * @return byte[] - the sourceMACAddress
+     */
+    public byte[] getSourceMACAddress() {
+        return fieldValues.get(SMAC);
+    }
+
+    /**
+     * Gets the etherType stored
+     * @return short - the etherType
+     */
+    public short getEtherType() {
+        return BitBufferHelper.getShort(fieldValues.get(ETHT));
+    }
+
+    /**
+     * Sets the destination MAC address for the current Ethernet object instance
+     * @param byte[] - the destinationMACAddress to set
+     */
+    public Ethernet setDestinationMACAddress(byte[] destinationMACAddress) {
+        fieldValues.put(DMAC, destinationMACAddress);
+        return this;
+    }
+
+    /**
+     * Sets the source MAC address for the current Ethernet object instance
+     * @param byte[] - the sourceMACAddress to set
+     */
+    public Ethernet setSourceMACAddress(byte[] sourceMACAddress) {
+        fieldValues.put(SMAC, sourceMACAddress);
+        return this;
+    }
+
+    /**
+     * Sets the etherType for the current Ethernet object instance
+     * @param short - the etherType to set
+     */
+    public Ethernet setEtherType(short etherType) {
+        byte[] ethType = BitBufferHelper.toByteArray(etherType);
+        fieldValues.put(ETHT, ethType);
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/ICMP.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/ICMP.java
new file mode 100644 (file)
index 0000000..d1f81c5
--- /dev/null
@@ -0,0 +1,127 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+
+/**
+ * Class that represents the ICMP packet objects
+ *
+ *
+ */
+
+public class ICMP extends Packet {
+    private static final String TYPECODE = "TypeCode";
+    private static final String CODE = "Code";
+    private static final String HEADERCHECKSUM = "HeaderChecksum";
+    private static final String IDENTIFIER = "Identifier";
+    private static final String SEQNUMBER = "SequenceNumber";
+
+    private static Map<String, Pair<Integer, Integer>> fieldCoordinates = new LinkedHashMap<String, Pair<Integer, Integer>>() {
+        private static final long serialVersionUID = 1L;
+
+        {
+            put(TYPECODE, new ImmutablePair<Integer, Integer>(0, 8));
+            put(CODE, new ImmutablePair<Integer, Integer>(8, 8));
+            put(HEADERCHECKSUM, new ImmutablePair<Integer, Integer>(16, 16));
+            put(IDENTIFIER, new ImmutablePair<Integer, Integer>(32, 16));
+            put(SEQNUMBER, new ImmutablePair<Integer, Integer>(48, 16));
+
+        }
+    };
+
+    /**
+     * Default constructor that creates and sets the hash map values
+     */
+    public ICMP() {
+        super();
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+    }
+
+    /**
+     * Constructor that sets the access level for the packet
+     */
+    public ICMP(boolean writeAccess) {
+        super(writeAccess);
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+    }
+
+    private Map<String, byte[]> fieldValues;
+
+    @Override
+    public void setHeaderField(String headerField, byte[] readValue) {
+        hdrFieldsMap.put(headerField, readValue);
+    }
+
+    /**
+     * Sets the TypeCode of ICMP  for the current ICMP object instance
+     * @param short - typeCode
+     * @return ICMP
+     */
+    public ICMP setTypeCode(short typeCode) {
+        byte[] icmpTypeCode = BitBufferHelper.toByteArray(typeCode);
+        fieldValues.put(TYPECODE, icmpTypeCode);
+        return this;
+    }
+
+    /**
+     * Sets the ICMP checksum  for the current ICMP object instance
+     * @param short - checksum
+     * @return ICMP
+     */
+    public ICMP setChecksum(short checksum) {
+        byte[] icmpChecksum = BitBufferHelper.toByteArray(checksum);
+        fieldValues.put(HEADERCHECKSUM, icmpChecksum);
+        return this;
+    }
+
+    /**
+     * Sets the ICMP identifier  for the current ICMP object instance
+     * @param short - identifier
+     * @return ICMP
+     */
+    public ICMP setIdentifier(short identifier) {
+        byte[] icmpIdentifier = BitBufferHelper.toByteArray(identifier);
+        fieldValues.put(IDENTIFIER, icmpIdentifier);
+        return this;
+    }
+
+    /**
+     * Sets the ICMP sequence number for the current ICMP object instance
+     * @param short - seqNumber
+     * @return ICMP
+     */
+    public ICMP setSequenceNumber(short seqNumber) {
+        byte[] icmpSeqNumber = BitBufferHelper.toByteArray(seqNumber);
+        fieldValues.put(SEQNUMBER, icmpSeqNumber);
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IDataPacketService.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IDataPacketService.java
new file mode 100644 (file)
index 0000000..c430518
--- /dev/null
@@ -0,0 +1,49 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   IDataPacketService.java
+ *
+ * @brief  SAL exported Data Packet services
+ *
+ * Data Packet Services SAL provides to the components
+ */
+package org.opendaylight.controller.sal.packet;
+
+/**
+ * Data Packet Services SAL provides to the components
+ */
+public interface IDataPacketService {
+    /**
+     * Transmit a data Packet. Transmission will ONLY happen if the
+     * RawPacket has the OutgoingNodeConnector set else of course
+     * transmission cannot happen.
+     *
+     * @param outPkt Packet to be transmitted out
+     */
+    void transmitDataPacket(RawPacket outPkt);
+
+    /**
+     * Decode a Data Packet received as a raw stream
+     *
+     * @param pkt Raw Packet to be decoded
+     *
+     * @return The formatted Data Packet
+     */
+    Packet decodeDataPacket(RawPacket pkt);
+
+    /**
+     * Encode a Formatted Data Packet in a raw bytestream
+     *
+     * @param pkt Formatted Data Packet to be encoded
+     *
+     * @return a RawPacket representation, good for transmission purpose
+     */
+    RawPacket encodeDataPacket(Packet pkt);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IListenDataPacket.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IListenDataPacket.java
new file mode 100644 (file)
index 0000000..76e2a6f
--- /dev/null
@@ -0,0 +1,70 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   IListenDataPacket.java
+ *
+ * @brief  Interface a component will need to implement and export as
+ * implemented interface in order to get data packet
+ *
+ * Interface a component will need to implement and export as
+ * implemented interface in order to get data packet
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+/**
+ * Interface that all the components that want to receive a dataPacket
+ * need to implement. The interface by itself doesn't specify any
+ * filtering or sequencing mechanism, but the model supported by Data
+ * Packet Service is such that the packets can be processed in two
+ * ways:
+ * - Serial: When a Data Packet Listener gets a packet after another,
+ * this case is necessary when the subsequent handler needs some extra
+ * information that can only be provided by another Data Packet
+ * Service Handler. If the dependent service is missing, then the one
+ * with dependencies will not be invoked. In a serial
+ * processing, a plugin has the the power to prevent the packet to be
+ * seen but other in the chain, if the return result is CONSUMED, else
+ * the packet will go through all the elements in the chain.
+ * - Parallel: When a Data Packet Listener doesn't express any
+ * dependency then it will get a copy of the packet as anybody
+ * else. Practical example, let say we have 2 handlers, both didn't
+ * express any dependency then both will get a copy of any incoming
+ * packet and they cannot step over each other feet.
+ * The Processing model is choosen by the properties with which the
+ * service is registered in the OSGi service registry.
+ * The properties that will be looked at are:
+ * salListenerName: Unique identifier of the SAL Data Packet
+ * Listener
+ * salListenerDependency: A String containing the
+ * salListenerName that consitute a dependency for this Listener, for
+ * now ONLY a SINGLE dependency is supported
+ * salListenerFilter: A Match class to be used to match a DataPacket,
+ * processing either parallel or serial will ONLY continue if the
+ * incoming DataPacket match the filter. If no filter is provided, the
+ * handler is called for EVERY packet i.e. match All is implied!
+ */
+public interface IListenDataPacket {
+    /**
+     * Handler for receiving the packet. The application can signal
+     * back to SAL if the packet has been consumed or no. In case of
+     * packet consumed SAL will prevent to keep passing to subsequent
+     * listener in the serial chain, but for handlers without
+     * dependency things will keep going .
+     * The packet will received will have the IncomingNodeConnector
+     * set to understand where the packet is coming from
+     *
+     * @param inPkt Packet received
+     *
+     * @return An indication if the packet should still be processed
+     * or we should stop it.
+     */
+    PacketResult receiveDataPacket(RawPacket inPkt);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPluginInDataPacketService.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPluginInDataPacketService.java
new file mode 100644 (file)
index 0000000..8252715
--- /dev/null
@@ -0,0 +1,35 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   IPluginInDataPacketService.java
+ *
+ * @brief  Data Packet Services exported by SouthBound plugins for SAL usage
+ *
+ * Data Packet Services exported by SouthBound plugins for SAL usage
+ */
+package org.opendaylight.controller.sal.packet;
+
+/**
+ * Data Packet Services exported by SouthBound plugins for SAL usage.
+ * The service will be used by SAL such that for every Protocol Plugin
+ * there is only one expected, for this reason the service need to be
+ * registered in the OSGi service registry along with the property:
+ * - "protocoloPluginType"
+ * the value of the property will org.opendaylight.controller.sal.core.Node.NodeIDType
+ */
+public interface IPluginInDataPacketService {
+    /**
+     * Transmit a data Packet. Packet will go out ONLY if the packet
+     * has property OutgoingNodeConnector set.
+     *
+     * @param outPkt Packet to be transmitted out
+     */
+    void transmitDataPacket(RawPacket outPkt);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPluginOutDataPacketService.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPluginOutDataPacketService.java
new file mode 100644 (file)
index 0000000..10667fd
--- /dev/null
@@ -0,0 +1,42 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   IPluginOutDataPacketService.java
+ *
+ * @brief  Interface SAL will need to register in order to get some
+ * packets from the southbound protocol plugins
+ *
+ * Interface SAL will need to register in order to get some
+ * packets from the southbound protocol plugins
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+/**
+ * Interface used by SAL to intercept any Data Packet coming from the
+ * southbound protocol plugins
+ */
+public interface IPluginOutDataPacketService {
+    /**
+     * Handler for receiving the packet. The SAL layer can signal back
+     * to the southbound plugin if the packet has been consumed or can
+     * go for further processing. Usually after SAL processing
+     * probably there is no other processing to be done, but just in
+     * case there is chain the return code can be used.
+     * The protocol plugin is supposed to deliver a packet with the
+     * IncomingNodeConnector set
+     *
+     * @param inPkt Packet received
+     *
+     * @return An indication if the packet should still be processed
+     * or we should stop it.
+     */
+    PacketResult receiveDataPacket(RawPacket inPkt);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPv4.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPv4.java
new file mode 100644 (file)
index 0000000..b1fef8f
--- /dev/null
@@ -0,0 +1,551 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ *
+ */
+package org.opendaylight.controller.sal.packet;
+
+import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Random;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.sal.utils.IPProtocols;
+import org.opendaylight.controller.sal.utils.NetUtils;
+
+/**
+ * Class that represents the IPv4  packet objects
+ *
+ *
+ */
+
+public class IPv4 extends Packet {
+    private static final String VERSION = "Version";
+    private static final String HEADERLENGTH = "HeaderLength";
+    private static final String DIFFSERV = "DiffServ";
+    private static final String ECN = "ECN";
+    private static final String TOTLENGTH = "TotalLength";
+    private static final String IDENTIFICATION = "Identification";
+    private static final String FLAGS = "Flags";
+    private static final String FRAGOFFSET = "FragmentOffset";
+    private static final String TTL = "TTL";
+    private static final String PROTOCOL = "Protocol";
+    private static final String CHECKSUM = "Checksum";
+    private static final String SIP = "SourceIPAddress";
+    private static final String DIP = "DestinationIPAddress";
+    private static final String OPTIONS = "Options";
+
+    public static Map<Byte, Class<? extends Packet>> protocolClassMap;
+    static {
+        protocolClassMap = new HashMap<Byte, Class<? extends Packet>>();
+        protocolClassMap.put(IPProtocols.ICMP.byteValue(), ICMP.class);
+        protocolClassMap.put(IPProtocols.UDP.byteValue(), UDP.class);
+        protocolClassMap.put(IPProtocols.TCP.byteValue(), TCP.class);
+    }
+    private static Map<String, Pair<Integer, Integer>> fieldCoordinates = new LinkedHashMap<String, Pair<Integer, Integer>>() {
+        private static final long serialVersionUID = 1L;
+        {
+            put(VERSION, new ImmutablePair<Integer, Integer>(0, 4));
+            put(HEADERLENGTH, new ImmutablePair<Integer, Integer>(4, 4));
+            put(DIFFSERV, new ImmutablePair<Integer, Integer>(8, 6));
+            put(ECN, new ImmutablePair<Integer, Integer>(14, 2));
+            put(TOTLENGTH, new ImmutablePair<Integer, Integer>(16, 16));
+            put(IDENTIFICATION, new ImmutablePair<Integer, Integer>(32, 16));
+            put(FLAGS, new ImmutablePair<Integer, Integer>(48, 3));
+            put(FRAGOFFSET, new ImmutablePair<Integer, Integer>(51, 13));
+            put(TTL, new ImmutablePair<Integer, Integer>(64, 8));
+            put(PROTOCOL, new ImmutablePair<Integer, Integer>(72, 8));
+            put(CHECKSUM, new ImmutablePair<Integer, Integer>(80, 16));
+            put(SIP, new ImmutablePair<Integer, Integer>(96, 32));
+            put(DIP, new ImmutablePair<Integer, Integer>(128, 32));
+            put(OPTIONS, new ImmutablePair<Integer, Integer>(160, 0));
+        }
+    };
+
+    private Map<String, byte[]> fieldValues;
+
+    /**
+     * Default constructor that sets the version to 4, headerLength to 5,
+     * and flags to 2.  The default value for the identification is set to a
+     * random number and the remaining fields are set to 0.
+     */
+    public IPv4() {
+        super();
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+
+        setVersion((byte) 4);
+        setHeaderLength((byte) 5);
+        setDiffServ((byte) 0);
+        setIdentification(generateId());
+        setFlags((byte) 2);
+        setFragmentOffset((short) 0);
+        setECN((byte) 0);
+    }
+
+    /**
+     * The write access to the packet is set in this constructor.
+     * Constructor that sets the version to 4, headerLength to 5,
+     * and flags to 2.  The default value for the identification is set to a
+     * random number and the remaining fields are set to 0.
+     * @param boolean
+     */
+    public IPv4(boolean writeAccess) {
+        super(writeAccess);
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+
+        setVersion((byte) 4);
+        setHeaderLength((byte) 5);
+        setDiffServ((byte) 0);
+        setIdentification(generateId());
+        setFlags((byte) 2);
+        setFragmentOffset((short) 0);
+        setECN((byte) 0);
+    }
+
+    /**
+     * Gets the IP version stored
+     * @return the version
+     */
+    public byte getVersion() {
+        return (BitBufferHelper.getByte(fieldValues.get(VERSION)));
+    }
+
+    /**
+     * Gets the IP header length stored
+     * @return the headerLength in bytes
+     */
+    public int getHeaderLen() {
+        return (4 * BitBufferHelper.getByte(fieldValues.get(HEADERLENGTH)));
+    }
+
+    /**
+     * Gets the header length in bits, from the header length stored and options if any
+     * @return HeaderLength to serialize code
+     */
+    @Override
+    public int getHeaderSize() {
+        int headerLen = this.getHeaderLen();
+        if (headerLen == 0)
+            headerLen = 20;
+
+        byte[] options = hdrFieldsMap.get(OPTIONS);
+        if (options != null)
+            headerLen += options.length;
+
+        return headerLen * NetUtils.NumBitsInAByte;
+
+    }
+
+    /**
+     * Gets the differential services value stored
+     * @return the diffServ
+     */
+    public byte getDiffServ() {
+        return BitBufferHelper.getByte(fieldValues.get(DIFFSERV));
+    }
+
+    /**
+     * Gets the ecn bits stored
+     * @return the ecn bits
+     */
+    public byte getECN() {
+        return BitBufferHelper.getByte(fieldValues.get(ECN));
+    }
+
+    /**
+     * Gets the total length of the IP header in bytes
+     * @return the totalLength
+     */
+    public short getTotalLength() {
+        return (BitBufferHelper.getShort(fieldValues.get(TOTLENGTH)));
+    }
+
+    /**
+     * Gets the identification value stored
+     * @return the identification
+     */
+    public short getIdentification() {
+        return (BitBufferHelper.getShort(fieldValues.get(IDENTIFICATION)));
+    }
+
+    /**
+     * Gets the flag values stored
+     * @return the flags
+     */
+    public byte getFlags() {
+        return (BitBufferHelper.getByte(fieldValues.get(FLAGS)));
+    }
+
+    /**
+     * Gets the TTL value stored
+     * @return the ttl
+     */
+    public byte getTtl() {
+        return (BitBufferHelper.getByte(fieldValues.get(TTL)));
+    }
+
+    /**
+     * Gets the protocol value stored
+     * @return the protocol
+     */
+    public byte getProtocol() {
+        return (BitBufferHelper.getByte(fieldValues.get(PROTOCOL)));
+    }
+
+    /**
+     * Gets the checksum value stored
+     * @return the checksum
+     */
+    public short getChecksum() {
+        return (BitBufferHelper.getShort(fieldValues.get(CHECKSUM)));
+    }
+
+    /**
+     * Gets the fragment offset stored
+     * @return the fragmentOffset
+     */
+    public short getFragmentOffset() {
+        return (BitBufferHelper.getShort(fieldValues.get(FRAGOFFSET)));
+    }
+
+    /**
+     * Gets the source IP address stored
+     * @return the sourceAddress
+     */
+    public int getSourceAddress() {
+        return (BitBufferHelper.getInt(fieldValues.get(SIP)));
+    }
+
+    /**
+     * Gets the destination IP address stored
+     * @return the destinationAddress
+     */
+    public int getDestinationAddress() {
+        return (BitBufferHelper.getInt(fieldValues.get(DIP)));
+    }
+
+    /**
+     * gets the Options stored
+     * @return the options
+     */
+    public byte[] getOptions() {
+        return (fieldValues.get(OPTIONS));
+    }
+
+    @Override
+    /**
+     * Stores the value of fields read from data stream
+     * Variable header value like payload protocol, is stored here
+     */
+    public void setHeaderField(String headerField, byte[] readValue) {
+        if (headerField.equals(PROTOCOL)) {
+            payloadClass = protocolClassMap.get(readValue[0]);
+        }
+        hdrFieldsMap.put(headerField, readValue);
+    }
+
+    /**
+     * Stores the IP version from the header
+     * @param version the version to set
+     * @return @IPv4
+     */
+    public IPv4 setVersion(byte ipVersion) {
+        byte[] version = BitBufferHelper.toByteArray(ipVersion);
+        fieldValues.put(VERSION, version);
+        return this;
+    }
+
+    /**
+     * Stores the length of IP header in words (2 bytes)
+     * @param headerLength the headerLength to set
+     * @return IPv4
+     */
+    public IPv4 setHeaderLength(byte ipheaderLength) {
+        byte[] headerLength = BitBufferHelper.toByteArray(ipheaderLength);
+        fieldValues.put(HEADERLENGTH, headerLength);
+        return this;
+    }
+
+    /**
+     * Stores the differential services value from the IP header
+     * @param diffServ the diffServ to set
+     * @return IPv4
+     */
+    public IPv4 setDiffServ(byte ipdiffServ) {
+        byte[] diffServ = BitBufferHelper.toByteArray(ipdiffServ);
+        fieldValues.put(DIFFSERV, diffServ);
+        return this;
+    }
+
+    /**
+     * Stores the ECN bits from the header
+     * @param ECN bits to set
+     * @return IPv4
+     */
+    public IPv4 setECN(byte ecn) {
+        byte[] ecnbytes = BitBufferHelper.toByteArray(ecn);
+        fieldValues.put(ECN, ecnbytes);
+        return this;
+    }
+
+    /**
+     * Stores the total length of IP header in bytes
+     * @param totalLength the totalLength to set
+     * @return IPv4
+     */
+    public IPv4 setTotalLength(short iptotalLength) {
+        byte[] totalLength = BitBufferHelper.toByteArray(iptotalLength);
+        fieldValues.put(TOTLENGTH, totalLength);
+        return this;
+    }
+
+    /**
+     * Stores the identification number from the header
+     * @param identification the identification to set
+     * @return IPv4
+     */
+    public IPv4 setIdentification(short ipIdentification) {
+        byte[] identification = BitBufferHelper.toByteArray(ipIdentification);
+        fieldValues.put(IDENTIFICATION, identification);
+        return this;
+    }
+
+    /**
+     * Stores the IP flags value
+     * @param flags the flags to set
+     * @return IPv4
+     */
+    public IPv4 setFlags(byte ipFlags) {
+        byte[] flags = { ipFlags };
+        fieldValues.put(FLAGS, flags);
+        return this;
+    }
+
+    /**
+     * Stores the IP fragmentation offset value
+     * @param fragmentOffset the fragmentOffset to set
+     * @return IPv4
+     */
+    public IPv4 setFragmentOffset(short ipFragmentOffset) {
+        byte[] fragmentOffset = BitBufferHelper.toByteArray(ipFragmentOffset);
+        fieldValues.put(FRAGOFFSET, fragmentOffset);
+        return this;
+    }
+
+    /**
+     * Stores the TTL value
+     * @param ttl the ttl to set
+     * @return IPv4
+     */
+    public IPv4 setTtl(byte ipTtl) {
+        byte[] ttl = BitBufferHelper.toByteArray(ipTtl);
+        fieldValues.put(TTL, ttl);
+        return this;
+    }
+
+    /**
+     * Stores the protocol value of the IP payload
+     * @param protocol the protocol to set
+     * @return IPv4
+     */
+    public IPv4 setProtocol(byte ipProtocol) {
+        byte[] protocol = BitBufferHelper.toByteArray(ipProtocol);
+        fieldValues.put(PROTOCOL, protocol);
+        return this;
+    }
+
+    /**
+     * @param checksum the checksum to set
+     */
+    /*public IPv4 setChecksum() {
+       short ipChecksum = computeChecksum();
+        byte[] checksum = BitBufferHelper.toByteArray(ipChecksum);
+       fieldValues.put(CHECKSUM, checksum);
+        return this;
+    }*/
+
+    /**
+     * Stores the IP source address from the header
+     * @param sourceAddress the sourceAddress to set
+     * @return IPv4
+     */
+    public IPv4 setSourceAddress(InetAddress ipSourceAddress) {
+        byte[] sourceAddress = ipSourceAddress.getAddress();
+        fieldValues.put(SIP, sourceAddress);
+        return this;
+    }
+
+    /**
+     * Stores the IP destination address from the header
+     * @param the destination Address to set
+     * @return IPv4
+     */
+    public IPv4 setDestinationAddress(InetAddress ipDestinationAddress) {
+        byte[] sourceAddress = ipDestinationAddress.getAddress();
+        fieldValues.put(DIP, sourceAddress);
+        return this;
+    }
+
+    /**
+     * Stores the IP destination address from the header
+     * @param destinationAddress the destinationAddress to set
+     * @return IPv4
+     */
+    public IPv4 setDestinationAddress(int ipDestinationAddress) {
+        byte[] destinationAddress = BitBufferHelper
+                .toByteArray(ipDestinationAddress);
+        fieldValues.put(DIP, destinationAddress);
+        return this;
+    }
+
+    /**
+     * Generate a random number to set the Identification field
+     * in IPv4 Header
+     * @return short
+     */
+    private short generateId() {
+        Random randomgen = new Random();
+        return (short) (randomgen.nextInt(Short.MAX_VALUE + 1));
+    }
+
+    /**
+     * Store the options from IP header
+     * @param options - byte[]
+     * @return IPv4
+     */
+    public IPv4 setOptions(byte[] options) {
+        fieldValues.put(OPTIONS, options);
+        byte newIHL = (byte) (5 + options.length);
+        setHeaderLength(newIHL);
+
+        return this;
+    }
+
+    /**
+     * Computes the header checksum
+     * @param byte[] hdrBytes - serialized bytes
+     * @param int endBitOffset - end bit Offset
+     * @return short - the computed checksum
+     */
+    private short computeChecksum(byte[] hdrBytes, int endByteOffset) {
+        int startByteOffset = endByteOffset - getHeaderLen();
+        short checkSum = (short) 0;
+        int sum = 0, carry = 0, finalSum = 0;
+        int parsedHex = 0;
+        int checksumStartByte = startByteOffset + getfieldOffset(CHECKSUM)
+                / NetUtils.NumBitsInAByte;
+
+        for (int i = startByteOffset; i <= (endByteOffset - 1); i = i + 2) {
+            //Skip, if the current bytes are checkSum bytes
+            if (i == checksumStartByte)
+                continue;
+            StringBuffer sbuffer = new StringBuffer();
+            sbuffer.append(String.format("%02X", hdrBytes[i]));
+            if (i < (hdrBytes.length - 1))
+                sbuffer.append(String.format("%02X", hdrBytes[i + 1]));
+
+            parsedHex = Integer.valueOf(sbuffer.toString(), 16);
+            sum += parsedHex;
+        }
+        carry = (sum >> 16) & 0xFF;
+        finalSum = (sum & 0xFFFF) + carry;
+        checkSum = (short) ~((short) finalSum & 0xFFFF);
+        return checkSum;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    /**
+     * Gets the number of bits for the fieldname specified
+     * If the fieldname has variable length like "Options", then this value is computed using the
+     * options length and the header length
+     * @param fieldname - String
+     * @return number of bits for fieldname - int
+     */
+    public int getfieldnumBits(String fieldName) {
+        if (fieldName.equals(OPTIONS)) {
+            byte[] options = getOptions();
+            return ((options == null) ? 0 : (options.length - getHeaderLen()));
+        }
+        return (((Pair<Integer, Integer>) hdrFieldCoordMap.get(fieldName))
+                .getRight());
+    }
+
+    @Override
+    /**
+     * Method to perform post serialization - like computation of checksum of serialized header
+     * @param serializedBytes
+     * @return void
+     * @Exception throws exception
+     */
+    protected void postSerializeCustomOperation(byte[] serializedBytes)
+            throws Exception {
+        int startOffset = this.getfieldOffset(CHECKSUM);
+        int numBits = this.getfieldnumBits(CHECKSUM);
+        byte[] checkSum = BitBufferHelper.toByteArray(computeChecksum(
+                serializedBytes, serializedBytes.length));
+        BitBufferHelper.setBytes(serializedBytes, checkSum, startOffset,
+                numBits);
+        return;
+    }
+
+    @Override
+    /**
+     * Stores the payload of IP, serializes it and stores the length of serialized payload
+     * bytes in Total Length
+     * @param payload - Packet
+     */
+    public void setPayload(Packet payload) {
+        this.payload = payload;
+        /*
+         * Deriving the Total Lenght here
+         * TODO: See if we can derive the total length during
+         * another phase (during serialization/deserialization)
+         * */
+        int payloadLength = 0;
+        try {
+            payloadLength = payload.serialize().length;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        this.setTotalLength((short) (this.getHeaderLen() + payloadLength));
+    }
+
+    @Override
+    /**
+     * Method to perform post deserialization - like compare computed checksum with
+     * the one obtained from IP header
+     */
+    protected void postDeserializeCustomOperation(byte[] data, int endBitOffset) {
+        int endByteOffset = endBitOffset / NetUtils.NumBitsInAByte;
+        int computedChecksum = computeChecksum(data, endByteOffset);
+        int actualChecksum = BitBufferHelper.getInt(fieldValues.get(CHECKSUM));
+        if (computedChecksum != actualChecksum)
+            corrupted = true;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LLDP.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LLDP.java
new file mode 100644 (file)
index 0000000..420614f
--- /dev/null
@@ -0,0 +1,211 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import org.opendaylight.controller.sal.utils.NetUtils;
+
+/**
+ * Class that represents the LLDP frame objects
+ */
+
+public class LLDP extends Packet {
+       private static final String CHASSISID = "ChassisId";
+       private static final String PORTID = "PortId";
+       private static final String TTL = "TTL";
+       private static final int LLDPDefaultTlvs = 3;
+       private static LLDPTLV emptyTLV = new LLDPTLV().setLength((short)0).setType((byte)0);
+       public static final byte[] LLDPMulticastMac = {1,(byte)0x80,(byte)0xc2, 0, 0,(byte)0xe};
+       private Map<Byte, LLDPTLV> tlvList;
+
+       /**
+        * Default constructor that creates the tlvList LinkedHashMap
+        */
+       public LLDP() {
+               super();
+               tlvList = new LinkedHashMap<Byte,LLDPTLV>(LLDPDefaultTlvs);
+       }
+
+       /**
+        * Constructor that creates the tlvList LinkedHashMap and sets
+        * the write access for the same
+        */
+       public LLDP (boolean writeAccess) {
+               super(writeAccess);
+               tlvList = new LinkedHashMap<Byte,LLDPTLV>(LLDPDefaultTlvs);     // Mandatory TLVs       
+       }
+       
+       /**
+        * @param String - description of the type of TLV
+        * @return byte - type of TLV
+        */
+       private byte getType(String typeDesc) {
+               if (typeDesc.equals(CHASSISID)) {
+                       return LLDPTLV.TLVType.ChassisID.getValue();
+               } else if (typeDesc.equals(PORTID)) {
+                       return LLDPTLV.TLVType.PortID.getValue();
+               } else if (typeDesc.equals(TTL)) {
+                       return LLDPTLV.TLVType.TTL.getValue();
+               } else {
+                       return LLDPTLV.TLVType.Unknown.getValue();
+               }                       
+       }
+
+       /**
+        * @param String - description of the type of TLV
+        * @return LLDPTLV - full TLV
+        */
+    public LLDPTLV getTLV(String type) {
+       return tlvList.get(getType(type));
+    }
+
+       /**
+        * @param String - description of the type of TLV
+        * @param LLDPTLV - tlv to set
+        * @return void
+        */
+    public void setTLV(String type, LLDPTLV tlv) {
+       tlvList.put(getType(type), tlv);
+    }
+
+    /**
+     * @return the chassisId TLV
+     */
+    public LLDPTLV getChassisId() {
+       return getTLV(CHASSISID);
+    }
+
+    /**
+     * @param LLDPTLV - the chassisId to set
+     */
+    public LLDP setChassisId(LLDPTLV chassisId) {
+       tlvList.put(getType(CHASSISID), chassisId);
+        return this;
+    }
+    
+    /**
+     * @return LLDPTLV - the portId TLV
+     */
+    public LLDPTLV getPortId() {
+       return tlvList.get(getType(PORTID));
+    }
+
+    /**
+     * @param LLDPTLV - the portId to set
+     * @return LLDP
+     */
+    public LLDP setPortId(LLDPTLV portId) {
+       tlvList.put(getType(PORTID), portId);
+        return this;
+    }
+
+    /**
+     * @return LLDPTLV - the ttl TLV
+     */
+    public LLDPTLV getTtl() {
+       return tlvList.get(getType(TTL));
+    }
+
+    /**
+     * @param LLDPTLV - the ttl to set
+     * @return LLDP
+     */
+    public LLDP setTtl(LLDPTLV ttl) {
+       tlvList.put(getType(TTL), ttl);
+        return this;
+    }
+
+    /**
+     * @return the optionalTLVList
+     */
+    public List<LLDPTLV> getOptionalTLVList() {
+       List<LLDPTLV> list = new ArrayList<LLDPTLV>();
+       for (Map.Entry<Byte,LLDPTLV> entry : tlvList.entrySet()) {
+               byte type = entry.getKey();
+               if ((type == LLDPTLV.TLVType.ChassisID.getValue()) ||
+                       (type == LLDPTLV.TLVType.PortID.getValue()) ||
+                       (type == LLDPTLV.TLVType.TTL.getValue())) {
+                       continue;
+               } else {
+                       list.add(entry.getValue());
+               }
+       }
+        return list;
+    }
+
+    /**
+     * @param optionalTLVList the optionalTLVList to set
+     * @return LLDP
+     */
+    public LLDP setOptionalTLVList(List<LLDPTLV> optionalTLVList)
+    {
+       for (LLDPTLV tlv : optionalTLVList) {
+               tlvList.put(tlv.getType(), tlv);
+       }
+        return this;
+    }
+
+    @Override
+    public Packet deserialize (byte[] data, int bitOffset, int size) throws Exception {
+       int lldpOffset = bitOffset; // LLDP start 
+       int lldpSize = size; // LLDP size
+
+       /*
+        * Deserialize the TLVs until we reach the end of the packet
+        */
+       
+       while (lldpSize > 0) {
+               LLDPTLV tlv = new LLDPTLV();
+               tlv.deserialize(data, lldpOffset, lldpSize);
+               lldpOffset += tlv.getTLVSize(); //Size of current TLV in bits
+               lldpSize -= tlv.getTLVSize();
+               this.tlvList.put(tlv.getType(), tlv);
+       }
+               return this;
+       }
+    
+    @Override
+    public byte[] serialize() throws Exception {
+               int startOffset = 0;
+               byte[] serializedBytes = new byte[getLLDPPacketLength()];
+               
+               for (Map.Entry<Byte, LLDPTLV> entry : tlvList.entrySet()) {
+                       LLDPTLV tlv = entry.getValue();
+                       int numBits = tlv.getTLVSize();
+                       BitBufferHelper.setBytes(serializedBytes, tlv.serialize(), startOffset, numBits);
+                       startOffset += numBits;
+               }
+               // Now add the empty LLDPTLV at the end
+               BitBufferHelper.setBytes(serializedBytes, LLDP.emptyTLV.serialize(), startOffset, LLDP.emptyTLV.getTLVSize());
+               
+               return serializedBytes;
+    }
+    
+    /**
+     * Returns the size of LLDP packet in bytes
+     * @return int - LLDP Packet size in bytes
+     * @throws Exception 
+     */
+    private int getLLDPPacketLength() throws Exception {
+       int len = 0;
+       LLDPTLV tlv;
+       
+       for (Map.Entry<Byte, LLDPTLV> entry : this.tlvList.entrySet()) {
+               tlv = entry.getValue();
+               len += tlv.getTLVSize();
+       }
+       len += LLDP.emptyTLV.getTLVSize();
+       
+       return len/NetUtils.NumBitsInAByte;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LLDPTLV.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LLDPTLV.java
new file mode 100644 (file)
index 0000000..a89816f
--- /dev/null
@@ -0,0 +1,279 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.sal.utils.HexEncode;
+import org.opendaylight.controller.sal.utils.NetUtils;
+
+/**
+ * Class that represents the LLDPTLV objects
+ */
+
+public class LLDPTLV extends Packet {
+    private static final String TYPE = "Type";
+    private static final String LENGTH = "Length";
+    private static final String VALUE = "Value";
+    private static final int LLDPTLVFields = 3;
+       public static final byte[] OFOUI = new byte[] {(byte)0x00, (byte)0x26, (byte)0xe1};     // OpenFlow OUI
+       public static final byte[] customTlvSubType = new byte[] {0};
+       public static final int customTlvOffset = OFOUI.length + customTlvSubType.length;
+       public static final byte chassisIDSubType[] = new byte[] {4};   // MAC address for the system
+       public static final byte portIDSubType[] = new byte[] {7};      // locally assigned
+
+       public enum TLVType {
+               Unknown         ((byte)0),
+               ChassisID       ((byte)1),
+               PortID          ((byte)2),
+               TTL                     ((byte)3),
+               PortDesc        ((byte)4),
+               SystemName      ((byte)5),
+               SystemDesc      ((byte)6),
+               Custom          ((byte)127);
+               
+               private byte value;
+               private TLVType(byte value) {
+                       this.value = value;
+               }
+               public byte getValue() {
+                       return value;
+               }
+       }
+
+    private static Map<String, Pair<Integer, Integer>> fieldCoordinates = new LinkedHashMap<String, Pair<Integer, Integer>>() {
+        private static final long serialVersionUID = 1L;
+
+        {
+            put(TYPE, new MutablePair<Integer, Integer>(0, 7));
+            put(LENGTH, new MutablePair<Integer, Integer>(7, 9));
+            put(VALUE, new MutablePair<Integer, Integer>(16, 0));
+        }
+    };
+
+    protected Map<String, byte[]> fieldValues;
+
+    /**
+     * Default constructor that creates and sets the hash map values
+     * and sets the payload to null
+     */
+    public LLDPTLV() {
+        payload = null;
+        fieldValues = new HashMap<String, byte[]>(LLDPTLVFields);
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+    }
+
+    /**
+     * Constructor that writes the passed LLDPTLV values to the
+     * hdrFieldsMap
+     */
+    public LLDPTLV(LLDPTLV other) {
+        for (Map.Entry<String, byte[]> entry : other.hdrFieldsMap.entrySet()) {
+            this.hdrFieldsMap.put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    /**
+     * @return int - the length of TLV
+     */
+    public int getLength() {
+        return (int) BitBufferHelper.toNumber(fieldValues.get(LENGTH),
+                fieldCoordinates.get(LENGTH).getRight().intValue());
+    }
+
+    /**
+     * @return byte - the type of TLV
+     */
+    public byte getType() {
+        return BitBufferHelper.getByte(fieldValues.get(TYPE));
+    }
+
+    /**
+     * @return byte[] - the value field of TLV
+     */
+    public byte[] getValue() {
+        return fieldValues.get(VALUE);
+    }
+
+    /**
+     * @param byte - the type to set
+     * @return LLDPTLV
+     */
+    public LLDPTLV setType(byte type) {
+        byte[] lldpTLVtype = { type };
+        fieldValues.put(TYPE, lldpTLVtype);
+        return this;
+    }
+
+    /**
+     * @param short - the length to set
+     * @return LLDPTLV
+     */
+    public LLDPTLV setLength(short length) {
+        fieldValues.put(LENGTH, BitBufferHelper.toByteArray(length));
+        return this;
+    }
+
+    /**
+     * @param byte[] - the value to set
+     * @return LLDPTLV
+     */
+    public LLDPTLV setValue(byte[] value) {
+        fieldValues.put(VALUE, value);
+        return this;
+    }
+
+    @Override
+    public void setHeaderField(String headerField, byte[] readValue) {
+        hdrFieldsMap.put(headerField, readValue);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public int getfieldnumBits(String fieldName) throws Exception {
+        if (fieldName.equals(VALUE)) {
+            return (NetUtils.NumBitsInAByte * (int) BitBufferHelper.getShort(
+                    fieldValues.get(LENGTH), fieldCoordinates.get(LENGTH)
+                            .getRight().intValue()));
+        }
+        return fieldCoordinates.get(fieldName).getRight();
+    }
+
+    /**
+     * Returns the size in bits of the whole TLV
+     * @return int - size in bits of full TLV
+     * @throws Exception
+     */
+    public int getTLVSize() throws Exception {
+        return (LLDPTLV.fieldCoordinates.get(TYPE).getRight() + // static
+                LLDPTLV.fieldCoordinates.get(LENGTH).getRight() + // static
+        getfieldnumBits(VALUE)); // variable
+    }
+    
+    /**
+     * Creates the ChassisID TLV value including the subtype and ChassisID string
+     * 
+     * @param nodeId node identifier string
+     * @return the ChassisID TLV value in byte array
+     */
+    static public byte[] createChassisIDTLVValue(String nodeId) {
+        byte[] cid = HexEncode.bytesFromHexString(nodeId);
+        byte[] cidValue = new byte[cid.length + chassisIDSubType.length];
+
+        System.arraycopy(chassisIDSubType, 0, cidValue, 0, chassisIDSubType.length);
+        System.arraycopy(cid, 0, cidValue, chassisIDSubType.length, cid.length);
+
+       return cidValue;
+    }
+
+    /**
+     * Creates the PortID TLV value including the subtype and PortID string
+     * 
+     * @param portId port identifier string
+     * @return the PortID TLV value in byte array
+     */
+    static public byte[] createPortIDTLVValue(String portId) {
+        byte[] pid = portId.getBytes();
+        byte[] pidValue = new byte[pid.length + portIDSubType.length];
+
+        System.arraycopy(portIDSubType, 0, pidValue, 0, portIDSubType.length);
+        System.arraycopy(pid, 0, pidValue, portIDSubType.length, pid.length);
+
+       return pidValue;
+    }
+
+    /**
+     * Creates the custom TLV value including OUI, subtype and custom string
+     * 
+     * @param portId port identifier string
+     * @return the custom TLV value in byte array
+     */
+    static public byte[] createCustomTLVValue(String customString) {
+        byte[] customArray = customString.getBytes();
+        byte[] customValue = new byte[customTlvOffset + customArray.length];
+
+        System.arraycopy(OFOUI, 0, customValue, 0, OFOUI.length);
+        System.arraycopy(customTlvSubType, 0, customValue, OFOUI.length,
+                customTlvSubType.length);
+        System.arraycopy(customArray, 0, customValue, customTlvOffset,
+                customArray.length);
+
+       return customValue;
+    }
+
+    /**
+     * Retrieves the string from TLV value and returns it in HexString format
+     * 
+     * @param tlvValue the TLV value
+     * @param tlvLen the TLV length
+     * @return the HexString
+     */
+    static public String getHexStringValue(byte[] tlvValue, int tlvLen) {
+       byte[] cidBytes = new byte[tlvLen - chassisIDSubType.length];                
+        System.arraycopy(tlvValue, chassisIDSubType.length, cidBytes, 0, cidBytes.length);
+       return HexEncode.bytesToHexStringWithColumn(cidBytes);
+    }
+
+    /**
+     * Retrieves the string from TLV value
+     * 
+     * @param tlvValue the TLV value
+     * @param tlvLen the TLV length
+     * @return the string
+     */
+    static public String getStringValue(byte[] tlvValue, int tlvLen) {
+       byte[] pidBytes = new byte[tlvLen - portIDSubType.length];
+        System.arraycopy(tlvValue, portIDSubType.length, pidBytes, 0, pidBytes.length);
+       return (new String(pidBytes));
+    }
+
+    /**
+     * Retrieves the custom string from the Custom TLV value which includes OUI, subtype and custom string
+     * 
+     * @param customTlvValue the custom TLV value
+     * @param customTlvLen the custom TLV length
+     * @return the custom string
+     */
+    static public String getCustomString(byte[] customTlvValue, int customTlvLen) {
+        String customString = "";
+        byte[] vendor = new byte[3];
+        System.arraycopy(customTlvValue, 0, vendor, 0, vendor.length);
+        if (Arrays.equals(vendor, LLDPTLV.OFOUI)) {
+            int customArrayLength = customTlvLen - customTlvOffset;
+            byte[] customArray = new byte[customArrayLength];
+            System.arraycopy(customTlvValue, customTlvOffset,
+                    customArray, 0, customArrayLength);
+            try {
+               customString = new String(customArray, "UTF-8");
+            } catch (UnsupportedEncodingException e) {
+            }
+        }
+        
+       return customString;
+    }    
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LinkEncap.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LinkEncap.java
new file mode 100644 (file)
index 0000000..6d295dd
--- /dev/null
@@ -0,0 +1,24 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   LinkEncap.java
+ *
+ * @brief  Enum some datalink packet format understood
+ *
+ * Enum some datalink packet format understood
+ */
+package org.opendaylight.controller.sal.packet;
+
+/**
+ * Describe a packet data link format
+ */
+public enum LinkEncap {
+    ETHERNET
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/Packet.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/Packet.java
new file mode 100644 (file)
index 0000000..61d6d24
--- /dev/null
@@ -0,0 +1,281 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.sal.utils.HexEncode;
+import org.opendaylight.controller.sal.utils.NetUtils;
+
+/**
+ * Abstract class which represents the generic network packet object
+ * It provides the basic methods which are common for all the packets,
+ * like serialize and deserialize
+ *
+ *
+ */
+
+public abstract class Packet {
+    // Access level granted to this packet
+    protected boolean writeAccess;
+    // When deserialized from wire, packet could result corrupted
+    protected boolean corrupted;
+    // The packet that encapsulate this packet
+    protected Packet parent;
+    // The packet encapsulated by this packet
+    protected Packet payload;
+    // Bit coordinates of packet header fields
+    protected Map<String, Pair<Integer, Integer>> hdrFieldCoordMap;
+    // Header fields values: Map<FieldName,Value>
+    protected Map<String, byte[]> hdrFieldsMap;
+    // The class of the encapsulated packet object
+    protected Class<? extends Packet> payloadClass;
+
+    public Packet() {
+        writeAccess = false;
+        corrupted = false;
+    }
+
+    public Packet(boolean writeAccess) {
+        this.writeAccess = writeAccess;
+        this.corrupted = false;
+    }
+
+    public Packet getParent() {
+        return parent;
+    }
+
+    public Packet getPayload() {
+        return payload;
+    }
+
+    public void setParent(Packet parent) {
+        this.parent = parent;
+    }
+
+    public void setPayload(Packet payload) {
+        this.payload = payload;
+    }
+
+    public void setHeaderField(String headerField, byte[] readValue) {
+        hdrFieldsMap.put(headerField, readValue);
+    }
+
+    /**
+     * This method deserializes the data bits obtained from the wire
+     * into the respective header and payload which are of type Packet
+     * @param byte[] data - data from wire to deserialize
+     * @param int bitOffset bit position where packet header starts in data array
+     * @param int size of packet in bits
+     * @return Packet
+     * @throws Exception
+     */
+
+    public Packet deserialize(byte[] data, int bitOffset, int size)
+            throws Exception {
+        String hdrField;
+        Integer startOffset = 0, numBits = 0;
+        byte[] hdrFieldBytes;
+
+        for (Entry<String, Pair<Integer, Integer>> pairs : hdrFieldCoordMap
+                .entrySet()) {
+            hdrField = pairs.getKey();
+            startOffset = bitOffset + this.getfieldOffset(hdrField);
+            numBits = this.getfieldnumBits(hdrField);
+
+            hdrFieldBytes = BitBufferHelper.getBits(data, startOffset, numBits);
+            /*
+             * Store the raw read value, checks the payload type and
+             * set the payloadClass accordingly
+             */
+            this.setHeaderField(hdrField, hdrFieldBytes);
+        }
+
+        postDeserializeCustomOperation(data, startOffset);
+
+        int payloadStart = startOffset + numBits;
+        //int payloadSize = size - payloadStart;
+        int payloadSize = data.length * NetUtils.NumBitsInAByte - payloadStart;
+
+        if (payloadClass != null) {
+            try {
+                payload = payloadClass.newInstance();
+            } catch (Exception e) {
+                throw new RuntimeException(
+                        "Error parsing payload for Ethernet packet", e);
+            }
+            payload.deserialize(data, payloadStart, payloadSize);
+            payload.setParent(this);
+        } else {
+            // For now let's discard unparsable payload
+        }
+        return this;
+    }
+
+    /**
+     * This method serializes the header and payload bytes from
+     * the respective packet class, into a single stream of bytes
+     * to be sent on the wire
+     * @return byte[] - serialized bytes
+     * @throws Exception
+     */
+
+    public byte[] serialize() throws Exception {
+        byte[] payloadBytes = null;
+        int payloadSize = 0;
+        int headerSize = this.getHeaderSize();
+        int payloadByteOffset = headerSize / NetUtils.NumBitsInAByte;
+        int size = 0;
+
+        if (payload != null) {
+            payloadBytes = payload.serialize();
+            payloadSize = payloadBytes.length * NetUtils.NumBitsInAByte;
+        }
+
+        size = headerSize + payloadSize;
+        int length = size / NetUtils.NumBitsInAByte;
+        byte headerBytes[] = new byte[length];
+
+        if (payload != null) {
+            System.arraycopy(payloadBytes, 0, headerBytes, payloadByteOffset,
+                    payloadBytes.length);
+        }
+
+        String field;
+        byte[] fieldBytes;
+        Integer startOffset, numBits;
+
+        for (Map.Entry<String, Pair<Integer, Integer>> pairs : hdrFieldCoordMap
+                .entrySet()) {
+            field = pairs.getKey();
+            fieldBytes = hdrFieldsMap.get(field);
+            // Let's skip optional fields when not set
+            if (fieldBytes != null) {
+                startOffset = this.getfieldOffset(field);
+                numBits = this.getfieldnumBits(field);
+                BitBufferHelper.setBytes(headerBytes, fieldBytes, startOffset,
+                        numBits);
+            }
+        }
+        postSerializeCustomOperation(headerBytes);
+
+        return headerBytes;
+    }
+
+    /**
+     * This method gets called at the end of the serialization process
+     * It is intended for the child packets to insert some custom data
+     * into the output byte stream which cannot be done or cannot be done
+     * efficiently during the normal Packet.serialize() path.
+     * An example is the checksum computation for IPv4
+     * @param byte[] - serialized bytes
+     */
+    protected void postSerializeCustomOperation(byte[] myBytes)
+            throws Exception {
+        // no op
+    }
+
+    /**
+     * This method re-computes the checksum of the bits received on the
+     * wire and validates it with the checksum in the bits received
+     * Since the computation of checksum varies based on the protocol,
+     * this method is overridden
+     * Currently only IPv4 does checksum computation and validation
+     * TCP and UDP need to implement these if required
+     * @param byte[] data
+     * @param int endBitOffset
+     * @return void
+     */
+    protected void postDeserializeCustomOperation(byte[] data, int endBitOffset)
+            throws Exception {
+        //             no op
+    }
+
+    /**
+     * Gets the header length in bits
+     * @return int
+     * @throws Exception
+     */
+    public int getHeaderSize() throws Exception {
+        int size = 0;
+        /*
+         *  We need to iterate over the fields that were read in the frame (hdrFieldsMap)
+         *  not all the possible ones described in hdrFieldCoordMap.
+         *  For ex, 802.1Q may or may not be there
+         */
+        for (Map.Entry<String, byte[]> fieldEntry : hdrFieldsMap.entrySet()) {
+            if (fieldEntry.getValue() != null) {
+                String field = fieldEntry.getKey();
+                size += getfieldnumBits(field);
+            }
+        }
+        return size;
+    }
+
+    /**
+     * This method fetches the start bit offset for header field specified by
+     * 'fieldname'.  The offset is present in the hdrFieldCoordMap of the respective
+     * packet class
+     * @param String fieldName
+     * @return Integer - startOffset of the requested field
+     */
+    public int getfieldOffset(String fieldName) {
+        return (((Pair<Integer, Integer>) hdrFieldCoordMap.get(fieldName))
+                .getLeft());
+    }
+
+    /**
+     * This method fetches the number of bits for header field specified by
+     * 'fieldname'.  The numBits are present in the hdrFieldCoordMap of the respective
+     * packet class
+     * @param String fieldName
+     * @return Integer - number of bits of the requested field
+     */
+    public int getfieldnumBits(String fieldName) throws Exception {
+        return (((Pair<Integer, Integer>) hdrFieldCoordMap.get(fieldName))
+                .getRight());
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer ret = new StringBuffer();
+        for (Map.Entry<String, byte[]> entry : hdrFieldsMap.entrySet()) {
+            ret.append(entry.getKey() + ": ");
+            if (entry.getValue().length == 6) {
+                ret.append(HexEncode.bytesToHexString(entry.getValue()) + " ");
+            } else if (entry.getValue().length == 4) {
+                try {
+                    ret.append(InetAddress.getByAddress(entry.getValue())
+                            .getHostAddress()
+                            + " ");
+                } catch (UnknownHostException e) {
+                    e.printStackTrace();
+                }
+            } else {
+                ret.append(((Long) BitBufferHelper.getLong(entry.getValue()))
+                        .toString()
+                        + " ");
+            }
+        }
+        return ret.toString();
+    }
+
+    /**
+     * Returns true if the packet is corrupted
+     * @return boolean
+     */
+    protected boolean isPacketCorrupted() {
+        return corrupted;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/PacketResult.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/PacketResult.java
new file mode 100644 (file)
index 0000000..c292657
--- /dev/null
@@ -0,0 +1,40 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   PacketResult.java
+ *
+ * @brief  Possible results for Data packet processing handler
+ */
+package org.opendaylight.controller.sal.packet;
+
+/**
+ * Possible results for Data packet processing handler
+ *
+ */
+public enum PacketResult {
+    /**
+     * Packet has been processed and noone in the chain after us is
+     * supposed to see it
+     *
+     */
+    CONSUME,
+    /**
+     * Packet has been processed and still further processing is
+     * possible
+     *
+     */
+    KEEP_PROCESSING,
+    /**
+     * Packet has been ignored so further handler is present in
+     * the sequence need to still look at it.
+     *
+     */
+    IGNORED
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/RawPacket.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/RawPacket.java
new file mode 100644 (file)
index 0000000..00befde
--- /dev/null
@@ -0,0 +1,196 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   RawPacket.java
+ *
+ * @brief  Describe a raw Data Packet, this is how a packet is
+ * received from the network and how it will be transmitted. It
+ * essentially wraps the raw bytestream
+ *
+ */
+package org.opendaylight.controller.sal.packet;
+
+import java.util.Map;
+import java.util.HashMap;
+
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.TimeStamp;
+
+/**
+ *
+ * Describe a raw Data Packet, this is how a packet is
+ * received from the network and how it will be transmitted. It
+ * essentially wraps the raw bytestream
+ *
+ */
+public class RawPacket {
+    private byte[] packetData;
+    private LinkEncap encap;
+    private TimeStamp incomingTime;
+    private TimeStamp copyTime;
+    private Map props;
+    private NodeConnector incomingNodeConnector;
+    private NodeConnector outgoingNodeConnector;
+
+    /**
+     * If the packet is being sent this parameter tells where the
+     * packet is sent toward
+     *
+     *
+     * @return the NodeConnector toward where the packet is being sent
+     */
+    public NodeConnector getOutgoingNodeConnector() {
+        return outgoingNodeConnector;
+    }
+
+    /**
+     * Setter method for OutGoing NodeConnector
+     *
+     * @param outgoingNodeConnector NodeConnector toward where the
+     * packet is travelling
+     */
+    public void setOutgoingNodeConnector(NodeConnector outgoingNodeConnector) {
+        this.outgoingNodeConnector = outgoingNodeConnector;
+    }
+
+    /**
+     * Return the incoming NodeConnector if the packet was received
+     *
+     * @return NodeConnector where the packet was received from
+     */
+    public NodeConnector getIncomingNodeConnector() {
+        return incomingNodeConnector;
+    }
+
+    /**
+     * Setter for Incoming NodeConnector
+     *
+     * @param incomingNodeConnector NodeConnector to be used and incoming one
+     */
+    public void setIncomingNodeConnector(NodeConnector incomingNodeConnector) {
+        this.incomingNodeConnector = incomingNodeConnector;
+    }
+
+    /**
+     * Retrieve a given property attached to the packet, if exits of course
+     *
+     * @param key Key to retrieve the wanted property attached to the packet
+     *
+     * @return The property attached to the packet
+     */
+    public Object getProps(Object key) {
+        if (this.props != null) {
+            return this.props.get(key);
+        }
+        return null;
+    }
+
+    /**
+     * Generic data associated to the data packet
+     *
+     * @param key key for the association
+     * @param value value associated to the key
+     */
+    public void setProps(Object key, Object value) {
+        if (this.props == null) {
+            this.props = new HashMap();
+        }
+
+        this.props.put(key, value);
+    }
+
+    /**
+     * Constructor for RawPacket
+     *
+     * @param data content of the packet as bytestream
+     * @param e datalink encapsulation for the packet
+     *
+     */
+    public RawPacket(byte[] data, LinkEncap e) throws ConstructionException {
+        if (data == null) {
+            throw new ConstructionException("Empty data");
+        }
+        if (e == null) {
+            throw new ConstructionException("Encap not known");
+        }
+        this.packetData = new byte[data.length];
+        System.arraycopy(data, 0, this.packetData, 0, data.length);
+        this.encap = e;
+        this.incomingTime = new TimeStamp(System.currentTimeMillis(),
+                "IncomingTime");
+        this.copyTime = null;
+    }
+
+    /**
+     * Copy Constructor for RawPacket, it perform a copy of the packet
+     * so each packet can be modified indipendently without worrying
+     * that source packet content is touched
+     *
+     * @param src packet to copy data from
+     *
+     */
+    public RawPacket(RawPacket src) throws ConstructionException {
+        if (src == null) {
+            throw new ConstructionException("null source packet");
+        }
+        if (src.getPacketData() != null) {
+            this.packetData = new byte[src.getPacketData().length];
+            System.arraycopy(src.getPacketData(), 0, this.packetData, 0, src
+                    .getPacketData().length);
+        } else {
+            throw new ConstructionException("Empty packetData");
+        }
+        this.encap = src.getEncap();
+        this.incomingTime = src.getIncomingTime();
+        this.incomingNodeConnector = src.getIncomingNodeConnector();
+        this.outgoingNodeConnector = src.getOutgoingNodeConnector();
+        this.props = (src.props == null ? null : new HashMap(src.props));
+        this.copyTime = new TimeStamp(System.currentTimeMillis(), "CopyTime");
+    }
+
+    /**
+     * Constructor for RawPacket with Ethernet encapsulation
+     *
+     * @param data content of the packet as bytestream
+     *
+     */
+    public RawPacket(byte[] data) throws ConstructionException {
+        this(data, LinkEncap.ETHERNET);
+    }
+
+    /**
+     * Read the timestamp when the packet has entered the system
+     *
+     * @return The timestamp when the packet has entered the system
+     */
+    public TimeStamp getIncomingTime() {
+        return this.incomingTime;
+    }
+
+    /**
+     * Read the packet encapsulation
+     *
+     * @return The encapsulation for the raw packet, necessary to
+     * start parsing the packet
+     */
+    public LinkEncap getEncap() {
+        return this.encap;
+    }
+
+    /**
+     * Get bytestream of the packet body
+     *
+     * @return The raw bytestream composing the packet
+     */
+    public byte[] getPacketData() {
+        return this.packetData;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/TCP.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/TCP.java
new file mode 100644 (file)
index 0000000..ca4a871
--- /dev/null
@@ -0,0 +1,246 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+
+/**
+ * Class that represents the TCP segment objects
+ *
+ *
+ */
+public class TCP extends Packet {
+
+    private static final String SRCPORT = "SourcePort";
+    private static final String DESTPORT = "DestinationPort";
+    private static final String SEQNUMBER = "SequenceNumber";
+    private static final String ACKNUMBER = "AcknoledgementNumber";
+    private static final String DATAOFFSET = "DataOffset";
+    private static final String RESERVED = "Reserved";
+    private static final String HEADERLENFLAGS = "HeaderLenFlags";
+    private static final String WINDOWSIZE = "WindowSize";
+    private static final String CHECKSUM = "Checksum";
+    private static final String URGENTPOINTER = "UrgentPointer";
+
+    private static Map<String, Pair<Integer, Integer>> fieldCoordinates = new LinkedHashMap<String, Pair<Integer, Integer>>() {
+        private static final long serialVersionUID = 1L;
+        {
+            put(SRCPORT, new ImmutablePair<Integer, Integer>(0, 16));
+            put(DESTPORT, new ImmutablePair<Integer, Integer>(16, 16));
+            put(SEQNUMBER, new ImmutablePair<Integer, Integer>(32, 32));
+            put(ACKNUMBER, new ImmutablePair<Integer, Integer>(64, 32));
+            put(DATAOFFSET, new ImmutablePair<Integer, Integer>(96, 4));
+            put(RESERVED, new ImmutablePair<Integer, Integer>(100, 3));
+            put(HEADERLENFLAGS, new ImmutablePair<Integer, Integer>(103, 9));
+            put(WINDOWSIZE, new ImmutablePair<Integer, Integer>(112, 16));
+            put(CHECKSUM, new ImmutablePair<Integer, Integer>(128, 16));
+            put(URGENTPOINTER, new ImmutablePair<Integer, Integer>(144, 16));
+        }
+    };
+
+    private Map<String, byte[]> fieldValues;
+
+    /**
+     * Default constructor that sets all the header fields to zero
+     */
+    public TCP() {
+        super();
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+        /* Setting all remaining header field values to
+         * default value of 0.  These maybe changed as needed
+         */
+        setSourcePort((short) 0);
+        setDestinationPort((short) 0);
+        setSequenceNumber(0);
+        setAckNumber(0);
+        setDataOffset((byte) 0);
+        setReserved((byte) 0);
+        setWindowSize((short) 0);
+        setUrgentPointer((short) 0);
+        setChecksum((short) 0);
+    }
+
+    /**
+     * Constructor that sets the access level for the packet and
+     * sets all the header fields to zero.
+     */
+    public TCP(boolean writeAccess) {
+        super(writeAccess);
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+        /* Setting all remaining header field values to
+         * default value of 0.  These maybe changed as needed
+         */
+        setSourcePort((short) 0);
+        setDestinationPort((short) 0);
+        setSequenceNumber(0);
+        setAckNumber(0);
+        setDataOffset((byte) 0);
+        setReserved((byte) 0);
+        setWindowSize((short) 0);
+        setUrgentPointer((short) 0);
+        setChecksum((short) 0);
+    }
+
+    @Override
+    /**
+     * Stores the value read from data stream
+     */
+    public void setHeaderField(String headerField, byte[] readValue) {
+        hdrFieldsMap.put(headerField, readValue);
+    }
+
+    /**
+     * Sets the TCP source port for the current TCP object instance
+     * @param short tcpSourcePort
+     * @return TCP
+     */
+    public TCP setSourcePort(short tcpSourcePort) {
+        byte[] sourcePort = BitBufferHelper.toByteArray(tcpSourcePort);
+        fieldValues.put(SRCPORT, sourcePort);
+        return this;
+    }
+
+    /**
+     * Sets the TCP destination port for the current TCP object instance
+     * @param short tcpDestinationPort
+     * @return TCP
+     */
+    public TCP setDestinationPort(short tcpDestinationPort) {
+        byte[] destinationPort = BitBufferHelper
+                .toByteArray(tcpDestinationPort);
+        fieldValues.put(DESTPORT, destinationPort);
+        return this;
+    }
+
+    /**
+     * Sets the TCP sequence number for the current TCP object instance
+     * @param int tcpSequenceNumber
+     * @return TCP
+     */
+    public TCP setSequenceNumber(int tcpSequenceNumber) {
+        byte[] sequenceNumber = BitBufferHelper.toByteArray(tcpSequenceNumber);
+        fieldValues.put(SEQNUMBER, sequenceNumber);
+        return this;
+    }
+
+    /**
+     * Sets the TCP data offset for the current TCP object instance
+     * @param byte tcpDataOffset
+     * @return TCP
+     */
+    public TCP setDataOffset(byte tcpDataOffset) {
+        byte[] offset = BitBufferHelper.toByteArray(tcpDataOffset);
+        fieldValues.put("DataOffset", offset);
+        return this;
+    }
+
+    /**
+     * Sets the TCP reserved bits for the current TCP object instance
+     * @param byte tcpReserved
+     * @return TCP
+     */
+    public TCP setReserved(byte tcpReserved) {
+        byte[] reserved = BitBufferHelper.toByteArray(tcpReserved);
+        fieldValues.put("Reserved", reserved);
+        return this;
+    }
+
+    /**
+     * Sets the TCP Ack number for the current TCP object instance
+     * @param int tcpAckNumber
+     * @return TCP
+     */
+    public TCP setAckNumber(int tcpAckNumber) {
+        byte[] ackNumber = BitBufferHelper.toByteArray(tcpAckNumber);
+        fieldValues.put(ACKNUMBER, ackNumber);
+        return this;
+    }
+
+    /**
+     * Sets the TCP flags for the current TCP object instance
+     * @param short tcpFlags
+     * @return TCP
+     */
+    public TCP setHeaderLenFlags(short tcpFlags) {
+        byte[] headerLenFlags = BitBufferHelper.toByteArray(tcpFlags);
+        fieldValues.put(HEADERLENFLAGS, headerLenFlags);
+        return this;
+    }
+
+    /**
+     * Sets the TCP window size for the current TCP object instance
+     * @param short tcpWsize
+     * @return TCP
+     */
+    public TCP setWindowSize(short tcpWsize) {
+        byte[] wsize = BitBufferHelper.toByteArray(tcpWsize);
+        fieldValues.put(WINDOWSIZE, wsize);
+        return this;
+    }
+
+    /**
+     * Sets the TCP checksum for the current TCP object instance
+     * @param short tcpChecksum
+     * @return TCP
+     */
+    public TCP setChecksum(short tcpChecksum) {
+        byte[] checksum = BitBufferHelper.toByteArray(tcpChecksum);
+        fieldValues.put(CHECKSUM, checksum);
+        return this;
+    }
+
+    /**
+     * Sets the TCP Urgent Pointer for the current TCP object instance
+     * @param short tcpUrgentPointer
+     * @return TCP
+     */
+    public TCP setUrgentPointer(short tcpUrgentPointer) {
+        byte[] urgentPointer = BitBufferHelper.toByteArray(tcpUrgentPointer);
+        fieldValues.put(URGENTPOINTER, urgentPointer);
+        return this;
+    }
+
+    /**
+     * Gets the stored source port value of TCP header
+     * @return the sourcePort
+     */
+    public short getSourcePort() {
+        return (BitBufferHelper.getShort(fieldValues.get(SRCPORT)));
+    }
+
+    /**
+     * Gets the stored destination port value of TCP header
+     * @return the destinationPort
+     */
+    public short getDestinationPort() {
+        return (BitBufferHelper.getShort(fieldValues.get(DESTPORT)));
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/UDP.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/UDP.java
new file mode 100644 (file)
index 0000000..52827d5
--- /dev/null
@@ -0,0 +1,176 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+
+/**
+ * Class that represents the UDP datagram objects
+ *
+ *
+ */
+
+public class UDP extends Packet {
+
+    private static final String SRCPORT = "SourcePort";
+    private static final String DESTPORT = "DestinationPort";
+    private static final String LENGTH = "Length";
+    private static final String CHECKSUM = "Checksum";
+
+    private static Map<String, Pair<Integer, Integer>> fieldCoordinates = new LinkedHashMap<String, Pair<Integer, Integer>>() {
+        private static final long serialVersionUID = 1L;
+        {
+            put(SRCPORT, new ImmutablePair<Integer, Integer>(0, 16));
+            put(DESTPORT, new ImmutablePair<Integer, Integer>(16, 16));
+            put(LENGTH, new ImmutablePair<Integer, Integer>(32, 16));
+            put(CHECKSUM, new ImmutablePair<Integer, Integer>(48, 16));
+        }
+    };
+
+    public UDP() {
+        super();
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+        /* Setting all remaining header field values to
+         * default value of 0.  These maybe changed as needed
+         */
+        setSourcePort((short) 0);
+        setDestinationPort((short) 0);
+        setChecksum((short) 0);
+    }
+
+    public UDP(boolean writeAccess) {
+        super(writeAccess);
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+        /* Setting all remaining header field values to
+         * default value of 0.  These maybe changed as needed
+         */
+        setSourcePort((short) 0);
+        setDestinationPort((short) 0);
+        setChecksum((short) 0);
+    }
+
+    private Map<String, byte[]> fieldValues;
+
+    /* public static Map<Short, Class<? extends Packet>> decodeMap;
+
+      static {
+          decodeMap = new HashMap<Short, Class<? extends Packet>>();
+          UDP.decodeMap.put((short)67, DHCP.class);
+          UDP.decodeMap.put((short)68, DHCP.class);
+      }*/
+    /**
+     * Get the stored source port
+     * @return short - the sourcePort
+     */
+    public short getSourcePort() {
+        return (BitBufferHelper.getShort(fieldValues.get(SRCPORT)));
+    }
+
+    /**
+     * Get the stored destination port
+     * @return short - the destinationPort
+     */
+    public short getDestinationPort() {
+        return (BitBufferHelper.getShort(fieldValues.get(DESTPORT)));
+    }
+
+    /**
+     * Gets the stored length of UDP header
+     * @return short - the length
+     */
+    public short getLength() {
+        return (BitBufferHelper.getShort(fieldValues.get(LENGTH)));
+    }
+
+    /**
+     * Get the stored checksum value of the UDP header
+     * @return short - the checksum
+     */
+    public short getChecksum() {
+        return (BitBufferHelper.getShort(fieldValues.get(CHECKSUM)));
+    }
+
+    @Override
+    /**
+     * Store the value read from data stream in hdrFieldMap
+     */
+    public void setHeaderField(String headerField, byte[] readValue) {
+        /*if (headerField.equals("Protocol")) {
+               payloadClass = decodeMap.get(readValue);
+        }*/
+        hdrFieldsMap.put(headerField, readValue);
+    }
+
+    /**
+     * Sets the sourcePort value for the current UDP object instance
+     * @param short - the sourcePort to set
+     * @return UDP
+     */
+    public UDP setSourcePort(short udpSourcePort) {
+        byte[] sourcePort = BitBufferHelper.toByteArray(udpSourcePort);
+        fieldValues.put(SRCPORT, sourcePort);
+        return this;
+    }
+
+    /**
+     * Sets the destinationPort value for the current UDP object instance
+     * @param short - the destinationPort to set
+     * @return UDP
+     */
+    public UDP setDestinationPort(short udpDestinationPort) {
+        byte[] destinationPort = BitBufferHelper
+                .toByteArray(udpDestinationPort);
+        fieldValues.put(DESTPORT, destinationPort);
+        return this;
+    }
+
+    /**
+     * Set the UDP header length value for the current UDP object instance
+     * @param short - the length to set
+     * @return UDP
+     */
+    public UDP setLength(short udpLength) {
+        byte[] length = BitBufferHelper.toByteArray(udpLength);
+        fieldValues.put(LENGTH, length);
+        return this;
+    }
+
+    /**
+     * Set the checksum for the current UDP object instance
+     * @param short - the checksum to set
+     * @return UDP
+     */
+    public UDP setChecksum(short udpChecksum) {
+        byte[] checksum = BitBufferHelper.toByteArray(udpChecksum);
+        fieldValues.put(CHECKSUM, checksum);
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/address/DataLinkAddress.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/address/DataLinkAddress.java
new file mode 100644 (file)
index 0000000..433f64c
--- /dev/null
@@ -0,0 +1,87 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet.address;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
+
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+
+/**
+ * @file   DataLinkAddress.java
+ *
+ * @brief  Abstract base class for a Datalink Address
+ *
+ */
+
+/**
+ * Abstract base class for a Datalink Address
+ *
+ */
+@XmlRootElement
+@XmlSeeAlso( { EthernetAddress.class })
+abstract public class DataLinkAddress implements Serializable {
+    private static final long serialVersionUID = 1L;
+    private String name;
+
+    public DataLinkAddress() {
+
+    }
+
+    /**
+     * Constructor of super class
+     *
+     * @param name Create a new DataLink, not for general use but
+     * available only for sub classes
+     *
+     * @return constructed object
+     */
+    protected DataLinkAddress(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Used to copy the DataLinkAddress in a polymorphic way
+     *
+     *
+     * @return A clone of this DataLinkAddress
+     */
+    abstract public DataLinkAddress clone();
+
+    /**
+     * Allow to distinguish among different data link addresses
+     *
+     *
+     * @return Name of the DataLinkAdress we are working on
+     */
+    public String getName() {
+        return this.name;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "DataLinkAddress[" + ReflectionToStringBuilder.toString(this)
+                + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/address/EthernetAddress.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/address/EthernetAddress.java
new file mode 100644 (file)
index 0000000..57dea9c
--- /dev/null
@@ -0,0 +1,114 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet.address;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.utils.HexEncode;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class EthernetAddress extends DataLinkAddress {
+    private static final long serialVersionUID = 1L;
+    private byte[] macAddress;
+
+    public static final EthernetAddress BROADCASTMAC = createWellKnownAddress(new byte[] {
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+            (byte) 0xff });
+
+    public static final EthernetAddress INVALIDHOST = BROADCASTMAC;
+
+    public static final String addressName = "Ethernet MAC Address";
+    public static final int SIZE = 6;
+
+    private static final EthernetAddress createWellKnownAddress(byte[] mac) {
+        try {
+            return new EthernetAddress(mac);
+        } catch (ConstructionException ce) {
+            return null;
+        }
+    }
+
+    /* Private constructor to satisfy JAXB */
+    private EthernetAddress() {
+
+    }
+
+    /**
+     * Public constructor for an Ethernet MAC address starting from
+     * the byte constituing the address, the constructor validate the
+     * size of the arrive to make sure it met the expected size
+     *
+     * @param macAddress A byte array in big endian format
+     * representing the Ethernet MAC Address
+     *
+     * @return The constructed object if valid
+     */
+    public EthernetAddress(byte[] macAddress) throws ConstructionException {
+        super(addressName);
+
+        if (macAddress == null) {
+            throw new ConstructionException("Null input parameter passed");
+        }
+
+        if (macAddress.length != SIZE) {
+            throw new ConstructionException(
+                    "Wrong size of passed byte array, expected:" + SIZE
+                            + " got:" + macAddress.length);
+        }
+        this.macAddress = new byte[SIZE];
+        System.arraycopy(macAddress, 0, this.macAddress, 0, SIZE);
+    }
+
+    public EthernetAddress clone() {
+        try {
+            return new EthernetAddress(this.macAddress.clone());
+        } catch (ConstructionException ce) {
+            return null;
+        }
+    }
+
+    /**
+     * Return the Ethernet Mac address in byte array format
+     *
+     * @return The Ethernet Mac address in byte array format
+     */
+    public byte[] getValue() {
+        return this.macAddress;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public String toString() {
+        return "EthernetAddress[" + ReflectionToStringBuilder.toString(this)
+                + "]";
+    }
+
+    @XmlElement(name = "macAddress")
+    public String getMacAddress() {
+        return HexEncode.bytesToHexString(macAddress);
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/FlowOnNode.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/FlowOnNode.java
new file mode 100644 (file)
index 0000000..431f589
--- /dev/null
@@ -0,0 +1,119 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.reader;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.sal.flowprogrammer.Flow;
+
+/**
+ * Represents the flow that is installed on the network node
+ * along with the table location, hit counters and timers
+ */
+
+@XmlRootElement (name="FlowStat")
+@XmlAccessorType(XmlAccessType.NONE)
+public class FlowOnNode {
+    @XmlElement
+    private Flow flow; // Flow descriptor
+    @XmlElement
+    private byte tableId;
+    @XmlElement
+    private int durationSeconds;
+    @XmlElement
+    private int durationNanoseconds;
+    @XmlElement
+    private long packetCount;
+    @XmlElement
+    private long byteCount;
+
+    /* Dummy constructor for JAXB */
+    private FlowOnNode () {
+    }
+    
+    public FlowOnNode(Flow flow) {
+        this.flow = flow;
+    }
+
+    /**
+     * Returns the description of the flow which statistics are about
+     * @return
+     */
+    public Flow getFlow() {
+        return flow;
+    }
+
+    /**
+     * Set the packet count's value
+     * @param count
+     */
+    public void setPacketCount(long count) {
+        packetCount = count;
+    }
+
+    /**
+     * Set the byte count's value
+     * @param count
+     */
+    public void setByteCount(long count) {
+        byteCount = count;
+    }
+
+    /**
+     * Returns the packet count for the flow
+     * @return
+     */
+    public long getPacketCount() {
+        return packetCount;
+    }
+
+    /**
+     * Return the byte count for the flow
+     * @return
+     */
+    public long getByteCount() {
+        return byteCount;
+    }
+
+    public byte getTableId() {
+        return tableId;
+    }
+
+    public void setTableId(byte tableId) {
+        this.tableId = tableId;
+    }
+
+    public int getDurationSeconds() {
+        return durationSeconds;
+    }
+
+    public void setDurationSeconds(int durationSeconds) {
+        this.durationSeconds = durationSeconds;
+    }
+
+    public int getDurationNanoseconds() {
+        return durationNanoseconds;
+    }
+
+    public void setDurationNanoseconds(int durationNanoseconds) {
+        this.durationNanoseconds = durationNanoseconds;
+    }
+
+    @Override
+    public String toString() {
+        return "FlowOnNode[flow =" + flow + ", tableId = " + tableId
+                + ", sec = " + durationSeconds + ", nsec = "
+                + durationNanoseconds + ", pkt = " + packetCount + ", byte = "
+                + byteCount + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/IPluginInReadService.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/IPluginInReadService.java
new file mode 100644 (file)
index 0000000..c563037
--- /dev/null
@@ -0,0 +1,72 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.reader;
+
+import java.util.List;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.flowprogrammer.Flow;
+
+/**
+ * @file   IPluginInReadService.java
+ *
+ * @brief  Hardware view interface to be implemented by protocol plugins
+ *
+ *
+ *
+ */
+public interface IPluginInReadService {
+
+    /**
+     * Returns the hardware image for the specified flow on the specified network node
+     * @param node
+     * @param flow
+     * @return
+     */
+    public FlowOnNode readFlow(Node node, Flow flow, boolean cached);
+
+    /**
+     * Returns the hardware view of all the flow installed on the specified network node
+     * @param node
+     * @return
+     */
+    public List<FlowOnNode> readAllFlow(Node node, boolean cached);
+
+    /**
+     * Returns the description of the network node as provided by the node itself
+     * @param node
+     * @return
+     */
+    public NodeDescription readDescription(Node node, boolean cached);
+
+    /**
+     * Returns the hardware view of the specified network node connector
+     * @param node
+     * @return
+     */
+    public NodeConnectorStatistics readNodeConnector(NodeConnector connector,
+            boolean cached);
+
+    /**
+     * Returns the hardware info for all the node connectors on the specified network node
+     * @param node
+     * @return
+     */
+    public List<NodeConnectorStatistics> readAllNodeConnector(Node node,
+            boolean cached);
+
+    /**
+     * Returns the averaged transmit rate for the specified node connector
+     * @param connector
+     * @return tx rate [bps]
+     */
+    public long getTransmitRate(NodeConnector connector);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/IReadService.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/IReadService.java
new file mode 100644 (file)
index 0000000..3a9f828
--- /dev/null
@@ -0,0 +1,117 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.reader;
+
+import java.util.List;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.flowprogrammer.Flow;
+
+/**
+ * Interface for retrieving the network node's flow/port/queue hardware view
+ *
+ *
+ *
+ */
+public interface IReadService {
+    /**
+     * Get the hardware view for the specified flow on the specified network node
+     *
+     * @param node
+     * @param flow
+     */
+    FlowOnNode readFlow(Node node, Flow flow);
+
+    /**
+     * Get the hardware view for the specified flow on the specified network node
+     * This call results in a direct polling of the information from the node
+     * Caller will be blocked until node replies or request times out
+     *
+     * @param node
+     * @param flow
+     */
+    FlowOnNode nonCachedReadFlow(Node node, Flow flow);
+
+    /**
+     * Get the hardware view for all the flows installed on the network node
+     *
+     * @param node
+     * @return
+     */
+    List<FlowOnNode> readAllFlows(Node node);
+
+    /**
+     * Get the hardware view for all the flows installed on the network node
+     * This call results in a direct polling of the information from the node
+     * Caller will be blocked until node replies or request times out
+     *
+     * @param node
+     * @param flow
+     */
+    List<FlowOnNode> nonCachedReadAllFlows(Node node);
+
+    /**
+     * Get the description information for the network node
+     * @param node
+     * @return
+     */
+    NodeDescription readDescription(Node node);
+
+    /**
+     * Get the description information for the network node
+     * This call results in a direct polling of the information from the node
+     * Caller will be blocked until node replies or request times out
+     *
+     * @param node
+     * @return
+     */
+    NodeDescription nonCachedReadDescription(Node node);
+
+    /**
+     * Get the hardware view for the specified node connector
+     * @param connector
+     */
+    NodeConnectorStatistics readNodeConnector(NodeConnector connector);
+
+    /**
+     * Get the hardware view for all the node connectors
+     * present on the specified network node
+     * @param connector
+     */
+    List<NodeConnectorStatistics> readNodeConnectors(Node node);
+
+    /**
+     * Get the node connectors statistics information for the network node
+     * This call results in a direct polling of the information from the node
+     * Caller will be blocked until node replies or request times out
+     *
+     * @param node
+     * @return
+     */
+    List<NodeConnectorStatistics> nonCachedReadNodeConnectors(Node node);
+
+    /**
+     * Get the node connectors statistics information for the network node
+     *
+     * @param node
+     * @return
+     */
+    NodeConnectorStatistics nonCachedReadNodeConnector(NodeConnector connector);
+
+    /**
+     * Get the transmit rate for the specified node connector
+     *
+     * @param connector
+     * @return tx rate [bps]
+     */
+    long getTransmitRate(NodeConnector connector);
+
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/NodeConnectorStatistics.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/NodeConnectorStatistics.java
new file mode 100644 (file)
index 0000000..a8c83e7
--- /dev/null
@@ -0,0 +1,282 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.reader;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.sal.core.NodeConnector;
+
+/**
+ * Represents the statistics for the node conenctor
+ *
+ *
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NodeConnectorStatistics {
+       @XmlElement
+    private NodeConnector nodeConnector;
+       @XmlElement
+    private long receivePackets;
+       @XmlElement
+    private long transmitPackets;
+       @XmlElement
+    private long receiveBytes;
+       @XmlElement
+    private long transmitBytes;
+       @XmlElement
+    private long receiveDrops;
+       @XmlElement
+    private long transmitDrops;
+       @XmlElement
+    private long receiveErrors;
+       @XmlElement
+    private long transmitErrors;
+       @XmlElement
+    private long receiveFrameError;
+       @XmlElement
+    private long receiveOverRunError;
+       @XmlElement
+    private long receiveCrcError;
+       @XmlElement
+    private long collisionCount;
+
+       //To Satisfy JAXB
+       public NodeConnectorStatistics() {
+               
+       }
+    /**
+     * Set the node connector
+     * @param port
+     */
+    public void setNodeConnector(NodeConnector port) {
+        this.nodeConnector = port;
+    }
+
+    /**
+     * Returns the node connector
+     * @return
+     */
+    public NodeConnector getNodeConnector() {
+        return nodeConnector;
+    }
+
+    /**
+     * Set the rx packet count's value
+     * @param count
+     */
+    public void setReceivePacketCount(long count) {
+        receivePackets = count;
+    }
+
+    /**
+     * Returns the rx packet count for the port
+     * @return
+     */
+    public long getReceivePacketCount() {
+        return receivePackets;
+    }
+
+    /**
+     * Set the tx packet count's value
+     * @param count
+     */
+    public void setTransmitPacketCount(long count) {
+        transmitPackets = count;
+    }
+
+    /**
+     * Returns the tx packet count for the port
+     * @return
+     */
+    public long getTransmitPacketCount() {
+        return transmitPackets;
+    }
+
+    /**
+     * Set the rx byte count's value
+     * @param count
+     */
+    public void setReceiveByteCount(long count) {
+        receiveBytes = count;
+    }
+
+    /**
+     * Return the rx byte count for the port
+     * @return
+     */
+    public long getReceiveByteCount() {
+        return receiveBytes;
+    }
+
+    /**
+     * Set the tx byte count's value
+     * @param count
+     */
+    public void setTransmitByteCount(long count) {
+        transmitBytes = count;
+    }
+
+    /**
+     * Return the tx byte count for the port
+     * @return
+     */
+    public long getTransmitByteCount() {
+        return transmitBytes;
+    }
+
+    /**
+     * Set the rx drop count's value
+     * @param count
+     */
+    public void setReceiveDropCount(long count) {
+        receiveDrops = count;
+    }
+
+    /**
+     * Returns the rx drop count for the port
+     * @return
+     */
+    public long getReceiveDropCount() {
+        return receiveDrops;
+    }
+
+    /**
+     * Set the tx drop count's value
+     * @param count
+     */
+    public void setTransmitDropCount(long count) {
+        transmitDrops = count;
+    }
+
+    /**
+     * Returns the tx drop count for the port
+     * @return
+     */
+    public long getTransmitDropCount() {
+        return transmitDrops;
+    }
+
+    /**
+     * Set the rx error count's value
+     * @param count
+     */
+    public void setReceiveErrorCount(long count) {
+        receiveErrors = count;
+    }
+
+    /**
+     * Return the rx error count for the port
+     * @return
+     */
+    public long getReceiveErrorCount() {
+        return receiveErrors;
+    }
+
+    /**
+     * Set the tx error count's value
+     * @param count
+     */
+    public void setTransmitErrorCount(long count) {
+        transmitErrors = count;
+    }
+
+    /**
+     * Return the tx error count for the port
+     * @return
+     */
+    public long getTransmitErrorCount() {
+        return transmitErrors;
+    }
+
+    /**
+     * Set the rx frame error value
+     * @param count
+     */
+    public void setReceiveFrameErrorCount(long count) {
+        receiveFrameError = count;
+    }
+
+    /**
+     * Returns the rx frame error for the port
+     * @return
+     */
+    public long getReceiveFrameErrorCount() {
+        return receiveFrameError;
+    }
+
+    /**
+     * Set the rx overrun error value
+     * @param count
+     */
+    public void setReceiveOverRunErrorCount(long count) {
+        receiveOverRunError = count;
+    }
+
+    /**
+     * Return the rx overrun error for the port
+     * @return
+     */
+    public long getReceiveOverRunErrorCount() {
+        return receiveOverRunError;
+    }
+
+    /**
+     * Set the rx CRC Error value
+     * @param count
+     */
+    public void setReceiveCRCErrorCount(long count) {
+        receiveCrcError = count;
+    }
+
+    /**
+     * Return the rx CRC error for the port
+     * @return
+     */
+    public long getReceiveCRCErrorCount() {
+        return receiveCrcError;
+    }
+
+    /**
+     * Set the collisionCount count's value
+     * @param count
+     */
+    public void setCollisionCount(long count) {
+        collisionCount = count;
+    }
+
+    /**
+     * Return the collisionCount count for the port
+     * @return
+     */
+    public long getCollisionCount() {
+        return collisionCount;
+    }
+
+    @Override
+    public String toString() {
+        return "NodeConnectorStats[portNumber = " + nodeConnector
+                + ", receivePackets = " + receivePackets
+                + ", transmitPackets = " + transmitPackets
+                + ", receiveBytes = " + receiveBytes + ", transmitBytes = "
+                + transmitBytes + ", receiveDrops = " + receiveDrops
+                + ", transmitDrops = " + transmitDrops + ", receiveErrors = "
+                + receiveErrors + ", transmitErrors = " + transmitErrors
+                + ", receiveFrameError = " + receiveFrameError
+                + ", receiveOverRunError = " + receiveOverRunError
+                + ", receiveCrcError = " + receiveCrcError
+                + ", collisionCount = " + collisionCount + "]";
+    }
+
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/NodeDescription.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/reader/NodeDescription.java
new file mode 100644 (file)
index 0000000..b683267
--- /dev/null
@@ -0,0 +1,76 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.reader;
+
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+
+/**
+ * Represents the switch description information
+ *
+ *
+ *
+ */
+public class NodeDescription {
+    private String manufacturer;
+    private String hardware;
+    private String software;
+    private String serialNumber;
+    private String sdnProtocolDescription;
+
+    public NodeDescription() {
+
+    }
+
+    public String getManufacturer() {
+        return manufacturer;
+    }
+
+    public void setManufacturer(String manufacturer) {
+        this.manufacturer = manufacturer;
+    }
+
+    public String getHardware() {
+        return hardware;
+    }
+
+    public void setHardware(String hardware) {
+        this.hardware = hardware;
+    }
+
+    public String getSoftware() {
+        return software;
+    }
+
+    public void setSoftware(String software) {
+        this.software = software;
+    }
+
+    public String getSerialNumber() {
+        return serialNumber;
+    }
+
+    public void setSerialNumber(String serialNumber) {
+        this.serialNumber = serialNumber;
+    }
+
+    public String getSdnProtocolDescription() {
+        return sdnProtocolDescription;
+    }
+
+    public void setSdnProtocolDescription(String sdnProtocolDescription) {
+        this.sdnProtocolDescription = sdnProtocolDescription;
+    }
+
+    @Override
+    public String toString() {
+        return "HwDescription[" + ReflectionToStringBuilder.toString(this)
+                + "]";
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/routing/IListenRoutingUpdates.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/routing/IListenRoutingUpdates.java
new file mode 100644 (file)
index 0000000..dde6510
--- /dev/null
@@ -0,0 +1,26 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.routing;
+
+/**
+ * Interface that will be implemented by the modules that wants to
+ * know events published by the routing engine
+ *
+ */
+
+public interface IListenRoutingUpdates {
+    /**
+     * Method invoked when the recalculation of the all shortest path
+     * tree is done
+     *
+     */
+    public void recalculateDone();
+
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/routing/IRouting.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/routing/IRouting.java
new file mode 100644 (file)
index 0000000..6d246c6
--- /dev/null
@@ -0,0 +1,63 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.routing;
+
+import java.util.Map;
+
+import org.opendaylight.controller.sal.core.Edge;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.Path;
+
+public interface IRouting {
+
+    /**
+     * Returns a Path leading from the source to the destination
+     * @param src: source Node
+     * @param dst: destination Node
+     * @return: Path
+     */
+    public Path getRoute(Node src, Node dst);
+
+    /**
+     * Returns a Max ThroughPut Path leading from the source to the destination
+     * @param src: source Node
+     * @param dst: destination Node
+     * @return: MTPath
+     */
+    public Path getMaxThroughputRoute(Node src, Node dst);
+
+    /**
+     * Returns a Path leading from the source to the destination that meets the specified bandwidth
+     * @param src: source Node
+     * @param dst: destination Node
+     * @param Bw: bandwidth
+     * @return: Path
+     */
+    public Path getRoute(Node src, Node dst, Short Bw);
+
+    /**
+     * Remove all routes and reset all state. USE CAREFULLY!
+     */
+    public void clear();
+
+    /**
+     * Remove all Max Throughput Routes and reset all state. USE CAREFULLY!
+     */
+    public void clearMaxThroughput();
+
+    /**
+     * Initialization For Max Throughput
+     * @param EdgeWeightMap: Map containing Edge and Corresponding
+     * Weight. Optional Param - if null, implementation specific weight
+     * calculation will be used.
+     */
+    public void initMaxThroughput(Map<Edge, Number> EdgeWeightMap);
+
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/topology/IListenTopoUpdates.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/topology/IListenTopoUpdates.java
new file mode 100644 (file)
index 0000000..8a640f1
--- /dev/null
@@ -0,0 +1,58 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.topology;
+
+import java.util.Set;
+
+import org.opendaylight.controller.sal.core.Edge;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.UpdateType;
+
+/**
+ * @file   IListenTopoUpdates.java
+ *
+ * @brief  Topology notifications provided by SAL toward the application
+ *
+ * For example an application that wants to keep up to date with the
+ * updates coming from SAL it will register in the OSGi service
+ * registry this interface (on a per-container base) and SAL will call it
+ * providing the update
+ */
+
+/**
+ * Topology notifications provided by SAL toward the application
+ *
+ */
+public interface IListenTopoUpdates {
+    /**
+     * Called to update on Edge in the topology graph
+     *
+     * @param e Edge being updated
+     * @param type Type of update
+     * @param props Properties of the edge, like BandWidth and/or Latency etc.
+     */
+    public void edgeUpdate(Edge e, UpdateType type, Set<Property> props);
+
+    /**
+     * Called when an Edge utilization is above the safety threshold
+     * configured on the controller
+     *
+     * @param edge The edge which bandwidth usage is above the safety level
+     */
+    public void edgeOverUtilized(Edge edge);
+
+    /**
+     * Called when the Edge utilization is back to normal, below the safety
+     * threshold level configured on the controller
+     *
+     * @param edge
+     */
+    public void edgeUtilBackToNormal(Edge edge);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/topology/IPluginInTopologyService.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/topology/IPluginInTopologyService.java
new file mode 100644 (file)
index 0000000..3744d80
--- /dev/null
@@ -0,0 +1,36 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.topology;
+
+/**
+ * @file   IPluginInTopologyService.java
+ *
+ * @brief  Methods that are invoked from SAL toward the protocol
+ * plugin.
+ *
+ * For example if SAL startup late in respect to a protocol plugin, or
+ * restarts, we need away to sollicit the push of older updates from
+ * Protocol Plugins this interface serve the purpose. This a practical
+ * example of the type of service provided by this interface
+ */
+
+/**
+ * Methods that are invoked from SAL toward the protocol
+ * plugin to sollicit Topoloy updates
+ *
+ */
+public interface IPluginInTopologyService {
+    /**
+     * Tell to protocol plugin that is time to send the updates of the
+     * current topology because someone joined late the game
+     *
+     */
+    public void sollicitRefresh();
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/topology/IPluginOutTopologyService.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/topology/IPluginOutTopologyService.java
new file mode 100644 (file)
index 0000000..7ea9360
--- /dev/null
@@ -0,0 +1,56 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.topology;
+
+import java.util.Set;
+
+import org.opendaylight.controller.sal.core.Edge;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.UpdateType;
+
+/**
+ * @file   IPluginOutTopologyService.java
+ *
+ * @brief  Methods that are invoked from Protocol Plugin toward SAL
+ *
+ * Every time a protocol plugin update the topology, it will call this
+ * service provided by SAL so the update can migrate upward toward the
+ * applications
+ */
+
+/**
+ * Methods that are invoked from Protocol Plugin toward SAL
+ *
+ */
+public interface IPluginOutTopologyService {
+    /**
+     * Called to update on Edge in the topology graph
+     *
+     * @param e Edge being updated
+     * @param type Type of update
+     * @param props Properties of the edge, like BandWidth and/or Latency etc.
+     */
+    public void edgeUpdate(Edge e, UpdateType type, Set<Property> props);
+
+    /**
+     * Called when an Edge utilization is above the safety threshold
+     * configured on the controller
+     * @param edge
+     */
+    public void edgeOverUtilized(Edge edge);
+
+    /**
+     * Called when the Edge utilization is back to normal, below the safety
+     * threshold level configured on the controller
+     *
+     * @param edge
+     */
+    public void edgeUtilBackToNormal(Edge edge);
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/topology/ITopologyService.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/topology/ITopologyService.java
new file mode 100644 (file)
index 0000000..c9b7a01
--- /dev/null
@@ -0,0 +1,32 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.topology;
+
+/**
+ * @file   ITopologyService.java
+ *
+ * @brief  Topology methods provided by SAL toward the applications
+ *
+ * For example An application that startup late in the game or restart
+ * for example, wants to know the current status of SAL, so can use
+ * this interface to get a bunlk sync of the topology status.
+ */
+
+/**
+ * Topology methods provided by SAL toward the applications
+ */
+public interface ITopologyService {
+    /**
+     * Tell to SAL that is time to send the updates of the
+     * current topology because someone joined late the game
+     *
+     */
+    public void sollicitRefresh();
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ConfigurationObject.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ConfigurationObject.java
new file mode 100644 (file)
index 0000000..2e0009c
--- /dev/null
@@ -0,0 +1,14 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+public interface ConfigurationObject {
+
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/Direction.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/Direction.java
new file mode 100644 (file)
index 0000000..8541210
--- /dev/null
@@ -0,0 +1,31 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import java.io.Serializable;
+
+/**
+ * Direction enum
+ *
+ *
+ *
+ */
+public enum Direction implements Serializable {
+    FORWARD("forward"), REVERSE("reverse");
+    private Direction(String name) {
+        this.name = name;
+    }
+
+    private String name;
+
+    public String toString() {
+        return name;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/EtherTypes.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/EtherTypes.java
new file mode 100644 (file)
index 0000000..dbdadff
--- /dev/null
@@ -0,0 +1,117 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The enum contains the most common 802.3 ethernet types and 802.2 + SNAP protocol ids
+ *
+ *
+ *
+ */
+public enum EtherTypes {
+    PVSTP("PVSTP", 0x010B), // 802.2 + SNAP (Spanning Tree)
+    CDP("CDP", 0x2000), // 802.2 + SNAP
+    VTP("VTP", 0x2003), // 802.2 + SNAP
+    IPv4("IPv4", 0x800), ARP("ARP", 0x806), RARP("Reverse ARP", 0x8035), VLANTAGGED(
+            "VLAN Tagged", 0x8100), // 802.1Q
+    IPv6("IPv6", 0x86DD), MPLSUCAST("MPLS Unicast", 0x8847), MPLSMCAST(
+            "MPLS Multicast", 0x8848), QINQ("QINQ", 0x88A8), // Standard 802.1ad QinQ
+    LLDP("LLDP", 0x88CC), OLDQINQ("Old QINQ", 0x9100), // Old non-standard QinQ
+    CISCOQINQ("Cisco QINQ", 0x9200); // Cisco non-standard QinQ
+
+    private static final String regexNumberString = "^[0-9]+$";
+    private String description;
+    private int number;
+
+    private EtherTypes(String description, int number) {
+        this.description = description;
+        this.number = number;
+    }
+
+    public String toString() {
+        return description;
+    }
+
+    public int intValue() {
+        return number;
+    }
+
+    public short shortValue() {
+        return ((Integer) number).shortValue();
+    }
+
+    public static String getEtherTypeName(int number) {
+        return getEtherTypeInternal(number);
+    }
+
+    public static String getEtherTypeName(short number) {
+        return getEtherTypeInternal((int) number & 0xffff);
+    }
+
+    public static String getEtherTypeName(byte number) {
+        return getEtherTypeInternal((int) number & 0xff);
+    }
+
+    private static String getEtherTypeInternal(int number) {
+        for (EtherTypes type : EtherTypes.values()) {
+            if (type.number == number) {
+                return type.toString();
+            }
+        }
+        return "0x" + Integer.toHexString(number);
+    }
+
+    public static short getEtherTypeNumberShort(String name) {
+        if (name.matches(regexNumberString)) {
+            return Short.valueOf(name);
+        }
+        for (EtherTypes type : EtherTypes.values()) {
+            if (type.description.equalsIgnoreCase(name)) {
+                return type.shortValue();
+            }
+        }
+        return 0;
+    }
+
+    public static int getEtherTypeNumberInt(String name) {
+        if (name.matches(regexNumberString)) {
+            return Integer.valueOf(name);
+        }
+        for (EtherTypes type : EtherTypes.values()) {
+            if (type.description.equalsIgnoreCase(name)) {
+                return type.intValue();
+            }
+        }
+        return 0;
+    }
+
+    public static List<String> getEtherTypesNameList() {
+        List<String> ethertypesList = new ArrayList<String>();
+        for (EtherTypes type : EtherTypes.values()) {
+            ethertypesList.add(type.toString());
+        }
+        return ethertypesList;
+    }
+
+    public static EtherTypes loadFromString(String string) {
+        int intType = Integer.parseInt(string);
+
+        for (EtherTypes type : EtherTypes.values()) {
+            if (type.number == intType) {
+                return type;
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/GUIField.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/GUIField.java
new file mode 100644 (file)
index 0000000..9ebf8a2
--- /dev/null
@@ -0,0 +1,48 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+/**
+ * GUI field constants
+ *
+ *
+ *
+ */
+public enum GUIField {
+    USER("User"), PASSWORD("Password"), ROLE("Role"), SERVERIP("Server address"), SERVERSECRET(
+            "Server secret"), SERVERPROTOCOL("Server protocol"), NAME("Name"), CONTAINER(
+            "Container"), SUBNET("Subnet"), GATEWAYIP("Gateway IP Address/Mask"), NODE(
+            "Node"), NODEID("Node ID"), NODEMAC("Node MAC Address"), NODENAME(
+            "Node Name"), SRCNODE("Source Node"), DSTNODE("Destination Node"), SRCPORT(
+            "Source Port"), DSTPORT("Destination Port"), PORTS("Ports"), NODEPORTS(
+            "Node/Ports"), SPANPORTS("Span Ports"), TIER("Tier"), MODE("Mode"), INPUTPORT(
+            "Input Port"), ETHERTYPE("Ether Type"), DLSRCADDRESS("Source MAC"), DLDSTADDRESS(
+            "Dest MAC"), VLANID("Vlan Id"), VLANPRIO("Vlan Priority"), NWSRCADDRESS(
+            "Source IP"), NWDSTADDRESS("Dest IP"), NWPROTOCOL("Protocol"), NWPROTOCOLSHORT(
+            "Proto"), NWTOSBITS("TOS"), TPSRCPORT("Transport Source Port"), TPDSTPORT(
+            "Transport Dest Port"), TPSRCPORTSHORT("Source L4 Port"), TPDSTPORTSHORT(
+            "Dest L4 Port"), METRIC("Metric"), STATUS("Status"), TAG("Tag"), TAGS(
+            "Tags"), STATICVLAN("Static Vlan"), PRIORITY("Priority"), PORTGROUP(
+            "Port Group"), COOKIE("Cookie"), ACTIONS("Actions"), ACTIVE(
+            "Active"), IDLETIMEOUT("Idle Time Out"), HARDTIMEOUT(
+            "Hard Time Out"), INHARDWARE("Install on Switch"), STATICROUTE(
+            "Static Route"), NEXTHOPTYPE("NextHop Type"), NEXTHOP(
+            "NextHop address");
+
+    private GUIField(String name) {
+        this.name = name;
+    }
+
+    private String name;
+
+    public String toString() {
+        return name;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/GlobalConstants.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/GlobalConstants.java
new file mode 100644 (file)
index 0000000..abc0c23
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+/**
+ * Global Constants
+ *
+ */
+public enum GlobalConstants {
+    DEFAULT("default"), CONTAINERMANAGER("containermanager"), CONTAINERNAME(
+            "name"), STATICVLAN("staticvlan"), CLUSTERINGSERVICES("clusteringservices"), ONECONTROLLER(
+            "onecontroller"), STARTUPHOME("configuration/startup/");
+
+    private GlobalConstants(String name) {
+        this.name = name;
+    }
+
+    private String name;
+
+    public String toString() {
+        return name;
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/HexEncode.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/HexEncode.java
new file mode 100644 (file)
index 0000000..1cc2cac
--- /dev/null
@@ -0,0 +1,94 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import java.math.BigInteger;
+
+/**
+ * The class provides methods to convert hex encode strings
+ *
+ *
+ */
+public class HexEncode {
+       /**
+        * This method converts byte array into String format without ":" inserted.
+        */
+    public static String bytesToHexString(byte[] bytes) {
+        int i;
+        String ret = "";
+        String tmp;
+        StringBuffer buf = new StringBuffer();
+        for (i = 0; i < bytes.length; i++) {
+            if (i > 0)
+                ret += ":";
+            short u8byte = (short) ((short) bytes[i] & 0xff);
+            tmp = Integer.toHexString(u8byte);
+            if (tmp.length() == 1)
+                buf.append("0");
+            buf.append(tmp);
+        }
+        ret = buf.toString();
+        return ret;
+    }
+
+    public static String longToHexString(long val) {
+        char arr[] = Long.toHexString(val).toCharArray();
+        StringBuffer buf = new StringBuffer();
+        // prepend the right number of leading zeros
+        int i = 0;
+        for (; i < (16 - arr.length); i++) {
+            buf.append("0");
+            if ((i & 0x01) == 1)
+                buf.append(":");
+        }
+        for (int j = 0; j < arr.length; j++) {
+            buf.append(arr[j]);
+            if ((((i + j) & 0x01) == 1) && (j < (arr.length - 1)))
+                buf.append(":");
+        }
+        return buf.toString();
+    }
+
+    public static byte[] bytesFromHexString(String values) {
+        String[] octets = values.split(":");
+        byte[] ret = new byte[octets.length];
+        int i;
+
+        for (i = 0; i < octets.length; i++)
+            ret[i] = Integer.valueOf(octets[i], 16).byteValue();
+        return ret;
+    }
+
+    public static long stringToLong(String values) {
+        long value = new BigInteger(values.replaceAll(":", ""), 16).longValue();
+        return value;
+    }
+
+       /**
+        * This method converts byte array into HexString format with ":" inserted.
+        */
+    public static String bytesToHexStringWithColumn(byte[] bytes) {
+        int i;
+        String ret = "";
+        String tmp;
+        StringBuffer buf = new StringBuffer();
+        for (i = 0; i < bytes.length; i++) {
+            if (i > 0)
+                buf.append(":");
+            short u8byte = (short) ((short) bytes[i] & 0xff);
+            tmp = Integer.toHexString(u8byte);
+            if (tmp.length() == 1)
+                buf.append("0");
+            buf.append(tmp);
+        }
+        ret = buf.toString();
+        return ret;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/IObjectReader.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/IObjectReader.java
new file mode 100644 (file)
index 0000000..af73dc7
--- /dev/null
@@ -0,0 +1,29 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+/**
+ * This interface is needed to allow object reconstruction when reading serialized objects from
+ * inside a package other than the one where ObjectReader is defined (otherwise you hit the
+ * java.lang.ClassNotFoundException). This interface will allow to deserialize a class from inside
+ * the package where the class is defined. All the exception handling can still happen in
+ * ObjectReader and the implementer of IObjectReader only need to throws such exceptions
+ *
+ *
+ *
+ */
+public interface IObjectReader {
+    public Object readObject(ObjectInputStream ois)
+            throws FileNotFoundException, IOException, ClassNotFoundException;
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/IPProtocols.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/IPProtocols.java
new file mode 100644 (file)
index 0000000..416018d
--- /dev/null
@@ -0,0 +1,260 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * It represents the most common IP protocols numbers
+ * It provides the binding between IP protocol names and numbers
+ * and provides APIs to read and parse them in either of the two forms
+ *
+ *
+ *
+ */
+// Openflow 1.0 supports the IP Proto match only for ICMP, TCP and UDP
+public enum IPProtocols {
+    ANY("any", 0),
+    /* HOPOPT("HOPOPT",0),
+     */ICMP("ICMP", 1),
+    /* IGMP("IGMP",2),
+     GGP("GGP",3),
+     IPV4("IPv4",4),
+     ST("ST",5),
+     */TCP("TCP", 6),
+    /* CBT("CBT",7),
+     EGP("EGP",8),
+     IGP("IGP",9),
+     BBNRCCMON("BBN-RCC-MON",10),
+     NVPII("NVP-II",11),
+     PUP("PUP",12),
+     ARGUS("ARGUS",13),
+     EMCON("EMCON",14),
+     XNET("XNET",15),
+     CHAOS("CHAOS",16),
+     */UDP("UDP", 17),
+    /* MUX("MUX",18),
+     DCNMEAS("DCN-MEAS",19),
+     HMP("HMP",20),
+     PRM("PRM",21),
+     XNSIDP("XNS-IDP",22),
+     TRUNK1("TRUNK-1",23),
+     TRUNK2("TRUNK-2",24),
+     LEAF1("LEAF-1",25),
+     LEAF2("LEAF-2",26),
+     RDP("RDP",27),
+     IRTP("IRTP",28),
+     ISOTP4("ISO-TP4",29),
+     NETBLT("NETBLT",30),
+     MFENSP("MFE-NSP",31),
+     MERITINP("MERIT-INP",32),
+     DCCP("DCCP",33),
+     THREEPC("3PC",34),
+     IDPR("IDPR",35),
+     XTP("XTP",36),
+     DDP("DDP",37),
+     IDPRCMTP("IDPR-CMTP",38),
+     TPPLUSPLUS("TP++",39),
+     IL("IL",40),
+     IPV6("IPv6",41),
+     SDRP("SDRP",42),
+     IPV6Route("IPv6-Route",43),
+     IPV6Frag("IPv6-Frag",44),
+     IDRP("IDRP",45),
+     RSVP("RSVP",46),
+     GRE("GRE",47),
+     DSR("DSR",48),
+     BNA("BNA",49),
+     ESP("ESP",50),
+     AH("AH",51),
+     INLSP("I-NLSP",52),
+     SWIPE("SWIPE",53),
+     NARP("NARP",54),
+     MOBILE("MOBILE",55),
+     TLSP("TLSP",56),
+     SKIP("SKIP",57),
+     */IPV6ICMP("IPv6-ICMP", 58);
+    /* IPV6NoNxt("IPv6-NoNxt",59),
+     IPV6Opts("IPv6-Opts",60),
+     ANYHOST("ANY-HOST",61),
+     CFTP("CFTP",62),
+     ANYNETWORK("ANY-NETWORK",63),
+     SATEXPAK("SAT-EXPAK",64),
+     KRYPTOLAN("KRYPTOLAN",65),
+     RVD("RVD",66),
+     IPPC("IPPC",67),
+     ANYDISTFS("ANY-DIST-FS",68),
+     SATMON("SAT-MON",69),
+     VISA("VISA",70),
+     IPCV("IPCV",71),
+     CPNX("CPNX",72),
+     CPHB("CPHB",73),
+     WSN("WSN",74),
+     PVP("PVP",75),
+     BRSATMON("BR-SAT-MON",76),
+     SUNND("SUN-ND",77),
+     WBMON("WB-MON",78),
+     WBEXPAK("WB-EXPAK",79),
+     ISOIP("ISO-IP",80),
+     VMTP("VMTP",81),
+     SECUREVMTP("SECURE-VMTP",82),
+     VINES("VINES",83),
+     TTP("TTP",84),
+     IPTM("IPTM",84),
+     NSFNETIGP("NSFNET-IGP",85),
+     DGP("DGP",86),
+     TCF("TCF",87),
+     EIGRP("EIGRP",88),
+     OSPFIGP("OSPFIGP",89),
+     SPRITERPC("Sprite-RPC",90),
+     LARP("LARP",91),
+     MTP("MTP",92),
+     AX25("AX.25",93),
+     IPIP("IPIP",94),
+     MICP("MICP",95),
+     SCCSP("SCC-SP",96),
+     ETHERIP("ETHERIP",97),
+     ENCAP("ENCAP",98),
+     ANYENC("ANY-ENC",99),
+     GMTP("GMTP",100),
+     IFMP("IFMP",101),
+     PNNI("PNNI",102),
+     PIM("PIM",103),
+     ARIS("ARIS",104),
+     SCPS("SCPS",105),
+     QNX("QNX",106),
+     AN("A/N",107),
+     IPComp("IPComp",108),
+     SNP("SNP",109),
+     COMPAQPEER("Compaq-Peer",110),
+     IPXINIP("IPX-in-IP",111),
+     VRRP("VRRP",112),
+     PGM("PGM",113),
+     ANY0HOP("ANY-0-HOP",114),
+     L2TP("L2TP",115),
+     DDX("DDX",116),
+     IATP("IATP",117),
+     STP("STP",118),
+     SRP("SRP",119),
+     UTI("UTI",120),
+     SMP("SMP",121),
+     SM("SM",122),
+     PTP("PTP",123),
+     ISIS("ISIS",124),
+     FIRE("FIRE",125),
+     CRTP("CRTP",126),
+     CRUDP("CRUDP",127),
+     SSCOPMCE("SSCOPMCE",128),
+     IPLT("IPLT",129),
+     SPS("SPS",130),
+     PIPE("PIPE",131),
+     SCTP("SCTP",132),
+     FC("FC",133),
+     RSVPE2EIGNORE("RSVP-E2E-IGNORE",134),
+     MOBILITYHEADER("Mobility Header",135),
+     UDPLITE("UDPLite",136),
+     MPLSINIP("MPLS-in-IP",137),
+     MANET("MANET",138),
+     HIP("HIP",139),
+     SHIM6("Shim6",140),
+     WESP("WESP",141),
+     ROHC("ROHC",142);
+     */
+    private static final String regexNumberString = "^[0-9]+$";
+    private String protocolName;
+    private int protocolNumber;
+
+    private IPProtocols(String name, int number) {
+        protocolName = name;
+        protocolNumber = number;
+    }
+
+    public int intValue() {
+        return protocolNumber;
+    }
+
+    public short shortValue() {
+        return ((Integer) protocolNumber).shortValue();
+    }
+
+    public byte byteValue() {
+        return ((Integer) protocolNumber).byteValue();
+    }
+
+    public String toString() {
+        return protocolName;
+    }
+
+    public static String getProtocolName(int number) {
+        return getProtocolNameInternal(number);
+    }
+
+    public static String getProtocolName(short number) {
+        return getProtocolNameInternal((int) number & 0xffff);
+    }
+
+    public static String getProtocolName(byte number) {
+        return getProtocolNameInternal((int) number & 0xff);
+    }
+
+    private static String getProtocolNameInternal(int number) {
+        for (IPProtocols proto : IPProtocols.values()) {
+            if (proto.protocolNumber == number) {
+                return proto.toString();
+            }
+        }
+        return "0x" + Integer.toHexString(number);
+    }
+
+    public static short getProtocolNumberShort(String name) {
+        if (name.matches(regexNumberString)) {
+            return Short.valueOf(name);
+        }
+        for (IPProtocols proto : IPProtocols.values()) {
+            if (proto.protocolName.equalsIgnoreCase(name)) {
+                return proto.shortValue();
+            }
+        }
+        return 0;
+    }
+
+    public static int getProtocolNumberInt(String name) {
+        if (name.matches(regexNumberString)) {
+            return Integer.valueOf(name);
+        }
+        for (IPProtocols proto : IPProtocols.values()) {
+            if (proto.protocolName.equalsIgnoreCase(name)) {
+                return proto.intValue();
+            }
+        }
+        return 0;
+    }
+
+    public static byte getProtocolNumberByte(String name) {
+        if (name.matches(regexNumberString)) {
+            return Integer.valueOf(name).byteValue();
+        }
+        for (IPProtocols proto : IPProtocols.values()) {
+            if (proto.protocolName.equalsIgnoreCase(name)) {
+                return proto.byteValue();
+            }
+        }
+        return 0;
+    }
+
+    public static List<String> getProtocolNameList() {
+        List<String> protoList = new ArrayList<String>();
+        for (IPProtocols proto : IPProtocols.values()) {
+            protoList.add(proto.toString());
+        }
+        return protoList;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java
new file mode 100644 (file)
index 0000000..703d49a
--- /dev/null
@@ -0,0 +1,341 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Utility class containing the common utility functions needed
+ * for operating on networking data structures
+ *
+ *
+ *
+ */
+public abstract class NetUtils {
+    /**
+     * Constant holding the number of bits in a byte
+     */
+    public static final int NumBitsInAByte = 8;
+
+    /**
+     * Converts a 4 bytes array into an integer number
+     *
+     * @param ba       the 4 bytes long byte array
+     * @return     the integer number
+     */
+    public static int byteArray4ToInt(byte[] ba) {
+        if (ba == null || ba.length != 4)
+            return 0;
+        return (int) ((0xff & ba[0]) << 24 | (0xff & ba[1]) << 16
+                | (0xff & ba[2]) << 8 | (0xff & ba[3]));
+    }
+
+    /**
+     * Converts an integer number into a 4 bytes array
+     *
+     * @param i the integer number
+     * @return  the byte array
+     */
+    public static byte[] intToByteArray4(int i) {
+        return new byte[] { (byte) ((i >> 24) & 0xff),
+                (byte) ((i >> 16) & 0xff), (byte) ((i >> 8) & 0xff),
+                (byte) (i & 0xff) };
+    }
+
+    /**
+     * Converts an IP address passed as integer value into the
+     * respective InetAddress object
+     *
+     * @param address  the IP address in integer form
+     * @return                 the IP address in InetAddress form
+     */
+    public static InetAddress getInetAddress(int address) {
+        InetAddress ip = null;
+        try {
+            ip = InetAddress.getByAddress(NetUtils.intToByteArray4(address));
+        } catch (UnknownHostException e) {
+            e.printStackTrace();
+        }
+        return ip;
+    }
+
+    /**
+     * Return the InetAddress Network Mask given the length of the prefix bit mask.
+     * The prefix bit mask indicates the contiguous leading bits that are NOT masked out.
+     * Example: A prefix bit mask length of 8 will give an InetAddress Network Mask of 255.0.0.0
+     *
+     * @param prefixMaskLength integer representing the length of the prefix network mask
+     * @param isV6                             boolean representing the IP version of the returned address
+     * @return
+     */
+    public static InetAddress getInetNetworkMask(int prefixMaskLength,
+            boolean isV6) {
+        if (prefixMaskLength < 0 || (!isV6 && prefixMaskLength > 32)
+                || (isV6 && prefixMaskLength > 128)) {
+            return null;
+        }
+        byte v4Address[] = { 0, 0, 0, 0 };
+        byte v6Address[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+        byte address[] = (isV6) ? v6Address : v4Address;
+        int numBytes = prefixMaskLength / 8;
+        int numBits = prefixMaskLength % 8;
+        int i = 0;
+        for (; i < numBytes; i++) {
+            address[i] = (byte) 0xff;
+        }
+        if (numBits > 0) {
+            int rem = 0;
+            for (int j = 0; j < numBits; j++) {
+                rem |= 1 << (7 - j);
+            }
+            address[i] = (byte) rem;
+        }
+
+        try {
+            return InetAddress.getByAddress(address);
+        } catch (UnknownHostException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * Returns the number of contiguous bits belonging to the subnet, that have to be masked out
+     * Example: A prefix network byte mask of ff.ff.ff.00 will give a subnet mask length of 8,
+     * while ff.00.00.00 will return a subnet mask length of 24.
+     * If the passed prefixMask object is null, 0 is returned
+     *
+     * @param prefixMask       the prefix mask as byte array
+     * @return                         the length of the prefix network mask
+     */
+    public static int getSubnetMaskLength(byte[] prefixMask) {
+        int maskLength = 0;
+        if (prefixMask != null) {
+            // Create bit mask
+            int intMask = 0;
+            int numBytes = prefixMask.length;
+            for (int i = 0; i < numBytes; i++) {
+                intMask |= ((int) prefixMask[i] & 0xff) << (8 * (numBytes - 1 - i));
+            }
+
+            int bit = 1;
+            while (((intMask & bit) == 0) && (maskLength <= (numBytes * 8))) {
+                maskLength += 1;
+                bit = bit << 1;
+            }
+        }
+        return maskLength;
+    }
+
+    /**
+     * Returns the number of contiguous bits belonging to the subnet, that have to be masked out
+     * Example: A prefix network byte mask of ff.ff.ff.00 will give a subnet mask length of 8,
+     * while ff.00.00.00 will return a subnet mask length of 24
+     * If the passed prefixMask object is null, 0 is returned
+     *
+     * @param prefixMask       the prefix mask as InetAddress
+     * @return                         the length of the prefix network mask
+     */
+    public static int getSubnetMaskLength(InetAddress prefixMask) {
+        return (prefixMask == null) ? 0 : NetUtils
+                .getSubnetMaskLength(prefixMask.getAddress());
+    }
+
+    /**
+     * Given an IP address and a prefix network mask length, it returns
+     * the equivalent subnet prefix IP address
+     * Example: for ip = "172.28.30.254" and maskLen = 25 it will return "172.28.30.128"
+     *
+     * @param ip               the IP address in InetAddress form
+     * @param maskLen  the length of the prefix network mask
+     * @return                 the subnet prefix IP address in InetAddress form
+     */
+    public static InetAddress getSubnetPrefix(InetAddress ip, int maskLen) {
+        int bytes = maskLen / 8;
+        int bits = maskLen % 8;
+        byte modifiedByte;
+        byte[] sn = ip.getAddress();
+        if (bits > 0) {
+            modifiedByte = (byte) (sn[bytes] >> (8 - bits));
+            sn[bytes] = (byte) (modifiedByte << (8 - bits));
+            bytes++;
+        }
+        for (; bytes < sn.length; bytes++) {
+            sn[bytes] = (byte) (0);
+        }
+        try {
+            return InetAddress.getByAddress(sn);
+        } catch (UnknownHostException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Checks if the test address and mask conflicts with
+     * the filter address and mask
+     *
+     * For example:
+     * testAddress: 172.28.2.23 testMask: 255.255.255.0
+     * filtAddress: 172.28.1.10 testMask: 255.255.255.0
+     * conflict
+     *
+     * testAddress: 172.28.2.23 testMask: 255.255.255.0
+     * filtAddress: 172.28.1.10 testMask: 255.255.0.0
+     * do not conflict
+     *
+     * Null parameters are permitted
+     *
+     * @param testAddress
+     * @param filterAddress
+     * @param testMask
+     * @param filterMask
+     * @return
+     */
+    public static boolean inetAddressConflict(InetAddress testAddress,
+            InetAddress filterAddress, InetAddress testMask,
+            InetAddress filterMask) {
+        // Sanity check
+        if ((testAddress == null) || (filterAddress == null)) {
+            return false;
+        }
+
+        // Presence check
+        if (isAny(testAddress) || isAny(filterAddress)) {
+            return false;
+        }
+
+        // Derive the masks length. A null mask means a full mask
+        int testMaskLen = (testMask != null) ? NetUtils
+                .getSubnetMaskLength(testMask.getAddress())
+                : (testAddress instanceof Inet6Address) ? 128 : 32;
+        int filterMaskLen = (filterMask != null) ? NetUtils
+                .getSubnetMaskLength(filterMask.getAddress())
+                : (filterAddress instanceof Inet6Address) ? 128 : 32;
+
+        // Mask length check. Test mask has to be more generic than filter one
+        if (testMaskLen < filterMaskLen) {
+            return true;
+        }
+
+        // Subnet Prefix on filter mask length must be the same
+        InetAddress prefix1 = getSubnetPrefix(testAddress, filterMaskLen);
+        InetAddress prefix2 = getSubnetPrefix(filterAddress, filterMaskLen);
+        return (!prefix1.equals(prefix2));
+    }
+
+    /**
+     * Returns true if the passed MAC address is all zero
+     *
+     * @param mac      the byte array representing the MAC address
+     * @return         true if all MAC bytes are zero
+     */
+    public static boolean isZeroMAC(byte[] mac) {
+        for (short i = 0; i < 6; i++) {
+            if (mac[i] != 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if the passed InetAddress contains all zero
+     *
+     * @param ip       the IP address to test
+     * @return         true if the address is all zero
+     */
+    public static boolean isAny(InetAddress ip) {
+        for (byte b : ip.getAddress()) {
+            if (b != 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static boolean fieldsConflict(int field1, int field2) {
+        if ((field1 == 0) || (field2 == 0) || (field1 == field2)) {
+            return false;
+        }
+        return true;
+    }
+
+    public static InetAddress parseInetAddress(String addressString) {
+        InetAddress address = null;
+        try {
+            address = InetAddress.getByName(addressString);
+        } catch (UnknownHostException e) {
+            e.printStackTrace();
+        }
+        return address;
+    }
+
+    /**
+     * Checks if the passed IP v4 address in string form is valid
+     * The address may specify a mask at the end as "/MM"
+     *
+     * @param cidr the v4 address as A.B.C.D/MM
+     * @return
+     */
+    public static boolean isIPv4AddressValid(String cidr) {
+        if (cidr == null)
+            return false;
+
+        String values[] = cidr.split("/");
+        Pattern ipv4Pattern = Pattern
+                .compile("(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])");
+        Matcher mm = ipv4Pattern.matcher(values[0]);
+        if (!mm.matches()) {
+            return false;
+        }
+        if (values.length >= 2) {
+            int prefix = Integer.valueOf(values[1]);
+            if ((prefix < 0) || (prefix > 32)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Checks if the passed IP v6 address in string form is valid
+     * The address may specify a mask at the end as "/MMM"
+     *
+     * @param cidr the v6 address as A::1/MMM
+     * @return
+     */
+    public static boolean isIPv6AddressValid(String cidr) {
+        if (cidr == null)
+            return false;
+
+        String values[] = cidr.split("/");
+        try {
+            //when given an IP address, InetAddress.getByName validates the ip address
+            InetAddress addr = InetAddress.getByName(values[0]);
+            if (!(addr instanceof Inet6Address)) {
+                return false;
+            }
+        } catch (UnknownHostException ex) {
+            return false;
+        }
+
+        if (values.length >= 2) {
+            int prefix = Integer.valueOf(values[1]);
+            if ((prefix < 0) || (prefix > 128)) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NodeConnectorCreator.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NodeConnectorCreator.java
new file mode 100644 (file)
index 0000000..b04ce9a
--- /dev/null
@@ -0,0 +1,92 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Node.NodeIDType;
+import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
+
+/**
+ * The class provides helper functions to create a node connector
+ *
+ *
+ */
+public abstract class NodeConnectorCreator {
+    /**
+     * Generic NodeConnector creator
+     * The nodeConnector type is inferred from the node type
+     *
+     * @param portId
+     * @param node
+     * @return
+     */
+    public static NodeConnector createNodeConnector(Object portId, Node node) {
+        if (node.getType().equals(NodeIDType.OPENFLOW)) {
+            try {
+                return new NodeConnector(NodeConnectorIDType.OPENFLOW,
+                        (Short) portId, node);
+            } catch (ConstructionException e1) {
+                e1.printStackTrace();
+                return null;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * NodeConnector creator where NodeConnector type can be specified
+     * Needed to create special internal node connectors (like software stack)
+     *
+     * @param nodeConnectorType
+     * @param portId
+     * @param node
+     * @return
+     */
+    public static NodeConnector createNodeConnector(
+            String nodeConnectorType, Object portId, Node node) {
+        try {
+            return new NodeConnector(nodeConnectorType, portId, node);
+        } catch (ConstructionException e1) {
+            e1.printStackTrace();
+            return null;
+        }
+    }
+
+    public static NodeConnector createOFNodeConnector(Short portId, Node node) {
+        try {
+            return new NodeConnector(NodeConnectorIDType.OPENFLOW, portId, node);
+        } catch (ConstructionException e1) {
+            e1.printStackTrace();
+            return null;
+        }
+    }
+
+    public static Set<NodeConnector> createOFNodeConnectorSet(
+            Set<Short> portIds, Node n) {
+        try {
+            Set<NodeConnector> nodeConnectors = new HashSet<NodeConnector>();
+            for (Short ofPortID : portIds) {
+                NodeConnector p = new NodeConnector(
+                        NodeConnector.NodeConnectorIDType.OPENFLOW, Short
+                                .valueOf(ofPortID), n);
+                nodeConnectors.add(p);
+            }
+            return nodeConnectors;
+        } catch (ConstructionException e1) {
+            e1.printStackTrace();
+            return null;
+        }
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NodeCreator.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NodeCreator.java
new file mode 100644 (file)
index 0000000..6b068fb
--- /dev/null
@@ -0,0 +1,31 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.Node.NodeIDType;
+
+/**
+ * Utility class for creating a Node object
+ *
+ *
+ *
+ */
+public abstract class NodeCreator {
+    public static Node createOFNode(Long switchId) {
+        try {
+            return new Node(NodeIDType.OPENFLOW, switchId);
+        } catch (ConstructionException e1) {
+            e1.printStackTrace();
+            return null;
+        }
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ObjectReader.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ObjectReader.java
new file mode 100644 (file)
index 0000000..1b2225c
--- /dev/null
@@ -0,0 +1,68 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Read object to read from file stream
+ *
+ *
+ *
+ */
+public class ObjectReader {
+    private static Logger logger = LoggerFactory.getLogger(ObjectReader.class);
+    private FileInputStream fis;
+    public ObjectInputStream ois;
+
+    public ObjectReader() {
+        fis = null;
+        ois = null;
+    }
+
+    public Object read(IObjectReader reader, String file) {
+        Object obj = null;
+        try {
+            fis = new FileInputStream(file);
+            ois = new ObjectInputStream(fis);
+            obj = reader.readObject(ois);
+        } catch (FileNotFoundException fnfex) {
+            //logger.info("Cannot find {} for reading", file);
+        } catch (IOException ioex) {
+            logger.error("Failed to read from {}", file);
+        } catch (ClassNotFoundException cnfex) {
+            logger.error("Failed to interpret content of {}", file);
+        } catch (Exception e) {
+
+        } finally {
+            if (ois != null) {
+                try {
+                    ois.close();
+                } catch (IOException ioex) {
+                    logger.error("Failed to close object input stream: {}",
+                            file);
+                }
+            }
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException ioex) {
+                    logger.error("Failed to close input file stream: {}", file);
+                }
+            }
+        }
+        return obj;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ObjectWriter.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ObjectWriter.java
new file mode 100644 (file)
index 0000000..730a9b0
--- /dev/null
@@ -0,0 +1,66 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Write object to write to file stream
+ *
+ */
+public class ObjectWriter {
+    private static Logger logger = LoggerFactory.getLogger(ObjectWriter.class);
+    private FileOutputStream fos;
+    private ObjectOutputStream oos;
+
+    public ObjectWriter() {
+        fos = null;
+        oos = null;
+    }
+
+    public Status write(Object obj, String file) {
+        try {
+            fos = new FileOutputStream(file);
+            oos = new ObjectOutputStream(fos);
+            oos.writeObject(obj);
+        } catch (FileNotFoundException fex) {
+            logger.error("Cannot create {} for writing", file);
+            return new Status(StatusCode.INTERNALERROR, "IO Error");
+        } catch (IOException ioex) {
+            logger.error("Failed to write to {}", file);
+            return new Status(StatusCode.INTERNALERROR, "IO Error");
+        } finally {
+            if (oos != null) {
+                try {
+                    oos.close();
+                } catch (IOException ioex) {
+                    logger.error("Failed to close object output stream: {}",
+                            file);
+                }
+            }
+            if (fos != null) {
+                try {
+                    fos.close();
+                } catch (IOException ioex) {
+                    logger
+                            .error("Failed to close output file stream: {}",
+                                    file);
+                }
+            }
+        }
+        return new Status(StatusCode.SUCCESS, null);
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ReadFromFile.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ReadFromFile.java
new file mode 100644 (file)
index 0000000..1d31eaa
--- /dev/null
@@ -0,0 +1,55 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import java.util.ArrayList;
+import java.io.*;
+
+/**
+ * Convenience object for reading from file
+ *
+ *
+ *
+ */
+public class ReadFromFile {
+    private FileInputStream fileStream;
+    private DataInputStream dataInput;
+    private BufferedReader bufferedReader;
+    private String fileName;
+    private File filePointer;
+
+    public ReadFromFile(String name) throws FileNotFoundException {
+        fileName = name;
+        fileStream = new FileInputStream(this.fileName);
+        filePointer = new File(fileName); //needed to allow file deletion
+    }
+
+    public ArrayList<String> readFile() throws IOException {
+        dataInput = new DataInputStream(this.fileStream);
+        bufferedReader = new BufferedReader(new InputStreamReader(dataInput));
+
+        ArrayList<String> lineList = new ArrayList<String>();
+        String line;
+        while ((line = bufferedReader.readLine()) != null) {
+            lineList.add(line);
+        }
+        bufferedReader.close();
+        dataInput.close();
+        fileStream.close();
+        return lineList;
+    }
+
+    public boolean delete() {
+        if (filePointer == null) {
+            return true;
+        }
+        return filePointer.delete();
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ServiceHelper.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ServiceHelper.java
new file mode 100644 (file)
index 0000000..0555860
--- /dev/null
@@ -0,0 +1,222 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   ServiceHelper.java
+ *
+ * @brief  The class helps to register and retrieve OSGi service registry
+ */
+package org.opendaylight.controller.sal.utils;
+
+import java.util.Hashtable;
+import org.osgi.framework.ServiceRegistration;
+import java.util.Dictionary;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The class helps to register and retrieve OSGi service registry
+ *
+ *
+ */
+public class ServiceHelper {
+    private static final Logger logger = LoggerFactory
+            .getLogger(ServiceHelper.class);
+
+    /**
+     * Register a Service in the OSGi service registry
+     *
+     * @param clazz The target class
+     * @param containerName The container name
+     * @param instance of the object exporting the service, be careful
+     * the object must implement/extend clazz else the registration
+     * will fail unless a ServiceFactory is passed as parameter
+     * @param properties The properties to be attached to the service
+     * registration
+     * @return true if registration happened, false otherwise
+     */
+    public static boolean registerService(Class<?> clazz, String containerName,
+            Object instance, Dictionary<String, Object> properties) {
+        if (properties == null) {
+            properties = (Dictionary<String, Object>) new Hashtable<String, Object>();
+        }
+        properties.put("containerName", containerName);
+        return registerGlobalService(clazz, instance, properties);
+    }
+
+    /**
+     * Register a Global Service in the OSGi service registry
+     *
+     * @param clazz The target class
+     * @param instance of the object exporting the service, be careful
+     * the object must implement/extend clazz else the registration
+     * will fail unless a ServiceFactory is passed as parameter
+     * @param properties The properties to be attached to the service
+     * registration
+     * @return true if registration happened, false otherwise
+     */
+    public static boolean registerGlobalService(Class<?> clazz,
+            Object instance, Dictionary<String, Object> properties) {
+        try {
+            BundleContext bCtx = FrameworkUtil.getBundle(instance.getClass())
+                    .getBundleContext();
+            if (bCtx == null) {
+                logger.error("Could not retrieve the BundleContext");
+                return false;
+            }
+
+            ServiceRegistration registration = bCtx.registerService(clazz
+                    .getName(), instance, properties);
+            if (registration == null) {
+                logger.error("Failed to register {} for instance {}", clazz,
+                        instance);
+            }
+            return true;
+        } catch (Exception e) {
+            logger.error("Exception "+e.getMessage() +" while registering the service "+instance.toString());
+        }
+        return false;
+    }
+
+    /**
+     * Retrieve instance of a class via OSGI registry, if there
+     * are many only the first is returned.
+     *
+     * @param clazz The target class
+     * @param containerName The container name
+     * @param bundle The caller
+     */
+    public static Object getInstance(Class<?> clazz, String containerName,
+            Object bundle) {
+        // Back-end convention: Container id in lower case. Let's enforce it here
+        return getInstance(clazz, containerName.toLowerCase(), bundle, null);
+    }
+
+    /**
+     * Retrieve global instance of a class via OSGI registry, if
+     * there are many only the first is returned.
+     *
+     * @param clazz The target class
+     * @param bundle The caller
+     */
+    public static Object getGlobalInstance(Class<?> clazz, Object bundle) {
+        return getGlobalInstance(clazz, bundle, null);
+    }
+
+    /**
+     * Retrieve instance of a class via OSGI registry, if there
+     * are many only the first is returned. On this version an LDAP
+     * type of filter is applied
+     *
+     * @param clazz The target class
+     * @param containerName The container name
+     * @param bundle The caller
+     * @param serviceFilter LDAP filter to be applied in the search
+     */
+    public static Object getInstance(Class<?> clazz, String containerName,
+            Object bundle, String serviceFilter) {
+        Object[] instances = getInstances(clazz, containerName, bundle,
+                serviceFilter);
+        if (instances != null) {
+            return instances[0];
+        }
+        return null;
+    }
+
+    /**
+     * Retrieve global instance of a class via OSGI registry, if
+     * there are many only the first is returned. On this version an LDAP
+     * type of filter is applied
+     *
+     * @param clazz The target class
+     * @param bundle The caller
+     * @param serviceFilter LDAP filter to be applied in the search
+     */
+    public static Object getGlobalInstance(Class<?> clazz, Object bundle,
+            String serviceFilter) {
+        Object[] instances = getGlobalInstances(clazz, bundle, serviceFilter);
+        if (instances != null) {
+            return instances[0];
+        }
+        return null;
+    }
+
+    /**
+     * Retrieve all the Instances of a Service, optionally
+     * filtered via serviceFilter if non-null else all the results are
+     * returned if null
+     *
+     * @param clazz The target class
+     * @param containerName The container name
+     * @param bundle The caller
+     * @param serviceFilter LDAP filter to be applied in the search
+     */
+    public static Object[] getInstances(Class<?> clazz, String containerName,
+            Object bundle, String serviceFilter) {
+        Object instances[] = null;
+        try {
+            BundleContext bCtx = FrameworkUtil.getBundle(bundle.getClass())
+                    .getBundleContext();
+
+            ServiceReference[] services = null;
+            if (serviceFilter != null) {
+                services = bCtx.getServiceReferences(clazz.getName(),
+                        "(&(containerName=" + containerName + ")"
+                                + serviceFilter + ")");
+            } else {
+                services = bCtx.getServiceReferences(clazz.getName(),
+                        "(containerName=" + containerName + ")");
+            }
+
+            if (services != null) {
+                instances = new Object[services.length];
+                for (int i = 0; i < services.length; i++) {
+                    instances[i] = bCtx.getService(services[i]);
+                }
+            }
+        } catch (Exception e) {
+            logger.error("Instance reference is NULL");
+        }
+        return instances;
+    }
+
+    /**
+     * Retrieve all the Instances of a Service, optionally
+     * filtered via serviceFilter if non-null else all the results are
+     * returned if null
+     *
+     * @param clazz The target class
+     * @param bundle The caller
+     * @param serviceFilter LDAP filter to be applied in the search
+     */
+    public static Object[] getGlobalInstances(Class<?> clazz, Object bundle,
+            String serviceFilter) {
+        Object instances[] = null;
+        try {
+            BundleContext bCtx = FrameworkUtil.getBundle(bundle.getClass())
+                    .getBundleContext();
+
+            ServiceReference[] services = bCtx.getServiceReferences(clazz
+                    .getName(), serviceFilter);
+
+            if (services != null) {
+                instances = new Object[services.length];
+                for (int i = 0; i < services.length; i++) {
+                    instances[i] = bCtx.getService(services[i]);
+                }
+            }
+        } catch (Exception e) {
+            logger.error("Instance reference is NULL");
+        }
+        return instances;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/Status.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/Status.java
new file mode 100644 (file)
index 0000000..9bd98ac
--- /dev/null
@@ -0,0 +1,75 @@
+package org.opendaylight.controller.sal.utils;
+
+/**
+ * Represents the return object of the osgi service interfaces function calls.
+ * It contains a code {@code StatusCode} representing the result of the call
+ * and a string which describes a failure reason (if any) in human readable form.
+ */
+public class Status {
+       StatusCode code;
+       String description;
+       
+       /**
+        * Generates an instance of the Status class.
+        * 
+        * @param errorCode The status code. If passed as null, code will be 
+        * stored as {@code StatusCode.UNDEFINED}
+        * @param description The human readable description of the status. If passed
+        * as null, description will be inferred by the code
+        */
+       public Status(StatusCode errorCode, String description) {
+               this.code = (errorCode != null)? errorCode : StatusCode.UNDEFINED;
+               this.description = (description != null)? description : this.code.toString();
+       }
+       
+       /**
+        * Returns the status code
+        * @return the {@code StatusCode} representing the status code 
+        */
+       public StatusCode getCode() {
+               return code;
+       }
+       
+       /**
+        * Returns a human readable description of the failure if any
+        * @return a string representing the reason of failure
+        */
+       public String getDescription() {
+               return description;
+       }
+       
+       /**
+        * Tells whether the status is successful
+        * @return true if the Status code is {@code StatusCode.SUCCESS}
+        */
+       public boolean isSuccess() {
+               return code == StatusCode.SUCCESS;
+       }
+       
+       @Override
+       public String toString() {
+               return code + ": " + description;
+       }
+
+       @Override
+       public int hashCode() {
+               final int prime = 31;
+               int result = 1;
+               result = prime * result + ((code == null) ? 0 : code.hashCode());
+               return result;
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj == null)
+                       return false;
+               if (getClass() != obj.getClass())
+                       return false;
+               Status other = (Status) obj;
+               if (code != other.code)
+                       return false;
+               return true;
+       }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/StatusCode.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/StatusCode.java
new file mode 100644 (file)
index 0000000..aca7919
--- /dev/null
@@ -0,0 +1,40 @@
+package org.opendaylight.controller.sal.utils;
+
+/**
+ * The enum which describes the generic error conditions.
+ * Each enum value is associated with a minimal description string. 
+ *
+ */
+public enum StatusCode {
+       SUCCESS("Success"),
+
+       BADREQUEST("Bad Request"),
+       UNAUTHORIZED("UnAuthorized"),
+       FORBIDDEN("Forbidden"),
+       NOTFOUND("Not Found"),
+       NOTALLOWED("Method Not Allowed"),
+       NOTACCEPTABLE("Request Not Acceptable"),
+       TIMEOUT("Request Timeout"),
+       CONFLICT("Resource Conflict"),
+       GONE("Resource Gone"),
+       UNSUPPORTED("Unsupported"),
+
+       INTERNALERROR("Internal Error"), 
+       NOTIMPLEMENTED("Not Implemented"),
+       NOSERVICE("Service Not Available"),
+       
+       UNDEFINED("Undefined Error");
+       
+       private String description;
+       private StatusCode(String description) {
+               this.description = description; 
+       }
+       
+       /**
+        * Prints the description associated to the code value
+        */
+       public String toString() {
+               return description;
+       }
+
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/TierHelper.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/TierHelper.java
new file mode 100644 (file)
index 0000000..f8b61b0
--- /dev/null
@@ -0,0 +1,51 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class TierHelper {
+    private static TierHelper tierHelper;
+    public static final int unknownTierNumber = 0;
+    private List<String> tierNames;
+
+    static {
+        tierHelper = new TierHelper();
+    }
+
+    private TierHelper() {
+        tierNames = new ArrayList<String>();
+        tierNames.add("Unknown");
+        tierNames.add("Access");
+        tierNames.add("Distribution");
+        tierNames.add("Core");
+    }
+
+    public static void setTierName(int tier, String name) {
+        if (tier > tierHelper.tierNames.size() - 1) {
+            for (int i = tierHelper.tierNames.size() - 1; i < tier; i++) {
+                tierHelper.tierNames.add("Unknown");
+            }
+        }
+        tierHelper.tierNames.set(tier, name);
+    }
+
+    public static String getTierName(int tier) {
+        if ((tier < 0) || (tier > tierHelper.tierNames.size() - 1)) {
+            return "Unknown";
+        }
+        return tierHelper.tierNames.get(tier);
+    }
+
+    public static List<String> getTiers() {
+        return tierHelper.tierNames;
+    }
+}
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/WriteToFile.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/WriteToFile.java
new file mode 100644 (file)
index 0000000..0345b90
--- /dev/null
@@ -0,0 +1,53 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import java.io.*;
+import java.util.ArrayList;
+
+/**
+ * Convenience object to write a file
+ *
+ *
+ *
+ */
+public class WriteToFile {
+    private FileWriter fstream;
+    private BufferedWriter bufferOut;
+    private String fileName;
+
+    public WriteToFile(String name) throws IOException {
+        fileName = name;
+        fstream = new FileWriter(fileName);
+        bufferOut = new BufferedWriter(fstream);
+    }
+
+    public void save(ArrayList<String> entryList) throws IOException {
+        for (String entry : entryList) {
+            bufferOut.write(entry);
+            bufferOut.append('\n');
+        }
+        try {
+            this.bufferOut.flush();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public boolean close() {
+        try {
+            bufferOut.close();
+            fstream.close();
+        } catch (IOException e) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/action/ActionTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/action/ActionTest.java
new file mode 100644 (file)
index 0000000..cf0f022
--- /dev/null
@@ -0,0 +1,237 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.action;
+
+import org.opendaylight.controller.sal.core.ConstructionException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.Assert;
+import org.opendaylight.controller.sal.action.Action;
+import org.opendaylight.controller.sal.action.Controller;
+import org.opendaylight.controller.sal.action.Output;
+import org.opendaylight.controller.sal.action.PopVlan;
+import org.opendaylight.controller.sal.action.PushVlan;
+import org.opendaylight.controller.sal.action.SetDlSrc;
+import org.opendaylight.controller.sal.action.SetNwDst;
+import org.opendaylight.controller.sal.action.SetNwSrc;
+import org.opendaylight.controller.sal.action.SetNwTos;
+import org.opendaylight.controller.sal.action.SetTpDst;
+import org.opendaylight.controller.sal.action.SetTpSrc;
+import org.opendaylight.controller.sal.action.SetVlanCfi;
+import org.opendaylight.controller.sal.action.SetVlanId;
+import org.opendaylight.controller.sal.action.SetVlanPcp;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.utils.EtherTypes;
+import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
+
+public class ActionTest {
+    @Test
+    public void tesActionCreationValidation() {
+        Action action = new PopVlan();
+        Assert.assertTrue(action.isValid());
+
+        byte mac[] = { (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0x11,
+                (byte) 0x22, (byte) 0x33 };
+
+        action = new SetDlSrc(mac);
+        Assert.assertTrue(action.isValid());
+
+        action = new SetDlSrc(mac);
+        Assert.assertTrue(action.isValid());
+    }
+
+    @Test
+    public void testSetVlanActionCreation() {
+        Action action = null;
+
+        action = new SetVlanId(2);
+        Assert.assertTrue(action.isValid());
+
+        action = new SetVlanId(4095);
+        Assert.assertTrue(action.isValid());
+
+        action = new SetVlanId(0);
+        Assert.assertFalse(action.isValid());
+
+        action = new SetVlanId(1);
+        Assert.assertFalse(action.isValid());
+
+        action = new SetVlanId(4096);
+        Assert.assertFalse(action.isValid());
+    }
+
+    @Test
+    public void testPushVlanActionCreation() {
+        Action action = null;
+
+        action = new PushVlan(EtherTypes.QINQ, 0x4, 0x1, 2000);
+        Assert.assertTrue(action.isValid());
+
+        action = new PushVlan(EtherTypes.QINQ.intValue(), 0x4, 0x1, 2000);
+        Assert.assertTrue(action.isValid());
+
+        action = new PushVlan(EtherTypes.OLDQINQ, 0x4, 2, 2000);
+        Assert.assertFalse(action.isValid());
+
+        action = new PushVlan(EtherTypes.VLANTAGGED, 0x4, 0, 2000);
+        Assert.assertTrue(action.isValid());
+
+        action = new PushVlan(EtherTypes.QINQ.intValue(), 0x4, 0x1, 5000);
+        Assert.assertFalse(action.isValid());
+
+        action = new PushVlan(EtherTypes.LLDP, 0x4, 0x1, 2000);
+        Assert.assertFalse(action.isValid());
+
+        action = new PushVlan(EtherTypes.PVSTP, 0x4, 2, 2000);
+        Assert.assertFalse(action.isValid());
+
+        action = new PushVlan(EtherTypes.QINQ, 0x4, -1, 2000);
+        Assert.assertFalse(action.isValid());
+    }
+
+    @Test
+    public void testSetVlanPcpActionCreation() {
+        Action action = null;
+
+        action = new SetVlanPcp(0x4);
+        Assert.assertTrue(action.isValid());
+
+        action = new SetVlanPcp(0x8);
+        Assert.assertFalse(action.isValid());
+
+        action = new SetVlanPcp(-1);
+        Assert.assertFalse(action.isValid());
+    }
+
+    @Test
+    public void testSetVlanCfiActionCreation() {
+        Action action = null;
+
+        action = new SetVlanCfi(0x0);
+        Assert.assertTrue(action.isValid());
+
+        action = new SetVlanCfi(0x1);
+        Assert.assertTrue(action.isValid());
+
+        action = new SetVlanCfi(0x2);
+        Assert.assertFalse(action.isValid());
+
+        action = new SetVlanCfi(-1);
+        Assert.assertFalse(action.isValid());
+    }
+
+    @Test
+    public void testNetworkSetActionCreation() {
+        Action action = null;
+
+        InetAddress ip = null;
+        try {
+            ip = InetAddress.getByName("171.71.9.52");
+        } catch (UnknownHostException e) {
+            e.printStackTrace();
+        }
+
+        action = new SetNwSrc(ip);
+        Assert.assertTrue(action.isValid());
+
+        action = new SetNwDst(ip);
+        Assert.assertTrue(action.isValid());
+
+        try {
+            ip = InetAddress.getByName("2001:420:281:1003:f2de:f1ff:fe71:728d");
+        } catch (UnknownHostException e) {
+            e.printStackTrace();
+        }
+        action = new SetNwSrc(ip);
+        Assert.assertTrue(action.isValid());
+
+        action = new SetNwDst(ip);
+        Assert.assertTrue(action.isValid());
+
+        action = new SetNwTos(0xf);
+        Assert.assertTrue(action.isValid());
+
+        action = new SetNwTos(0xff);
+        Assert.assertTrue(action.isValid());
+
+        action = new SetNwTos(0xff1);
+        Assert.assertFalse(action.isValid());
+
+        action = new SetNwTos(-1);
+        Assert.assertFalse(action.isValid());
+    }
+
+    @Test
+    public void testTransportSetActionCreation() {
+        Action action = null;
+
+        action = new SetTpSrc(50000);
+        Assert.assertTrue(action.isValid());
+
+        action = new SetTpDst(65535);
+        Assert.assertTrue(action.isValid());
+
+        action = new SetTpDst(0);
+        Assert.assertTrue(action.isValid());
+
+        action = new SetTpSrc(-1);
+        Assert.assertFalse(action.isValid());
+
+        action = new SetTpDst(-1);
+        Assert.assertFalse(action.isValid());
+
+        action = new SetTpSrc(65536);
+        Assert.assertFalse(action.isValid());
+
+        action = new SetTpDst(65536);
+        Assert.assertFalse(action.isValid());
+    }
+
+    @Test
+    public void testActionList() {
+        List<Action> actions = new ArrayList<Action>();
+        short portId = (short) 9;
+        Node node = null;
+        try {
+            node = new Node(Node.NodeIDType.OPENFLOW, new Long(0x55667788L));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+        NodeConnector nc = NodeConnectorCreator.createNodeConnector(portId,
+                node);
+        byte mac[] = { (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0x11,
+                (byte) 0x22, (byte) 0x33 };
+        InetAddress ip = null;
+        try {
+            ip = InetAddress.getByName("1.1.1.1");
+        } catch (UnknownHostException e) {
+            e.printStackTrace();
+        }
+
+        actions.add(new SetDlSrc(mac));
+        actions.add(new SetNwSrc(ip));
+        actions.add(new Output(nc));
+        Assert.assertTrue(actions.size() == 3);
+        Assert.assertTrue(actions.get(0).isValid());
+
+        Action probe = new Output(nc);
+        Assert.assertTrue(actions.contains(probe));
+        Assert.assertFalse(actions.contains(new Output(NodeConnectorCreator
+                .createNodeConnector((short) 5, node))));
+        Assert.assertFalse(actions.contains(new Controller()));
+    }
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/authorization/AuthorizationTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/authorization/AuthorizationTest.java
new file mode 100644 (file)
index 0000000..518e9c6
--- /dev/null
@@ -0,0 +1,67 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.authorization;
+               
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.utils.NodeCreator;
+       
+       public class AuthorizationTest {
+       
+       @Test
+       public void testResources () {
+       Privilege p = Privilege.WRITE;
+       ResourceGroup resourceGroup = new ResourceGroup("NodeGroup", p);
+       Map<ResourceGroup, ArrayList<Resource>> resourceMap = new HashMap<ResourceGroup, ArrayList<Resource>>();
+       ArrayList<Resource> resourceList = new ArrayList<Resource>();
+       
+               for (int i = 0; i < 5; i++) {
+                       Node node = NodeCreator.createOFNode((long)i);
+                       Resource resource = new Resource (node, p);     
+                       resourceList.add(resource);
+               }
+               
+               resourceMap.put(resourceGroup, resourceList);
+               
+               ArrayList<Resource> retrievedResourceList = resourceMap.get(resourceGroup);
+               for (Entry<ResourceGroup, ArrayList<Resource>> entry : resourceMap.entrySet()) {
+                       ResourceGroup rGroup = entry.getKey();
+                       Assert.assertTrue(rGroup.getGroupName().equals(resourceGroup.getGroupName()));
+                       for (int i = 0; i < 5; i++) {
+                               Resource resource = retrievedResourceList.get(i);
+                               Assert.assertTrue(resource.getPrivilege().equals(Privilege.WRITE));
+                               Assert.assertTrue(((Long)((Node)resource.getResource()).getID()).equals((long)i));
+                       }
+               }
+       }
+       
+       @Test
+       public void testAppRoleLevel() {
+               AppRoleLevel appRoleLevel = AppRoleLevel.APPOPERATOR;
+               Assert.assertTrue(appRoleLevel.toString().equals("Network-Operator"));
+               Assert.assertTrue(appRoleLevel.toNumber() == 2);
+               Assert.assertTrue(appRoleLevel.toStringPretty().equals("Application Operator"));
+       }
+       
+       @Test
+       public void testUserLevel() {
+               UserLevel userLevel = UserLevel.SYSTEMADMIN;
+               Assert.assertTrue(userLevel.toString().equals("System-Admin"));
+               Assert.assertTrue(userLevel.toNumber() == 0);
+               Assert.assertTrue(userLevel.toStringPretty().equals("System Administrator"));
+       }
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/EdgeTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/EdgeTest.java
new file mode 100644 (file)
index 0000000..f3a9a6b
--- /dev/null
@@ -0,0 +1,190 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   EdgeTest.java
+ *
+ * @brief  Unit Tests for Edge element
+ *
+ * Unit Tests for Edge element
+ */
+package org.opendaylight.controller.sal.core;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Edge;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+
+public class EdgeTest {
+    @Test
+    public void testEdgeEquals() {
+        try {
+            Node n0 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            NodeConnector c0 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x4), n0);
+
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector c1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x1), n1);
+
+            Node n2 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            NodeConnector c2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x4), n2);
+
+            Node n3 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector c3 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x1), n3);
+
+            Edge e0 = new Edge(c0, c1);
+            Edge e1 = new Edge(c2, c3);
+            // e0 must be equal to e1 to pass the test
+            Assert.assertTrue(e0.equals(e1));
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testEdgeDifferents() {
+        Node n0, n1, n2, n3;
+        NodeConnector c0, c1, c2, c3;
+        Edge e0, e1;
+        try {
+            // Difference in the tail node
+            n0 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            c0 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x4), n0);
+
+            n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            c1 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x1), n1);
+
+            e0 = new Edge(c0, c1);
+
+            n2 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            c2 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x4), n2);
+
+            n3 = new Node(Node.NodeIDType.OPENFLOW, new Long(111L));
+            c3 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x1), n3);
+
+            e0 = new Edge(c0, c1);
+            e1 = new Edge(c2, c3);
+            // e0 must be different from e1 to pass the test
+            Assert.assertTrue(!e0.equals(e1));
+
+            // Difference in the head node
+            n0 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            c0 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x4), n0);
+
+            n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            c1 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x1), n1);
+
+            e0 = new Edge(c0, c1);
+
+            n2 = new Node(Node.NodeIDType.OPENFLOW, new Long(41L));
+            c2 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x4), n2);
+
+            n3 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            c3 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x1), n3);
+
+            e0 = new Edge(c0, c1);
+            e1 = new Edge(c2, c3);
+            // e0 must be different from e1 to pass the test
+            Assert.assertTrue(!e0.equals(e1));
+
+            // Difference in the head nodeconnetor
+            n0 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            c0 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x4), n0);
+
+            n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            c1 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x1), n1);
+
+            e0 = new Edge(c0, c1);
+
+            n2 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            c2 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x5), n2);
+
+            n3 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            c3 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x1), n3);
+
+            e0 = new Edge(c0, c1);
+            e1 = new Edge(c2, c3);
+            // e0 must be different from e1 to pass the test
+            Assert.assertTrue(!e0.equals(e1));
+
+            // Difference in the tail nodeconnetor
+            n0 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            c0 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x4), n0);
+
+            n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            c1 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x1), n1);
+
+            e0 = new Edge(c0, c1);
+
+            n2 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            c2 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x4), n2);
+
+            n3 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            c3 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x2), n3);
+
+            e0 = new Edge(c0, c1);
+            e1 = new Edge(c2, c3);
+            // e0 must be different from e1 to pass the test
+            Assert.assertTrue(!e0.equals(e1));
+
+            // Difference in the both nodeconnetor/node
+            n0 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            c0 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x4), n0);
+
+            n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            c1 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x1), n1);
+
+            e0 = new Edge(c0, c1);
+
+            n2 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            c2 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x4), n2);
+
+            n3 = new Node(Node.NodeIDType.OPENFLOW, new Long(111L));
+            c3 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW,
+                    new Short((short) 0x2), n3);
+
+            e0 = new Edge(c0, c1);
+            e1 = new Edge(c2, c3);
+            // e0 must be different from e1 to pass the test
+            Assert.assertTrue(!e0.equals(e1));
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+    }
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/NodeConnectorTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/NodeConnectorTest.java
new file mode 100644 (file)
index 0000000..f7e8f45
--- /dev/null
@@ -0,0 +1,1280 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   NodeConnectorTest.java
+ *
+ * @brief  Unit Tests for NodeConnector element
+ *
+ * Unit Tests for NodeConnector element
+ */
+package org.opendaylight.controller.sal.core;
+
+import java.util.UUID;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+
+public class NodeConnectorTest {
+    @Test
+    public void testNodeConnectorOpenFlowOfWrongType() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector of1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new String(
+                            "0xDEADBEEFCAFE0001L"), n1);
+
+            // If we reach this point the exception was not raised
+            // which should have been the case
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+            // If we reach this point the exception has been raised
+            // and so test passed
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(true);
+        }
+    }
+
+    @Test
+    public void testNodeConnectorONEPKOfWrongType() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector onepk1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new Long(
+                            0xDEADBEEFCAFE0001L), n1);
+
+            // If we reach this point the exception was not raised
+            // which should have been the case
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+            // If we reach this point the exception has been raised
+            // and so test passed
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(true);
+        }
+    }
+
+    @Test
+    public void testNodeConnectorPCEPOfWrongType() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector pcep1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP, new Long(
+                            0xDEADBEEFCAFE0001L), n1);
+
+            // If we reach this point the exception was not raised
+            // which should have been the case
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+            // If we reach this point the exception has been raised
+            // and so test passed
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(true);
+        }
+    }
+
+    @Test
+    public void testNodeConnectorOpenFlowOfCorrectType() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector of1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0xCAFE), n1);
+
+            // If we reach this point the exception has not been
+            // raised so we passed the test
+            System.out.println("Got node:" + of1);
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testNodeConnectorONEPKOfCorrectType() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector onepk1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n1);
+
+            // If we reach this point the exception has not been
+            // raised so we passed the test
+            System.out.println("Got node:" + onepk1);
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testNodeConnectorPCEPOfCorrectType() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector pcep1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP, new Integer(
+                            0xDEADBEEF), n1);
+
+            // If we reach this point the exception has not been
+            // raised so we passed the test
+            System.out.println("Got node:" + pcep1);
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoOpenFlowNodeConnectorEquals() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector of1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0xCAFE), n1);
+            NodeConnector of2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0xCAFE), n1);
+
+            Assert.assertTrue(of1.equals(of2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoONEPKNodeConnectorEquals() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector onepk1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n1);
+            NodeConnector onepk2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n1);
+
+            Assert.assertTrue(onepk1.equals(onepk2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoPCEPNodeConnectorEquals() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector pcep1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP, new Integer(
+                            0xDEADBEEF), n1);
+            NodeConnector pcep2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP, new Integer(
+                            0xDEADBEEF), n1);
+
+            Assert.assertTrue(pcep1.equals(pcep2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoOpenFlowNodeConnectorDifferents() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector of1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0xCAFE), n1);
+            NodeConnector of2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0xBEEF), n1);
+
+            Assert.assertTrue(!of1.equals(of2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoONEPKNodeConnectorDifferents() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector onepk1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n1);
+            NodeConnector onepk2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/2"), n1);
+
+            Assert.assertTrue(!onepk1.equals(onepk2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoPCEPNodeConnectorDifferents() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector pcep1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP, new Integer(
+                            0xDEADBEEF), n1);
+            NodeConnector pcep2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP, new Integer(
+                            0xCAFECAFE), n1);
+
+            Assert.assertTrue(!pcep1.equals(pcep2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoOpenFlowNodeConnectorDifferentsNodes() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            Node n2 = new Node(Node.NodeIDType.OPENFLOW, new Long(111L));
+            NodeConnector of1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0xCAFE), n1);
+            NodeConnector of2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0xCAFE), n2);
+
+            Assert.assertTrue(!of1.equals(of2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoONEPKNodeConnectorDifferentsNodes() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            Node n2 = new Node(Node.NodeIDType.ONEPK, new String("Router2"));
+            NodeConnector onepk1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n1);
+            NodeConnector onepk2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n2);
+
+            Assert.assertTrue(!onepk1.equals(onepk2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoPCEPNodeConnectorDifferentsNodes() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            Node n2 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 1L));
+            NodeConnector pcep1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP, new Integer(
+                            0xDEADBEEF), n1);
+            NodeConnector pcep2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP, new Integer(
+                            0xDEADBEEF), n2);
+
+            Assert.assertTrue(!pcep1.equals(pcep2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testIncompatibleNodes() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW2PCEP, new Short(
+                            (short) 0), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW2ONEPK,
+                    new Short((short) 0), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK2PCEP, new String(
+                            "towardPCEP1"), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK2OPENFLOW,
+                    new String("towardPCEP1"), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP, new Integer(0), n1);
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP2ONEPK,
+                    new Integer(0), n1);
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP2OPENFLOW,
+                    new Integer(0), n1);
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW2PCEP, new Short(
+                            (short) 0), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW2ONEPK,
+                    new Short((short) 0), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK2PCEP, new String(
+                            "towardPCEP1"), n1);
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK2OPENFLOW,
+                    new String("towardPCEP1"), n1);
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n1);
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP, new Integer(0), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP2ONEPK,
+                    new Integer(0), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP2OPENFLOW,
+                    new Integer(0), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0), n1);
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW2PCEP, new Short(
+                            (short) 0), n1);
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW2ONEPK,
+                    new Short((short) 0), n1);
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK2PCEP, new String(
+                            "towardPCEP1"), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK2OPENFLOW,
+                    new String("towardPCEP1"), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP, new Integer(0), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP2ONEPK,
+                    new Integer(0), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP2OPENFLOW,
+                    new Integer(0), n1);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+    }
+
+    @Test
+    public void testConversionToStringAndBack() {
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(
+                    0xDEADBEEFCAFE0001L, 0xDEADBEEFCAFE0002L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP2ONEPK, new Integer(
+                            0xDEADBEEF), n1);
+            String nc1Str = nc1.toString();
+            System.out.println("NodeConnector String = " + nc1Str);
+            NodeConnector nc1FromStr = NodeConnector.fromString(nc1Str);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(nc1FromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(nc1.equals(nc1FromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(
+                    0xDEADBEEFCAFE0001L, 0xDEADBEEFCAFE0002L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP2OPENFLOW,
+                    new Integer(0x10), n1);
+            String nc1Str = nc1.toString();
+            System.out.println("NodeConnector String = " + nc1Str);
+            NodeConnector nc1FromStr = NodeConnector.fromString(nc1Str);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(nc1FromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(nc1.equals(nc1FromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.PCEP, new UUID(
+                    0xDEADBEEFCAFE0001L, 0xDEADBEEFCAFE0002L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.PCEP, new Integer(0x10),
+                    n1);
+            String nc1Str = nc1.toString();
+            System.out.println("NodeConnector String = " + nc1Str);
+            NodeConnector nc1FromStr = NodeConnector.fromString(nc1Str);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(nc1FromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(nc1.equals(nc1FromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK2PCEP, new String(
+                            "towardPCEP1"), n1);
+
+            String nc1Str = nc1.toString();
+            System.out.println("NodeConnector String = " + nc1Str);
+            NodeConnector nc1FromStr = NodeConnector.fromString(nc1Str);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(nc1FromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(nc1.equals(nc1FromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK2OPENFLOW,
+                    new String("towardOPENFLOW1"), n1);
+
+            String nc1Str = nc1.toString();
+            System.out.println("NodeConnector String = " + nc1Str);
+            NodeConnector nc1FromStr = NodeConnector.fromString(nc1Str);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(nc1FromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(nc1.equals(nc1FromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n1);
+
+            String nc1Str = nc1.toString();
+            System.out.println("NodeConnector String = " + nc1Str);
+            NodeConnector nc1FromStr = NodeConnector.fromString(nc1Str);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(nc1FromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(nc1.equals(nc1FromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(
+                    0xDEADBEEFCAFE0001L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0xCAFE), n1);
+
+            String nc1Str = nc1.toString();
+            System.out.println("NodeConnector String = " + nc1Str);
+            NodeConnector nc1FromStr = NodeConnector.fromString(nc1Str);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(nc1FromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(nc1.equals(nc1FromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(0x100L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW2PCEP, new Short(
+                            (short) 0x10), n1);
+
+            String nc1Str = nc1.toString();
+            System.out.println("NodeConnector String = " + nc1Str);
+            NodeConnector nc1FromStr = NodeConnector.fromString(nc1Str);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(nc1FromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(nc1.equals(nc1FromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(0x100L));
+            NodeConnector nc1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW2ONEPK,
+                    new Short((short) 0x11), n1);
+
+            String nc1Str = nc1.toString();
+            System.out.println("NodeConnector String = " + nc1Str);
+            NodeConnector nc1FromStr = NodeConnector.fromString(nc1Str);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(nc1FromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(nc1.equals(nc1FromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testNodeConnectorSpecialType() {
+        try {
+            Node n = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.CONTROLLER,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+            System.out.println("Special NC = " + specialNc);
+            // We expect to reach this point succesfully
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If this expection is raised the test is failing
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ALL,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+            System.out.println("Special NC = " + specialNc);
+            // We expect to reach this point succesfully
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If this expection is raised the test is failing
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.SWSTACK,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+            System.out.println("Special NC = " + specialNc);
+            // We expect to reach this point succesfully
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If this expection is raised the test is failing
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.HWPATH,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+            System.out.println("Special NC = " + specialNc);
+            // We expect to reach this point succesfully
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If this expection is raised the test is failing
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.CONTROLLER,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+            System.out.println("Special NC = " + specialNc);
+            // We expect to reach this point succesfully
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If this expection is raised the test is failing
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ALL,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+            System.out.println("Special NC = " + specialNc);
+            // We expect to reach this point succesfully
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If this expection is raised the test is failing
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.SWSTACK,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+            System.out.println("Special NC = " + specialNc);
+            // We expect to reach this point succesfully
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If this expection is raised the test is failing
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.HWPATH,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+            System.out.println("Special NC = " + specialNc);
+            // We expect to reach this point succesfully
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If this expection is raised the test is failing
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.CONTROLLER,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+            System.out.println("Special NC = " + specialNc);
+            // We expect to reach this point succesfully
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If this expection is raised the test is failing
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ALL,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+            System.out.println("Special NC = " + specialNc);
+            // We expect to reach this point succesfully
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If this expection is raised the test is failing
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.SWSTACK,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+            System.out.println("Special NC = " + specialNc);
+            // We expect to reach this point succesfully
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If this expection is raised the test is failing
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.HWPATH,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+            System.out.println("Special NC = " + specialNc);
+            // We expect to reach this point succesfully
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If this expection is raised the test is failing
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testToStringConversionForOpenFlow() {
+        try {
+            Node n = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector nc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x2AB), n);
+
+            NodeConnector ofFromStr = null;
+
+            ofFromStr = NodeConnector.fromStringNoNode("0x2ab", n);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(ofFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(nc.equals(ofFromStr));
+
+            ofFromStr = NodeConnector.fromStringNoNode("0x2AB", n);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(ofFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(nc.equals(ofFromStr));
+
+            ofFromStr = NodeConnector.fromStringNoNode("683", n);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(ofFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(nc.equals(ofFromStr));
+        } catch (Exception e) {
+            // If this expection is raised the test is failing
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector nc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0xcafe), n);
+
+            NodeConnector ofFromStr = null;
+
+            ofFromStr = NodeConnector.fromStringNoNode("-13570", n);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(ofFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(nc.equals(ofFromStr));
+        } catch (Exception e) {
+            // If this expection is raised the test is failing
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testConversionToStringAndBackSpecialPorts() {
+        try {
+            Node n = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.CONTROLLER,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+
+            String specialNcStr = specialNc.toString();
+            System.out.println("NodeConnector String obtained= " + specialNc);
+            NodeConnector specialNcFromStr = NodeConnector
+                    .fromString(specialNcStr);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(specialNcFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(specialNc.equals(specialNcFromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ALL,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+
+            String specialNcStr = specialNc.toString();
+            System.out.println("NodeConnector String obtained= " + specialNc);
+            NodeConnector specialNcFromStr = NodeConnector
+                    .fromString(specialNcStr);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(specialNcFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(specialNc.equals(specialNcFromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.HWPATH,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+
+            String specialNcStr = specialNc.toString();
+            System.out.println("NodeConnector String obtained= " + specialNc);
+            NodeConnector specialNcFromStr = NodeConnector
+                    .fromString(specialNcStr);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(specialNcFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(specialNc.equals(specialNcFromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.SWSTACK,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+
+            String specialNcStr = specialNc.toString();
+            System.out.println("NodeConnector String obtained= " + specialNc);
+            NodeConnector specialNcFromStr = NodeConnector
+                    .fromString(specialNcStr);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(specialNcFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(specialNc.equals(specialNcFromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.CONTROLLER,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+
+            String specialNcStr = specialNc.toString();
+            System.out.println("NodeConnector String obtained= " + specialNc);
+            NodeConnector specialNcFromStr = NodeConnector
+                    .fromString(specialNcStr);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(specialNcFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(specialNc.equals(specialNcFromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ALL,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+
+            String specialNcStr = specialNc.toString();
+            System.out.println("NodeConnector String obtained= " + specialNc);
+            NodeConnector specialNcFromStr = NodeConnector
+                    .fromString(specialNcStr);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(specialNcFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(specialNc.equals(specialNcFromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.HWPATH,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+
+            String specialNcStr = specialNc.toString();
+            System.out.println("NodeConnector String obtained= " + specialNc);
+            NodeConnector specialNcFromStr = NodeConnector
+                    .fromString(specialNcStr);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(specialNcFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(specialNc.equals(specialNcFromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.SWSTACK,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+
+            String specialNcStr = specialNc.toString();
+            System.out.println("NodeConnector String obtained= " + specialNc);
+            NodeConnector specialNcFromStr = NodeConnector
+                    .fromString(specialNcStr);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(specialNcFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(specialNc.equals(specialNcFromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.CONTROLLER,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+
+            String specialNcStr = specialNc.toString();
+            System.out.println("NodeConnector String obtained= " + specialNc);
+            NodeConnector specialNcFromStr = NodeConnector
+                    .fromString(specialNcStr);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(specialNcFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(specialNc.equals(specialNcFromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ALL,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+
+            String specialNcStr = specialNc.toString();
+            System.out.println("NodeConnector String obtained= " + specialNc);
+            NodeConnector specialNcFromStr = NodeConnector
+                    .fromString(specialNcStr);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(specialNcFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(specialNc.equals(specialNcFromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.HWPATH,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+
+            String specialNcStr = specialNc.toString();
+            System.out.println("NodeConnector String obtained= " + specialNc);
+            NodeConnector specialNcFromStr = NodeConnector
+                    .fromString(specialNcStr);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(specialNcFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(specialNc.equals(specialNcFromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector specialNc = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.SWSTACK,
+                    NodeConnector.SPECIALNODECONNECTORID, n);
+
+            String specialNcStr = specialNc.toString();
+            System.out.println("NodeConnector String obtained= " + specialNc);
+            NodeConnector specialNcFromStr = NodeConnector
+                    .fromString(specialNcStr);
+
+            // Make sure we got a nodeconnector
+            Assert.assertTrue(specialNcFromStr != null);
+
+            // Now the converted nodeconnector need to be the same of the
+            // original one
+            Assert.assertTrue(specialNc.equals(specialNcFromStr));
+        } catch (ConstructionException e) {
+            // Fail if exception raised
+            Assert.assertTrue(false);
+        }
+    }
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/NodeTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/NodeTest.java
new file mode 100644 (file)
index 0000000..c081e10
--- /dev/null
@@ -0,0 +1,427 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   NodeTest.java
+ *
+ * @brief  Unit Tests for Node element
+ *
+ * Unit Tests for Node element
+ */
+package org.opendaylight.controller.sal.core;
+
+import java.util.UUID;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Node;
+
+public class NodeTest {
+    @Test
+    public void testNodeOpenFlowOfWrongType() {
+        try {
+            Node of1 = new Node(Node.NodeIDType.OPENFLOW, new String(
+                    "0xDEADBEEFCAFE0001L"));
+
+            // If we reach this point the exception was not raised
+            // which should have been the case
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+            // If we reach this point the exception has been raised
+            // and so test passed
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(true);
+        }
+    }
+
+    @Test
+    public void testNodeONEPKOfWrongType() {
+        try {
+            Node onepk1 = new Node(Node.NodeIDType.ONEPK, new Long(
+                    0xDEADBEEFCAFE0001L));
+
+            // If we reach this point the exception was not raised
+            // which should have been the case
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+            // If we reach this point the exception has been raised
+            // and so test passed
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(true);
+        }
+    }
+
+    @Test
+    public void testNodePCEPOfWrongType() {
+        try {
+            Node pcep1 = new Node(Node.NodeIDType.PCEP, new Long(
+                    0xDEADBEEFCAFE0001L));
+
+            // If we reach this point the exception was not raised
+            // which should have been the case
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+            // If we reach this point the exception has been raised
+            // and so test passed
+            System.out.println("Got exception as expected!:" + e);
+            Assert.assertTrue(true);
+        }
+    }
+
+    @Test
+    public void testNodeOpenFlowOfCorrectType() {
+        try {
+            Node of1 = new Node(Node.NodeIDType.OPENFLOW, new Long(
+                    0xDEADBEEFCAFE0001L));
+
+            // If we reach this point the exception has not been
+            // raised so we passed the test
+            System.out.println("Got node:" + of1);
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testNodeONEPKOfCorrectType() {
+        try {
+            Node onepk1 = new Node(Node.NodeIDType.ONEPK, new String(
+                    "0xDEADBEEFCAFE0001L"));
+
+            // If we reach this point the exception has not been
+            // raised so we passed the test
+            System.out.println("Got node:" + onepk1);
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testNodePCEPOfCorrectType() {
+        try {
+            Node pcep1 = new Node(Node.NodeIDType.PCEP, new UUID(0L, 0L));
+
+            // If we reach this point the exception has not been
+            // raised so we passed the test
+            System.out.println("Got node:" + pcep1);
+            Assert.assertTrue(true);
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoOpenFlowNodeEquals() {
+        try {
+            Node of1 = new Node(Node.NodeIDType.OPENFLOW, new Long(
+                    0xDEADBEEFCAFE0001L));
+            Node of2 = new Node(Node.NodeIDType.OPENFLOW, new Long(
+                    0xDEADBEEFCAFE0001L));
+
+            Assert.assertTrue(of1.equals(of2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoONEPKNodeEquals() {
+        try {
+            Node onepk1 = new Node(Node.NodeIDType.ONEPK, new String(
+                    "0xDEADBEEFCAFE0001L"));
+            Node onepk2 = new Node(Node.NodeIDType.ONEPK, new String(
+                    "0xDEADBEEFCAFE0001L"));
+
+            Assert.assertTrue(onepk1.equals(onepk2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoPCEPNodeEquals() {
+        try {
+            Node pcep1 = new Node(Node.NodeIDType.PCEP, new UUID(
+                    0xDEADBEEFCAFE0001L, 0L));
+            Node pcep2 = new Node(Node.NodeIDType.PCEP, new UUID(
+                    0xDEADBEEFCAFE0001L, 0L));
+
+            Assert.assertTrue(pcep1.equals(pcep2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoOpenFlowNodeDifferents() {
+        try {
+            Node of1 = new Node(Node.NodeIDType.OPENFLOW, new Long(
+                    0xDEADBEEFCAFE0001L));
+            Node of2 = new Node(Node.NodeIDType.OPENFLOW, new Long(
+                    0xDEADBEEFCAFE0002L));
+
+            Assert.assertTrue(!of1.equals(of2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoONEPKNodeDifferents() {
+        try {
+            Node onepk1 = new Node(Node.NodeIDType.ONEPK, new String(
+                    "0xDEADBEEFCAFE0001L"));
+            Node onepk2 = new Node(Node.NodeIDType.ONEPK, new String(
+                    "0xDEADBEEFCAFE0002L"));
+
+            Assert.assertTrue(!onepk1.equals(onepk2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testTwoPCEPNodeDifferents() {
+        try {
+            Node pcep1 = new Node(Node.NodeIDType.PCEP, new UUID(
+                    0xDEADBEEFCAFE0001L, 0L));
+            Node pcep2 = new Node(Node.NodeIDType.PCEP, new UUID(
+                    0xDEADBEEFCAFE0001L, 1L));
+
+            Assert.assertTrue(!pcep1.equals(pcep2));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testToStringConversionAndBack() {
+        // Test PCEP
+        try {
+            Node pcep = new Node(Node.NodeIDType.PCEP, new UUID(
+                    0xDEADBEEFCAFE0001L, 0L));
+
+            String pcepToStr = pcep.toString();
+            System.out.println("Got String from PCEP=(" + pcepToStr + ")");
+
+            Node pcepFromStr = Node.fromString(pcepToStr);
+
+            // Make sure we got a node
+            Assert.assertTrue(pcepFromStr != null);
+
+            // Now the converted node need to be the same of the
+            // original one
+            Assert.assertTrue(pcep.equals(pcepFromStr));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+
+        // Test ONEPK
+        try {
+            Node onepk = new Node(Node.NodeIDType.ONEPK, new String(
+                    "0xDEADBEEFCAFE0001L"));
+
+            String onepkToStr = onepk.toString();
+            System.out.println("Got String from ONEPK=(" + onepkToStr + ")");
+
+            Node onepkFromStr = Node.fromString(onepkToStr);
+
+            // Make sure we got a node
+            Assert.assertTrue(onepkFromStr != null);
+
+            // Now the converted node need to be the same of the
+            // original one
+            Assert.assertTrue(onepk.equals(onepkFromStr));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+
+        // Test OPENFLOW short string
+        try {
+            Node of = new Node(Node.NodeIDType.OPENFLOW, new Long(0x10L));
+
+            String ofToStr = of.toString();
+            System.out.println("Got String from OPENFLOW=(" + ofToStr + ")");
+
+            Node ofFromStr = Node.fromString(ofToStr);
+
+            // Make sure we got a node
+            Assert.assertTrue(ofFromStr != null);
+
+            // Now the converted node need to be the same of the
+            // original one
+            Assert.assertTrue(of.equals(ofFromStr));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+
+        // Test OPENFLOW longer string
+        try {
+            Node of = new Node(Node.NodeIDType.OPENFLOW, new Long(
+                    0xDEADBEEFCAFE0001L));
+
+            String ofToStr = of.toString();
+            System.out.println("Got String from OPENFLOW=(" + ofToStr + ")");
+
+            Node ofFromStr = Node.fromString(ofToStr);
+
+            // Make sure we got a node
+            Assert.assertTrue(ofFromStr != null);
+
+            // Now the converted node need to be the same of the
+            // original one
+            Assert.assertTrue(of.equals(ofFromStr));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testToStringConversionForOpenFlow() {
+        // Test OPENFLOW longer string
+        try {
+            Node of = new Node(Node.NodeIDType.OPENFLOW, new Long(
+                    0xDEADBEEFCAFE0001L));
+            Node ofFromStr = null;
+
+            // Decimal value for deadbeefcafe0001
+            ofFromStr = Node.fromString("-2401053089206501375");
+
+            // Make sure we got a node
+            Assert.assertTrue(ofFromStr != null);
+
+            // Now the converted node need to be the same of the
+            // original one
+            Assert.assertTrue(of.equals(ofFromStr));
+
+            ofFromStr = Node.fromString("deadbeefcafe0001");
+
+            // Make sure we got a node
+            Assert.assertTrue(ofFromStr != null);
+
+            // Now the converted node need to be the same of the
+            // original one
+            Assert.assertTrue(of.equals(ofFromStr));
+
+            ofFromStr = Node.fromString("DEADBEEFCAFE0001");
+
+            // Make sure we got a node
+            Assert.assertTrue(ofFromStr != null);
+
+            // Now the converted node need to be the same of the
+            // original one
+            Assert.assertTrue(of.equals(ofFromStr));
+
+            // Now the converted node need to be the same of the
+            // original one
+            Assert.assertTrue(of.equals(ofFromStr));
+
+            ofFromStr = Node.fromString("0xdeadbeefcafe0001");
+
+            // Make sure we got a node
+            Assert.assertTrue(ofFromStr != null);
+
+            // Now the converted node need to be the same of the
+            // original one
+            Assert.assertTrue(of.equals(ofFromStr));
+
+            ofFromStr = Node.fromString("0xDEADBEEFCAFE0001");
+
+            // Make sure we got a node
+            Assert.assertTrue(ofFromStr != null);
+
+            // Now the converted node need to be the same of the
+            // original one
+            Assert.assertTrue(of.equals(ofFromStr));
+
+            ofFromStr = Node.fromString("DE:AD:BE:EF:CA:FE:00:01");
+
+            // Make sure we got a node
+            Assert.assertTrue(ofFromStr != null);
+
+            // Now the converted node need to be the same of the
+            // original one
+            Assert.assertTrue(of.equals(ofFromStr));
+
+            ofFromStr = Node.fromString("de:ad:be:ef:ca:fe:00:01");
+
+            // Make sure we got a node
+            Assert.assertTrue(ofFromStr != null);
+
+            // Now the converted node need to be the same of the
+            // original one
+            Assert.assertTrue(of.equals(ofFromStr));
+        } catch (ConstructionException e) {
+            // If we reach this point the exception was raised
+            // which is not expected
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testExtensibleNode() {
+        // Add a new ID type
+        Assert.assertTrue(Node.NodeIDType.registerIDType("FOO", Integer.class));
+        
+        // Trying to re-register the node must fail
+        Assert.assertFalse(Node.NodeIDType.registerIDType("FOO",
+                                                          Integer.class));
+        try {
+            Node n = new Node("FOO", new Integer(0xCAFE));
+
+            System.out.println("Got Extended node:" + n);
+        } catch (ConstructionException e) {
+            // Got an unexpected exception
+            Assert.assertTrue(false);
+        }
+        
+        // Now unregister the type and make sure the node doesn't get
+        // created
+        Node.NodeIDType.unRegisterIDType("FOO");
+        try {
+            Node n = new Node("FOO", new Integer(0xCAFE));
+
+            // If we reach here, something didn't go fine, an
+            // exception should have been raised
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+            // Got an expected exception, do nothing!
+        }
+
+        Assert.assertTrue(true);
+    }
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/PathTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/PathTest.java
new file mode 100644 (file)
index 0000000..9058156
--- /dev/null
@@ -0,0 +1,341 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   PathTest.java
+ *
+ * @brief  Unit Tests for Path element
+ *
+ * Unit Tests for Path element
+ */
+package org.opendaylight.controller.sal.core;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Arrays;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Edge;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Path;
+
+public class PathTest {
+    @Test
+    public void testPathValid() {
+        List<Edge> edges = null;
+        try {
+            Node n0 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            NodeConnector c0 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x4), n0);
+
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector c1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x1), n1);
+            NodeConnector c2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW2ONEPK,
+                    new Short((short) 0xCAFE), n1);
+
+            Node n2 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector c3 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK2OPENFLOW,
+                    new String("towardOF1"), n2);
+            NodeConnector c4 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n2);
+
+            Node n3 = new Node(Node.NodeIDType.ONEPK, new String("Router2"));
+            NodeConnector c5 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n3);
+
+            Edge e0 = new Edge(c0, c1);
+            Edge e1 = new Edge(c1, c2);
+            Edge e2 = new Edge(c2, c3);
+            Edge e3 = new Edge(c3, c4);
+            Edge e4 = new Edge(c4, c5);
+            edges = new LinkedList(Arrays.asList(e0, e1, e2, e3, e4));
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Path res = new Path(edges);
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        // Now lets disconnect on edge so to create a disconnected
+        // path, the constructor should catch that and should not
+        // create the path
+        edges.remove(2);
+
+        try {
+            Path res = new Path(edges);
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+    }
+
+    @Test
+    public void testPathComparison() {
+        List<Edge> edges1 = null;
+        Path path1 = null;
+        List<Edge> edges2 = null;
+        Path path2 = null;
+        List<Edge> edges3 = null;
+        Path path3 = null;
+
+        try {
+            Node n0 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            NodeConnector c0 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x4), n0);
+
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector c1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x1), n1);
+            NodeConnector c2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW2ONEPK,
+                    new Short((short) 0xCAFE), n1);
+
+            Node n2 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector c3 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK2OPENFLOW,
+                    new String("towardOF1"), n2);
+            NodeConnector c4 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n2);
+
+            Node n3 = new Node(Node.NodeIDType.ONEPK, new String("Router2"));
+            NodeConnector c5 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n3);
+
+            Edge e0 = new Edge(c0, c1);
+            Edge e1 = new Edge(c1, c2);
+            Edge e2 = new Edge(c2, c3);
+            Edge e3 = new Edge(c3, c4);
+            Edge e4 = new Edge(c4, c5);
+            edges1 = new LinkedList(Arrays.asList(e0, e1, e2, e3, e4));
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n0 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            NodeConnector c0 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x4), n0);
+
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector c1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x1), n1);
+            NodeConnector c2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW2ONEPK,
+                    new Short((short) 0xCAFE), n1);
+
+            Node n2 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector c3 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK2OPENFLOW,
+                    new String("towardOF1"), n2);
+            NodeConnector c4 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n2);
+
+            Node n3 = new Node(Node.NodeIDType.ONEPK, new String("Router2"));
+            NodeConnector c5 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n3);
+
+            Edge e0 = new Edge(c0, c1);
+            Edge e1 = new Edge(c1, c2);
+            Edge e2 = new Edge(c2, c3);
+            Edge e3 = new Edge(c3, c4);
+            Edge e4 = new Edge(c4, c5);
+            edges2 = new LinkedList(Arrays.asList(e0, e1, e2, e3, e4));
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        try {
+            Node n0 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            NodeConnector c0 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x5), n0);
+
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector c1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x1), n1);
+            NodeConnector c2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW2ONEPK,
+                    new Short((short) 0xCAFE), n1);
+
+            Node n2 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector c3 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK2OPENFLOW,
+                    new String("towardOF1"), n2);
+            NodeConnector c4 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n2);
+
+            Node n3 = new Node(Node.NodeIDType.ONEPK, new String("Router2"));
+            NodeConnector c5 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n3);
+
+            Edge e0 = new Edge(c0, c1);
+            Edge e1 = new Edge(c1, c2);
+            Edge e2 = new Edge(c2, c3);
+            Edge e3 = new Edge(c3, c4);
+            Edge e4 = new Edge(c4, c5);
+            edges3 = new LinkedList(Arrays.asList(e0, e1, e2, e3, e4));
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        try {
+            path1 = new Path(edges1);
+            path2 = new Path(edges2);
+            path3 = new Path(edges3);
+
+            System.out.println("Path1: " + path1);
+            System.out.println("Path2: " + path2);
+            System.out.println("Path3: " + path3);
+
+            // Make sure the path are equals
+            Assert.assertTrue(path1.equals(path2));
+
+            // Make sure the path are marked as different
+            Assert.assertTrue(!path1.equals(path3));
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testPathEmpty() {
+        try {
+            Path path = new Path(new LinkedList());
+            // Exception is expected if not raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+    }
+
+    @Test
+    public void testPathOneElement() {
+        try {
+            Node n0 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            NodeConnector c0 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x5), n0);
+
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector c1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x1), n1);
+
+            Edge e0 = new Edge(c0, c1);
+
+            Path path = new Path(new LinkedList(Arrays.asList(e0)));
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testPathGetNodes() {
+        // Test on >2 edges paths
+        try {
+            Node n0 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            NodeConnector c0 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x4), n0);
+
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector c1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x1), n1);
+            NodeConnector c2 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW2ONEPK,
+                    new Short((short) 0xCAFE), n1);
+
+            Node n2 = new Node(Node.NodeIDType.ONEPK, new String("Router1"));
+            NodeConnector c3 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK2OPENFLOW,
+                    new String("towardOF1"), n2);
+            NodeConnector c4 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n2);
+
+            Node n3 = new Node(Node.NodeIDType.ONEPK, new String("Router2"));
+            NodeConnector c5 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.ONEPK, new String(
+                            "Gi1/0/1"), n3);
+
+            Edge e0 = new Edge(c0, c1);
+            Edge e1 = new Edge(c1, c2);
+            Edge e2 = new Edge(c2, c3);
+            Edge e3 = new Edge(c3, c4);
+            Edge e4 = new Edge(c4, c5);
+            List<Edge> edges = new LinkedList(Arrays.asList(e0, e1, e2, e3, e4));
+            Path path = new Path(edges);
+
+            // Test start node
+            Assert.assertTrue(path.getStartNode().equals(n0));
+
+            // Test end node
+            Assert.assertTrue(path.getEndNode().equals(n3));
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        // Test on 1 edge path
+        try {
+            Node n0 = new Node(Node.NodeIDType.OPENFLOW, new Long(40L));
+            NodeConnector c0 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x4), n0);
+
+            Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
+            NodeConnector c1 = new NodeConnector(
+                    NodeConnector.NodeConnectorIDType.OPENFLOW, new Short(
+                            (short) 0x1), n1);
+
+            Edge e0 = new Edge(c0, c1);
+            List<Edge> edges = new LinkedList(Arrays.asList(e0));
+            Path path = new Path(edges);
+
+            // Test start node
+            Assert.assertTrue(path.getStartNode().equals(n0));
+
+            // Test end node
+            Assert.assertTrue(path.getEndNode().equals(n1));
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+    }
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/PropertyTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/core/PropertyTest.java
new file mode 100644 (file)
index 0000000..8c2d38d
--- /dev/null
@@ -0,0 +1,95 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   PropertyTest.java
+ *
+ * @brief  Test for properties
+ *
+ */
+
+package org.opendaylight.controller.sal.core;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.core.Bandwidth;
+import org.opendaylight.controller.sal.core.Latency;
+import org.opendaylight.controller.sal.core.Property;
+
+public class PropertyTest {
+    @Test
+    public void testBandWidthStr() {
+        Property b;
+
+        b = new Bandwidth(Bandwidth.BWUNK);
+        System.out.println("b = " + b);
+        Assert.assertTrue(b.toString().equals("BandWidth[UnKnown]"));
+
+        b = new Bandwidth(100L);
+        System.out.println("b = " + b);
+        Assert.assertTrue(b.toString().equals("BandWidth[100bps]"));
+
+        b = new Bandwidth(Bandwidth.BW10Mbps);
+        System.out.println("b = " + b);
+        Assert.assertTrue(b.toString().equals("BandWidth[10Mbps]"));
+
+        b = new Bandwidth(Bandwidth.BW100Mbps);
+        System.out.println("b = " + b);
+        Assert.assertTrue(b.toString().equals("BandWidth[100Mbps]"));
+
+        b = new Bandwidth(Bandwidth.BW100Mbps);
+        System.out.println("b = " + b);
+        Assert.assertTrue(b.toString().equals("BandWidth[100Mbps]"));
+
+        b = new Bandwidth(Bandwidth.BW1Gbps);
+        System.out.println("b = " + b);
+        Assert.assertTrue(b.toString().equals("BandWidth[1Gbps]"));
+
+        b = new Bandwidth(Bandwidth.BW10Gbps);
+        System.out.println("b = " + b);
+        Assert.assertTrue(b.toString().equals("BandWidth[10Gbps]"));
+
+        b = new Bandwidth(Bandwidth.BW40Gbps);
+        System.out.println("b = " + b);
+        Assert.assertTrue(b.toString().equals("BandWidth[40Gbps]"));
+
+        b = new Bandwidth(Bandwidth.BW100Gbps);
+        System.out.println("b = " + b);
+        Assert.assertTrue(b.toString().equals("BandWidth[100Gbps]"));
+
+        b = new Bandwidth(Bandwidth.BW100Gbps + 15L);
+        System.out.println("b = " + b);
+        Assert.assertTrue(b.toString().equals("BandWidth[100Gbps]"));
+
+        b = new Bandwidth(Bandwidth.BW1Tbps);
+        System.out.println("b = " + b);
+        Assert.assertTrue(b.toString().equals("BandWidth[1Tbps]"));
+    }
+
+    @Test
+    public void testLatencyStr() {
+        Property l;
+
+        l = new Latency(Latency.LATENCYUNK);
+        System.out.println("l = " + l);
+        Assert.assertTrue(l.toString().equals("Latency[UnKnown]"));
+
+        l = new Latency(Latency.LATENCY1ns);
+        System.out.println("l = " + l);
+        Assert.assertTrue(l.toString().equals("Latency[1nsec]"));
+
+        l = new Latency(Latency.LATENCY1us);
+        System.out.println("l = " + l);
+        Assert.assertTrue(l.toString().equals("Latency[1usec]"));
+
+        l = new Latency(Latency.LATENCY1ms);
+        System.out.println("l = " + l);
+        Assert.assertTrue(l.toString().equals("Latency[1msec]"));
+    }
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/flowprogrammer/FlowTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/flowprogrammer/FlowTest.java
new file mode 100644 (file)
index 0000000..8434057
--- /dev/null
@@ -0,0 +1,221 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.flowprogrammer;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.action.Action;
+import org.opendaylight.controller.sal.action.Controller;
+import org.opendaylight.controller.sal.action.Flood;
+import org.opendaylight.controller.sal.action.Loopback;
+import org.opendaylight.controller.sal.action.Output;
+import org.opendaylight.controller.sal.action.PopVlan;
+import org.opendaylight.controller.sal.action.PushVlan;
+import org.opendaylight.controller.sal.action.SetDlDst;
+import org.opendaylight.controller.sal.action.SetNwDst;
+import org.opendaylight.controller.sal.action.SetVlanId;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.flowprogrammer.Flow;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
+import org.opendaylight.controller.sal.utils.EtherTypes;
+import org.opendaylight.controller.sal.utils.IPProtocols;
+import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
+import org.opendaylight.controller.sal.utils.NodeCreator;
+
+public class FlowTest {
+
+    @Test
+    public void testFlowEquality() throws Exception {
+        Node node = NodeCreator.createOFNode(1055l);
+        Flow flow1 = getSampleFlowV6(node);
+        Flow flow2 = getSampleFlowV6(node);
+        Flow flow3 = getSampleFlow(node);
+
+        // Check Match equality
+        Assert.assertTrue(flow1.getMatch().equals(flow2.getMatch()));
+
+        // Check Actions equality
+        for (int i = 0; i < flow1.getActions().size(); i++) {
+            Action a = flow1.getActions().get(i);
+            Action b = flow2.getActions().get(i);
+            Assert.assertTrue(a != b);
+            Assert.assertTrue(a.equals(b));
+        }
+
+        Assert.assertTrue(flow1.equals(flow2));
+        Assert.assertFalse(flow2.equals(flow3));
+
+        // Check Flow equality where Flow has null action list (pure match)
+        List<Action> emptyList = new ArrayList<Action>(1);
+        Flow x = flow1.clone();
+        x.setActions(emptyList);
+        Assert.assertFalse(flow1.equals(x));
+        flow1.setActions(emptyList);
+        Assert.assertTrue(flow1.equals(x));
+    }
+
+    @Test
+    public void testFlowCloning() throws UnknownHostException {
+        Node node = NodeCreator.createOFNode(55l);
+        Flow flow1 = getSampleFlowV6(node);
+        Flow flow2 = flow1.clone();
+
+        Assert.assertTrue(flow1.equals(flow2));
+        Assert.assertTrue(flow1.getMatch().equals(flow2.getMatch()));
+        Assert.assertTrue(flow1.getActions() != flow2.getActions());
+        Assert.assertTrue(flow1.getActions().equals(flow2.getActions()));
+    }
+
+    @Test
+    public void testFlowActions() throws UnknownHostException {
+        Node node = NodeCreator.createOFNode(55l);
+        Flow flow = getSampleFlowV6(node);
+
+        List<Action> actions = flow.getActions();
+        actions.add(new Loopback());
+
+        Assert.assertTrue(flow.getActions() != actions);
+        Assert.assertTrue(!flow.getActions().equals(actions));
+
+        flow.addAction(new Loopback());
+        Assert.assertTrue(flow.getActions().equals(actions));
+
+        actions.remove(new Loopback());
+        flow.removeAction(new Loopback());
+        Assert.assertTrue(flow.getActions().equals(actions));
+
+        // Add a malformed action
+        Assert.assertFalse(flow.addAction(new PushVlan(EtherTypes.CISCOQINQ, 3,
+                3, 8000)));
+    }
+
+    private Flow getSampleFlow(Node node) throws UnknownHostException {
+        NodeConnector port = NodeConnectorCreator.createOFNodeConnector(
+                (short) 24, node);
+        NodeConnector oport = NodeConnectorCreator.createOFNodeConnector(
+                (short) 30, node);
+        byte srcMac[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
+                (byte) 0x9a, (byte) 0xbc };
+        byte dstMac[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
+                (byte) 0x5e, (byte) 0x6f };
+        InetAddress srcIP = InetAddress.getByName("172.28.30.50");
+        InetAddress dstIP = InetAddress.getByName("171.71.9.52");
+        InetAddress newIP = InetAddress.getByName("200.200.100.1");
+        InetAddress ipMask = InetAddress.getByName("255.255.255.0");
+        InetAddress ipMask2 = InetAddress.getByName("255.240.0.0");
+        short ethertype = EtherTypes.IPv4.shortValue();
+        short vlan = (short) 27;
+        byte vlanPr = 3;
+        Byte tos = 4;
+        byte proto = IPProtocols.TCP.byteValue();
+        short src = (short) 55000;
+        short dst = 80;
+
+        /*
+         * Create a SAL Flow aFlow
+         */
+        Match match = new Match();
+        match.setField(MatchType.IN_PORT, port);
+        match.setField(MatchType.DL_SRC, srcMac);
+        match.setField(MatchType.DL_DST, dstMac);
+        match.setField(MatchType.DL_TYPE, ethertype);
+        match.setField(MatchType.DL_VLAN, vlan);
+        match.setField(MatchType.DL_VLAN_PR, vlanPr);
+        match.setField(MatchType.NW_SRC, srcIP, ipMask);
+        match.setField(MatchType.NW_DST, dstIP, ipMask2);
+        match.setField(MatchType.NW_TOS, tos);
+        match.setField(MatchType.NW_PROTO, proto);
+        match.setField(MatchType.TP_SRC, src);
+        match.setField(MatchType.TP_DST, dst);
+
+        List<Action> actions = new ArrayList<Action>();
+        actions.add(new SetNwDst(newIP));
+        actions.add(new Output(oport));
+        actions.add(new PopVlan());
+        actions.add(new Flood());
+        actions.add(new Controller());
+
+        Flow flow = new Flow(match, actions);
+        flow.setPriority((short) 100);
+        flow.setHardTimeout((short) 360);
+
+        return flow;
+    }
+
+    private Flow getSampleFlowV6(Node node) throws UnknownHostException {
+        NodeConnector port = NodeConnectorCreator.createOFNodeConnector(
+                (short) 24, node);
+        NodeConnector oport = NodeConnectorCreator.createOFNodeConnector(
+                (short) 30, node);
+        byte srcMac[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
+                (byte) 0x9a, (byte) 0xbc };
+        byte dstMac[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
+                (byte) 0x5e, (byte) 0x6f };
+        byte newMac[] = { (byte) 0x11, (byte) 0xaa, (byte) 0xbb, (byte) 0x34,
+                (byte) 0x9a, (byte) 0xee };
+        InetAddress srcIP = InetAddress
+                .getByName("2001:420:281:1004:407a:57f4:4d15:c355");
+        InetAddress dstIP = InetAddress
+                .getByName("2001:420:281:1004:e123:e688:d655:a1b0");
+        InetAddress ipMask = InetAddress
+                .getByName("ffff:ffff:ffff:ffff:0:0:0:0");
+        InetAddress ipMask2 = InetAddress
+                .getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0");
+        InetAddress newIP = InetAddress.getByName("2056:650::a1b0");
+        short ethertype = EtherTypes.IPv6.shortValue();
+        short vlan = (short) 27;
+        byte vlanPr = (byte) 3;
+        Byte tos = 4;
+        byte proto = IPProtocols.UDP.byteValue();
+        short src = (short) 5500;
+        short dst = 80;
+
+        /*
+         * Create a SAL Flow aFlow
+         */
+        Match match = new Match();
+        match.setField(MatchType.IN_PORT, port);
+        match.setField(MatchType.DL_SRC, srcMac);
+        match.setField(MatchType.DL_DST, dstMac);
+        match.setField(MatchType.DL_TYPE, ethertype);
+        match.setField(MatchType.DL_VLAN, vlan);
+        match.setField(MatchType.DL_VLAN_PR, vlanPr);
+        match.setField(MatchType.NW_SRC, srcIP, ipMask);
+        match.setField(MatchType.NW_DST, dstIP, ipMask2);
+        match.setField(MatchType.NW_TOS, tos);
+        match.setField(MatchType.NW_PROTO, proto);
+        match.setField(MatchType.TP_SRC, src);
+        match.setField(MatchType.TP_DST, dst);
+
+        List<Action> actions = new ArrayList<Action>();
+        actions.add(new Controller());
+        actions.add(new SetVlanId(5));
+        actions.add(new SetDlDst(newMac));
+        actions.add(new SetNwDst(newIP));
+        actions.add(new Output(oport));
+        actions.add(new PopVlan());
+        actions.add(new Flood());
+
+        actions.add(new Controller());
+
+        Flow flow = new Flow(match, actions);
+        flow.setPriority((short) 300);
+        flow.setHardTimeout((short) 240);
+
+        return flow;
+    }
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/match/MatchTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/match/MatchTest.java
new file mode 100644 (file)
index 0000000..722f993
--- /dev/null
@@ -0,0 +1,449 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.match;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchField;
+import org.opendaylight.controller.sal.match.MatchType;
+import org.opendaylight.controller.sal.utils.EtherTypes;
+import org.opendaylight.controller.sal.utils.IPProtocols;
+import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
+import org.opendaylight.controller.sal.utils.NodeCreator;
+
+public class MatchTest {
+    @Test
+    public void testMatchCreation() {
+        Node node = NodeCreator.createOFNode(7l);
+        NodeConnector port = NodeConnectorCreator.createOFNodeConnector(
+                (short) 6, node);
+        MatchField field = new MatchField(MatchType.IN_PORT, port);
+
+        Assert.assertTrue(field != null);
+        Assert.assertTrue(field.getType() == MatchType.IN_PORT);
+        Assert.assertTrue((NodeConnector) field.getValue() == port);
+        Assert.assertTrue(field.isValid());
+
+        field = null;
+        field = new MatchField(MatchType.TP_SRC, Long.valueOf(23));
+        Assert.assertFalse(field.isValid());
+
+        field = null;
+        field = new MatchField(MatchType.TP_SRC, (long) 45);
+        Assert.assertFalse(field.isValid());
+
+        field = null;
+        field = new MatchField(MatchType.TP_SRC, 120000);
+        Assert.assertFalse(field.isValid());
+
+        byte mac[] = { (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd,
+                (byte) 11, (byte) 22 };
+        byte mask[] = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff };
+        field = null;
+        field = new MatchField(MatchType.DL_SRC, mac, mask);
+        Assert.assertFalse(field.getValue() == null);
+
+        field = null;
+        field = new MatchField(MatchType.NW_TOS, (byte) 0x22, (byte) 0x3);
+        Assert.assertFalse(field.getValue() == null);
+    }
+
+    @Test
+    public void testMatchSetGet() {
+        Match x = new Match();
+        short val = 2346;
+        NodeConnector inPort = NodeConnectorCreator.createOFNodeConnector(val,
+                NodeCreator.createOFNode(1l));
+        x.setField(MatchType.IN_PORT, inPort);
+        Assert.assertTrue(((NodeConnector) x.getField(MatchType.IN_PORT)
+                .getValue()).equals(inPort));
+        Assert
+                .assertTrue((Short) ((NodeConnector) x.getField(
+                        MatchType.IN_PORT).getValue()).getID() == val);
+    }
+
+    @Test
+    public void testMatchSetGetMAC() {
+        Match x = new Match();
+        byte mac[] = { (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd,
+                (byte) 11, (byte) 22 };
+        byte mac2[] = { (byte) 0xaa, (byte) 0xbb, 0, 0, 0, (byte) 0xbb };
+        byte mask1[] = { (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44,
+                (byte) 0x55, (byte) 0x66 };
+        byte mask2[] = { (byte) 0xff, (byte) 0xff, (byte) 0, (byte) 0,
+                (byte) 0, (byte) 0xff };
+
+        x.setField(MatchType.DL_SRC, mac.clone(), mask1);
+        x.setField(MatchType.DL_DST, mac2.clone(), mask2);
+        Assert.assertTrue(Arrays.equals(mac, (byte[]) x.getField(
+                MatchType.DL_SRC).getValue()));
+        Assert.assertFalse(Arrays.equals((byte[]) x.getField(MatchType.DL_SRC)
+                .getValue(), (byte[]) x.getField(MatchType.DL_DST).getValue()));
+        Assert.assertFalse(x.getField(MatchType.DL_SRC).getBitMask() == x
+                .getField(MatchType.DL_DST).getBitMask());
+
+        x.setField(new MatchField(MatchType.DL_DST, mac.clone(), mask1));
+        Assert.assertTrue(Arrays.equals((byte[]) x.getField(MatchType.DL_SRC)
+                .getValue(), (byte[]) x.getField(MatchType.DL_DST).getValue()));
+    }
+
+    @Test
+    public void testMatchSetGetNWAddr() throws UnknownHostException {
+        Match x = new Match();
+        String ip = "172.20.231.23";
+        InetAddress address = InetAddress.getByName(ip);
+        InetAddress mask = InetAddress.getByName("255.255.0.0");
+
+        x.setField(MatchType.NW_SRC, address, mask);
+        Assert.assertTrue(ip.equals(((InetAddress) x.getField(MatchType.NW_SRC)
+                .getValue()).getHostAddress()));
+        Assert.assertTrue(x.getField(MatchType.NW_SRC).getMask().equals(mask));
+    }
+
+    @Test
+    public void testMatchSetGetEtherType() throws UnknownHostException {
+        Match x = new Match();
+
+        x.setField(MatchType.DL_TYPE, EtherTypes.QINQ.shortValue(),
+                (short) 0xffff);
+        Assert.assertTrue(((Short) x.getField(MatchType.DL_TYPE).getValue())
+                .equals(EtherTypes.QINQ.shortValue()));
+        Assert
+                .assertFalse(x.getField(MatchType.DL_TYPE).getValue() == EtherTypes.QINQ);
+        Assert.assertFalse(x.getField(MatchType.DL_TYPE).getValue().equals(
+                EtherTypes.QINQ));
+
+        x.setField(MatchType.DL_TYPE, EtherTypes.LLDP.shortValue(),
+                (short) 0xffff);
+        Assert.assertTrue(((Short) x.getField(MatchType.DL_TYPE).getValue())
+                .equals(EtherTypes.LLDP.shortValue()));
+        Assert.assertFalse(x.getField(MatchType.DL_TYPE).equals(
+                EtherTypes.LLDP.intValue()));
+    }
+
+    @Test
+    public void testSetGetNwTos() {
+        Match x = new Match();
+        x.setField(MatchType.NW_TOS, (byte) 0xb, (byte) 0xf);
+
+        Byte t = new Byte((byte) 0xb);
+
+        Object o = x.getField(MatchType.NW_TOS).getValue();
+        Assert.assertTrue(o.equals(t));
+        Assert.assertTrue(o.equals((byte) 0xb));
+    }
+
+    @Test
+    public void testSetGetNwProto() {
+        Match x = new Match();
+        byte proto = (byte) 199;
+        x.setField(MatchType.NW_PROTO, proto, (byte) 0xff);
+
+        Object o = x.getField(MatchType.NW_PROTO).getValue();
+        Assert.assertTrue(o.equals(proto));
+    }
+
+    @Test
+    public void testMatchMask() {
+        Match x = new Match();
+        NodeConnector inPort = NodeConnectorCreator.createOFNodeConnector(
+                (short) 6, NodeCreator.createOFNode(3l));
+        x.setField(MatchType.IN_PORT, inPort);
+        x.setField(MatchType.DL_VLAN, (short) 28, (short) 0xfff);
+        Assert.assertFalse(x.getMatches() == 0);
+        Assert
+                .assertTrue(x.getMatches() == (MatchType.IN_PORT.getIndex() | MatchType.DL_VLAN
+                        .getIndex()));
+    }
+
+    @Test
+    public void testMatchBitMask() {
+        byte mac[] = { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 22, (byte) 12 };
+        byte mask[] = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0 };
+        NodeConnector inPort = NodeConnectorCreator.createOFNodeConnector(
+                (short) 4095, NodeCreator.createOFNode(7l));
+
+        MatchField x = new MatchField(MatchType.IN_PORT, inPort);
+        Assert.assertTrue((x.getMask()) == null);
+
+        x = new MatchField(MatchType.DL_VLAN, (short) 255, (short) 0xff);
+        Assert.assertTrue(x.getBitMask() == 0xff);
+
+        x = new MatchField(MatchType.DL_SRC, mac, mask);
+        Assert.assertTrue(x.getMask().equals(mask));
+        Assert.assertTrue(x.getBitMask() == 0xffffffffff00L);
+    }
+
+    @Test
+    public void testNullMask() {
+        byte mac[] = { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 22, (byte) 12 };
+        NodeConnector inPort = NodeConnectorCreator.createOFNodeConnector(
+                (short) 2000, NodeCreator.createOFNode(7l));
+
+        MatchField x = new MatchField(MatchType.IN_PORT, inPort);
+        Assert.assertTrue(x.getBitMask() == 0);
+
+        x = new MatchField(MatchType.NW_PROTO, (byte) 17);
+        Assert.assertTrue(x.getBitMask() == 0xff);
+
+        x = new MatchField(MatchType.DL_VLAN, (short) 255);
+        Assert.assertTrue(x.getBitMask() == 0xfff);
+
+        x = new MatchField(MatchType.DL_SRC, mac);
+        Assert.assertTrue(x.getBitMask() == 0xffffffffffffL);
+    }
+
+    @Test
+    public void testEquality() throws Exception {
+        Node node = NodeCreator.createOFNode(7l);
+        NodeConnector port = NodeConnectorCreator.createOFNodeConnector(
+                (short) 24, node);
+        NodeConnector port2 = NodeConnectorCreator.createOFNodeConnector(
+                (short) 24, node);
+        byte srcMac[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
+                (byte) 0x9a, (byte) 0xbc };
+        byte dstMac[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
+                (byte) 0x5e, (byte) 0x6f };
+        byte srcMac2[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
+                (byte) 0x9a, (byte) 0xbc };
+        byte dstMac2[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
+                (byte) 0x5e, (byte) 0x6f };
+        InetAddress srcIP = InetAddress
+                .getByName("2001:420:281:1004:407a:57f4:4d15:c355");
+        InetAddress dstIP = InetAddress
+                .getByName("2001:420:281:1004:e123:e688:d655:a1b0");
+        InetAddress ipMask = InetAddress
+                .getByName("ffff:ffff:ffff:ffff:0:0:0:0");
+        InetAddress ipMaskd = InetAddress
+                .getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0");
+        InetAddress srcIP2 = InetAddress
+                .getByName("2001:420:281:1004:407a:57f4:4d15:c355");
+        InetAddress dstIP2 = InetAddress
+                .getByName("2001:420:281:1004:e123:e688:d655:a1b0");
+        InetAddress ipMask2 = InetAddress
+                .getByName("ffff:ffff:ffff:ffff:0:0:0:0");
+        InetAddress ipMaskd2 = InetAddress
+                .getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0");
+        short ethertype = EtherTypes.IPv6.shortValue();
+        short ethertype2 = EtherTypes.IPv6.shortValue();
+        short vlan = (short) 27, vlan2 = (short) 27;
+        byte vlanPr = (byte) 3, vlanPr2 = (byte) 3;
+        Byte tos = 4, tos2 = 4;
+        byte proto = IPProtocols.UDP.byteValue(), proto2 = IPProtocols.UDP
+                .byteValue();
+        short src = (short) 5500, src2 = (short) 5500;
+        short dst = 80, dst2 = 80;
+
+        /*
+         * Create a SAL Flow aFlow
+         */
+        Match match1 = new Match();
+        Match match2 = new Match();
+        match1.setField(MatchType.IN_PORT, port);
+        match1.setField(MatchType.DL_SRC, srcMac);
+        match1.setField(MatchType.DL_DST, dstMac);
+        match1.setField(MatchType.DL_TYPE, ethertype);
+        match1.setField(MatchType.DL_VLAN, vlan);
+        match1.setField(MatchType.DL_VLAN_PR, vlanPr);
+        match1.setField(MatchType.NW_SRC, srcIP, ipMask);
+        match1.setField(MatchType.NW_DST, dstIP, ipMaskd);
+        match1.setField(MatchType.NW_TOS, tos);
+        match1.setField(MatchType.NW_PROTO, proto);
+        match1.setField(MatchType.TP_SRC, src);
+        match1.setField(MatchType.TP_DST, dst);
+
+        match2.setField(MatchType.IN_PORT, port2);
+        match2.setField(MatchType.DL_SRC, srcMac2);
+        match2.setField(MatchType.DL_DST, dstMac2);
+        match2.setField(MatchType.DL_TYPE, ethertype2);
+        match2.setField(MatchType.DL_VLAN, vlan2);
+        match2.setField(MatchType.DL_VLAN_PR, vlanPr2);
+        match2.setField(MatchType.NW_SRC, srcIP2, ipMask2);
+        match2.setField(MatchType.NW_DST, dstIP2, ipMaskd2);
+        match2.setField(MatchType.NW_TOS, tos2);
+        match2.setField(MatchType.NW_PROTO, proto2);
+        match2.setField(MatchType.TP_SRC, src2);
+        match2.setField(MatchType.TP_DST, dst2);
+
+        Assert.assertTrue(match1.equals(match2));
+
+        // Make sure all values are equals
+        for (MatchType type : MatchType.values()) {
+            if (match1.isPresent(type)) {
+                Assert.assertTrue(match1.getField(type).equals(
+                        match2.getField(type)));
+            }
+        }
+
+        // Make none of the fields couples are pointing to the same reference
+        MatchField a = null, b = null;
+        for (MatchType type : MatchType.values()) {
+            a = match1.getField(type);
+            b = match2.getField(type);
+            if (a != null && b != null) {
+                Assert.assertFalse(a == b);
+            }
+        }
+    }
+
+    @Test
+    public void testCloning() throws Exception {
+        Node node = NodeCreator.createOFNode(7l);
+        NodeConnector port = NodeConnectorCreator.createOFNodeConnector(
+                (short) 24, node);
+        byte srcMac[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
+                (byte) 0x9a, (byte) 0xbc };
+        byte dstMac[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
+                (byte) 0x5e, (byte) 0x6f };
+        InetAddress srcIP = InetAddress
+                .getByName("2001:420:281:1004:407a:57f4:4d15:c355");
+        InetAddress dstIP = InetAddress
+                .getByName("2001:420:281:1004:e123:e688:d655:a1b0");
+        InetAddress ipMasks = InetAddress
+                .getByName("ffff:ffff:ffff:ffff:0:0:0:0");
+        InetAddress ipMaskd = InetAddress
+                .getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0");
+        short ethertype = EtherTypes.IPv6.shortValue();
+        short vlan = (short) 27;
+        byte vlanPr = (byte) 3;
+        Byte tos = 4;
+        byte proto = IPProtocols.UDP.byteValue();
+        short src = (short) 5500;
+        short dst = 80;
+
+        /*
+         * Create a SAL Flow aFlow
+         */
+        Match match = new Match();
+        match.setField(MatchType.IN_PORT, port);
+        match.setField(MatchType.DL_SRC, srcMac);
+        match.setField(MatchType.DL_DST, dstMac);
+        match.setField(MatchType.DL_TYPE, ethertype);
+        match.setField(MatchType.DL_VLAN, vlan);
+        match.setField(MatchType.DL_VLAN_PR, vlanPr);
+        match.setField(MatchType.NW_SRC, srcIP, ipMasks);
+        match.setField(MatchType.NW_DST, dstIP, ipMaskd);
+        match.setField(MatchType.NW_TOS, tos);
+        match.setField(MatchType.NW_PROTO, proto);
+        match.setField(MatchType.TP_SRC, src);
+        match.setField(MatchType.TP_DST, dst);
+
+        Match cloned = match.clone();
+
+        // Make sure all values are equals
+        for (MatchType type : MatchType.values()) {
+            if (match.isPresent(type)) {
+                if (!match.getField(type).equals(cloned.getField(type))) {
+                    Assert.assertTrue(match.getField(type).equals(
+                            cloned.getField(type)));
+                }
+            }
+        }
+
+        // Make sure none of the fields couples are pointing to the same reference
+        MatchField a = null, b = null;
+        for (MatchType type : MatchType.values()) {
+            a = match.getField(type);
+            b = cloned.getField(type);
+            if (a != null && b != null) {
+                Assert.assertFalse(a == b);
+            }
+        }
+
+        Assert.assertTrue(match.equals(cloned));
+
+        Assert.assertFalse(match.getField(MatchType.DL_SRC) == cloned
+                .getField(MatchType.DL_SRC));
+        Assert.assertFalse(match.getField(MatchType.NW_DST) == cloned
+                .getField(MatchType.NW_DST));
+        Assert.assertTrue(match.getField(MatchType.NW_DST).getMask().equals(
+                cloned.getField(MatchType.NW_DST).getMask()));
+    }
+
+    @Test
+    public void testFlip() throws Exception {
+        Node node = NodeCreator.createOFNode(7l);
+        NodeConnector port = NodeConnectorCreator.createOFNodeConnector(
+                (short) 24, node);
+        byte srcMac[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
+                (byte) 0x9a, (byte) 0xbc };
+        byte dstMac[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
+                (byte) 0x5e, (byte) 0x6f };
+        InetAddress srcIP = InetAddress
+                .getByName("2001:420:281:1004:407a:57f4:4d15:c355");
+        InetAddress dstIP = InetAddress
+                .getByName("2001:420:281:1004:e123:e688:d655:a1b0");
+        InetAddress ipMasks = InetAddress
+                .getByName("ffff:ffff:ffff:ffff:0:0:0:0");
+        InetAddress ipMaskd = InetAddress
+                .getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0");
+        short ethertype = EtherTypes.IPv6.shortValue();
+        short vlan = (short) 27;
+        byte vlanPr = (byte) 3;
+        Byte tos = 4;
+        byte proto = IPProtocols.UDP.byteValue();
+        short src = (short) 5500;
+        short dst = 80;
+
+        /*
+         * Create a SAL Flow aFlow
+         */
+        Match match = new Match();
+        match.setField(MatchType.IN_PORT, port);
+        match.setField(MatchType.DL_SRC, srcMac);
+        match.setField(MatchType.DL_DST, dstMac);
+        match.setField(MatchType.DL_TYPE, ethertype);
+        match.setField(MatchType.DL_VLAN, vlan);
+        match.setField(MatchType.DL_VLAN_PR, vlanPr);
+        match.setField(MatchType.NW_SRC, srcIP, ipMasks);
+        match.setField(MatchType.NW_DST, dstIP, ipMaskd);
+        match.setField(MatchType.NW_TOS, tos);
+        match.setField(MatchType.NW_PROTO, proto);
+        match.setField(MatchType.TP_SRC, src);
+        match.setField(MatchType.TP_DST, dst);
+
+        Match flipped = match.reverse();
+
+        Assert.assertTrue(match.getField(MatchType.DL_TYPE).equals(
+                flipped.getField(MatchType.DL_TYPE)));
+        Assert.assertTrue(match.getField(MatchType.DL_VLAN).equals(
+                flipped.getField(MatchType.DL_VLAN)));
+
+        Assert.assertTrue(match.getField(MatchType.DL_DST).getValue().equals(
+                flipped.getField(MatchType.DL_SRC).getValue()));
+        Assert.assertTrue(match.getField(MatchType.DL_DST).getMask() == flipped
+                .getField(MatchType.DL_SRC).getMask());
+
+        Assert.assertTrue(match.getField(MatchType.NW_DST).getValue().equals(
+                flipped.getField(MatchType.NW_SRC).getValue()));
+        Assert.assertTrue(match.getField(MatchType.NW_DST).getMask() == flipped
+                .getField(MatchType.NW_SRC).getMask());
+
+        Assert.assertTrue(match.getField(MatchType.TP_DST).getValue().equals(
+                flipped.getField(MatchType.TP_SRC).getValue()));
+        Assert.assertTrue(match.getField(MatchType.TP_DST).getMask() == flipped
+                .getField(MatchType.TP_SRC).getMask());
+
+        Match flipflip = flipped.reverse().reverse();
+        Assert.assertTrue(flipflip.equals(flipped));
+
+    }
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/ARPTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/ARPTest.java
new file mode 100644 (file)
index 0000000..a51f448
--- /dev/null
@@ -0,0 +1,227 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.packet.ARP;
+
+import junit.framework.Assert;
+
+public class ARPTest {
+
+    @Test
+    public void testGetHardwareType() {
+        ARP arp = new ARP();
+        byte[] hardwaretype = { 8, 6 };
+        arp.hdrFieldsMap.put("HardwareType", hardwaretype);
+        short hwtype = arp.getHardwareType();
+        Assert.assertTrue(hwtype == 2054);
+    }
+
+    @Test
+    public void testGetProtocolType() {
+        ARP arp = new ARP();
+        byte[] protocoltype = { 8, 0 };
+        arp.hdrFieldsMap.put("ProtocolType", protocoltype);
+        short ptype = arp.getProtocolType();
+        Assert.assertTrue(ptype == 2048);
+    }
+
+    @Test
+    public void testGetHardwareAddressLength() {
+        ARP arp = new ARP();
+        byte[] hardwareaddresslength = { 48 };
+        arp.hdrFieldsMap.put("HardwareAddressLength", hardwareaddresslength);
+        byte hwaddrlength = arp.getHardwareAddressLength();
+        Assert.assertTrue(hwaddrlength == 48);
+    }
+
+    @Test
+    public void testGetProtocolAddressLength() {
+        ARP arp = new ARP();
+        byte[] protocoladdresslength = { 32 };
+        arp.hdrFieldsMap.put("ProtocolAddressLength", protocoladdresslength);
+        byte paddrlength = arp.getProtocolAddressLength();
+        Assert.assertTrue(paddrlength == 32);
+    }
+
+    @Test
+    public void testGetOpCode() {
+        ARP arp = new ARP();
+        byte[] opcode = { 0, 2 };
+        arp.hdrFieldsMap.put("OpCode", opcode);
+        short opCode = arp.getOpCode();
+        Assert.assertTrue(opCode == 2);
+    }
+
+    @Test
+    public void testGetSenderHardwareAddress() {
+        ARP arp = new ARP();
+        byte[] hardwareaddress = { 48, 50, 120, 15, 66, 80 };
+        arp.hdrFieldsMap.put("SenderHardwareAddress", hardwareaddress);
+        byte[] hwAddress = arp.getSenderHardwareAddress();
+        Assert.assertTrue(hwAddress[0] == 48);
+        Assert.assertTrue(hwAddress[1] == 50);
+        Assert.assertTrue(hwAddress[2] == 120);
+        Assert.assertTrue(hwAddress[3] == 15);
+        Assert.assertTrue(hwAddress[4] == 66);
+        Assert.assertTrue(hwAddress[5] == 80);
+    }
+
+    @Test
+    public void testGetSenderProtocolAddress() {
+        ARP arp = new ARP();
+        byte[] protocoladdress = { 50, 100, 10, 20, 40, 80 };
+        arp.hdrFieldsMap.put("SenderProtocolAddress", protocoladdress);
+        byte[] pAddress = arp.getSenderProtocolAddress();
+        Assert.assertTrue(pAddress[0] == 50);
+        Assert.assertTrue(pAddress[1] == 100);
+        Assert.assertTrue(pAddress[2] == 10);
+        Assert.assertTrue(pAddress[3] == 20);
+        Assert.assertTrue(pAddress[4] == 40);
+        Assert.assertTrue(pAddress[5] == 80);
+    }
+
+    @Test
+    public void testGetTargetHardwareAddress() {
+        ARP arp = new ARP();
+        byte[] hardwareaddress = { 48, 50, 120, 15, 66, 80 };
+        arp.hdrFieldsMap.put("TargetHardwareAddress", hardwareaddress);
+        byte[] hwAddress = arp.getTargetHardwareAddress();
+        Assert.assertTrue(hwAddress[0] == 48);
+        Assert.assertTrue(hwAddress[1] == 50);
+        Assert.assertTrue(hwAddress[2] == 120);
+        Assert.assertTrue(hwAddress[3] == 15);
+        Assert.assertTrue(hwAddress[4] == 66);
+        Assert.assertTrue(hwAddress[5] == 80);
+    }
+
+    @Test
+    public void testGetTargetProtocolAddress() {
+        ARP arp = new ARP();
+        byte[] protocoladdress = { 50, 100, 10, 20, 40, 80 };
+        arp.hdrFieldsMap.put("TargetProtocolAddress", protocoladdress);
+        byte[] pAddress = arp.getTargetProtocolAddress();
+        Assert.assertTrue(pAddress[0] == 50);
+        Assert.assertTrue(pAddress[1] == 100);
+        Assert.assertTrue(pAddress[2] == 10);
+        Assert.assertTrue(pAddress[3] == 20);
+        Assert.assertTrue(pAddress[4] == 40);
+        Assert.assertTrue(pAddress[5] == 80);
+    }
+
+    @Test
+    public void testSetHardwareType() {
+        ARP arp = new ARP();
+        short hwtype = 2054;
+        arp.setHardwareType(hwtype);
+        byte[] hardwaretype = arp.hdrFieldsMap.get("HardwareType");
+        Assert.assertTrue(hardwaretype[0] == 8);
+        Assert.assertTrue(hardwaretype[1] == 6);
+    }
+
+    @Test
+    public void testSetProtocolType() {
+        ARP arp = new ARP();
+        short ptype = 2048;
+        arp.setProtocolType(ptype);
+        byte[] protocoltype = arp.hdrFieldsMap.get("ProtocolType");
+        Assert.assertTrue(protocoltype[0] == 8);
+        Assert.assertTrue(protocoltype[1] == 0);
+    }
+
+    @Test
+    public void testSetHardwareAddressLength() {
+        ARP arp = new ARP();
+        byte hwaddrlength = 48;
+        arp.setHardwareAddressLength(hwaddrlength);
+        byte[] hardwareaddresslength = arp.hdrFieldsMap
+                .get("HardwareAddressLength");
+        Assert.assertTrue(hardwareaddresslength[0] == 48);
+    }
+
+    @Test
+    public void testSetProtocolAddressLength() {
+        ARP arp = new ARP();
+        byte PAddrlength = 32;
+        arp.setProtocolAddressLength(PAddrlength);
+        byte[] protocoladdresslength = arp.hdrFieldsMap
+                .get("ProtocolAddressLength");
+        Assert.assertTrue(protocoladdresslength[0] == 32);
+    }
+
+    @Test
+    public void testSetOpCode() {
+        ARP arp = new ARP();
+        short opCode = (short) 2;
+        arp.setOpCode(opCode);
+        byte[] opcode = arp.hdrFieldsMap.get("OpCode");
+        //System.out.println(opCode);
+        Assert.assertTrue(opcode[0] == 0);
+        Assert.assertTrue(opcode[1] == 2);
+    }
+
+    @Test
+    public void testSetSenderHardwareAddress() {
+        ARP arp = new ARP();
+        byte[] hardwareaddress = { 48, 50, 120, 15, 66, 80 };
+        arp.setSenderHardwareAddress(hardwareaddress);
+        byte[] hwAddress = arp.hdrFieldsMap.get("SenderHardwareAddress");
+        Assert.assertTrue(hwAddress[0] == 48);
+        Assert.assertTrue(hwAddress[1] == 50);
+        Assert.assertTrue(hwAddress[2] == 120);
+        Assert.assertTrue(hwAddress[3] == 15);
+        Assert.assertTrue(hwAddress[4] == 66);
+        Assert.assertTrue(hwAddress[5] == 80);
+    }
+
+    @Test
+    public void testSetSenderProtocolAddress() {
+        ARP arp = new ARP();
+        byte[] protocoladdress = { 50, 100, 10, 20, 40, 80 };
+        arp.setSenderProtocolAddress(protocoladdress);
+        byte[] pAddress = arp.hdrFieldsMap.get("SenderProtocolAddress");
+        Assert.assertTrue(pAddress[0] == 50);
+        Assert.assertTrue(pAddress[1] == 100);
+        Assert.assertTrue(pAddress[2] == 10);
+        Assert.assertTrue(pAddress[3] == 20);
+        Assert.assertTrue(pAddress[4] == 40);
+        Assert.assertTrue(pAddress[5] == 80);
+    }
+
+    @Test
+    public void testSetTargetHardwareAddress() {
+        ARP arp = new ARP();
+        byte[] hardwareaddress = { 48, 50, 120, 15, 66, 80 };
+        arp.setTargetHardwareAddress(hardwareaddress);
+        byte[] hwAddress = arp.hdrFieldsMap.get("TargetHardwareAddress");
+        Assert.assertTrue(hwAddress[0] == 48);
+        Assert.assertTrue(hwAddress[1] == 50);
+        Assert.assertTrue(hwAddress[2] == 120);
+        Assert.assertTrue(hwAddress[3] == 15);
+        Assert.assertTrue(hwAddress[4] == 66);
+        Assert.assertTrue(hwAddress[5] == 80);
+    }
+
+    @Test
+    public void testSetTargetProtocolAddress() {
+        ARP arp = new ARP();
+        byte[] protocoladdress = { 50, 100, 10, 20, 40, 80 };
+        arp.setTargetProtocolAddress(protocoladdress);
+        byte[] pAddress = arp.hdrFieldsMap.get("TargetProtocolAddress");
+        Assert.assertTrue(pAddress[0] == 50);
+        Assert.assertTrue(pAddress[1] == 100);
+        Assert.assertTrue(pAddress[2] == 10);
+        Assert.assertTrue(pAddress[3] == 20);
+        Assert.assertTrue(pAddress[4] == 40);
+        Assert.assertTrue(pAddress[5] == 80);
+    }
+
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/BitBufferHelperTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/BitBufferHelperTest.java
new file mode 100644 (file)
index 0000000..b1c5e94
--- /dev/null
@@ -0,0 +1,693 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.packet.BitBufferHelper;
+
+public class BitBufferHelperTest {
+
+    @Test
+    public void testGetByte() {
+        byte[] data = { 100 };
+        Assert.assertTrue(BitBufferHelper.getByte(data) == 100);
+    }
+
+    @Test
+    public void testGetBits() throws Exception {
+        byte[] data = { 10, 12, 14, 20, 55, 69, 82, 97, 109, 117, 127, -50 };
+        byte[] bits;
+
+        bits = BitBufferHelper.getBits(data, 88, 8); //BYTE extraOffsetBits = extranumBits = 0
+        Assert.assertTrue(bits[0] == -50);
+
+        bits = BitBufferHelper.getBits(data, 8, 16); //Short
+        Assert.assertTrue(bits[0] == 12);
+        Assert.assertTrue(bits[1] == 14);
+
+        bits = BitBufferHelper.getBits(data, 32, 32); //Int
+        Assert.assertTrue(bits[0] == 55);
+        Assert.assertTrue(bits[1] == 69);
+        Assert.assertTrue(bits[2] == 82);
+        Assert.assertTrue(bits[3] == 97);
+
+        bits = BitBufferHelper.getBits(data, 16, 48); //Long
+        Assert.assertTrue(bits[0] == 14);
+        Assert.assertTrue(bits[1] == 20);
+        Assert.assertTrue(bits[2] == 55);
+        Assert.assertTrue(bits[3] == 69);
+        Assert.assertTrue(bits[4] == 82);
+        Assert.assertTrue(bits[5] == 97);
+
+        bits = BitBufferHelper.getBits(data, 40, 7); //BYTE extraOffsetBits = extranumBits != 0
+        Assert.assertTrue(bits[0] == 34);
+
+        bits = BitBufferHelper.getBits(data, 8, 13); //Short
+        Assert.assertTrue(bits[0] == 1);
+        Assert.assertTrue(bits[1] == -127);
+
+        bits = BitBufferHelper.getBits(data, 32, 28); //Int
+        Assert.assertTrue(bits[0] == 3);
+        Assert.assertTrue(bits[1] == 116);
+        Assert.assertTrue(bits[2] == 85);
+        Assert.assertTrue(bits[3] == 38);
+
+        bits = BitBufferHelper.getBits(data, 16, 41); //Long
+        Assert.assertTrue(bits[0] == 0);
+        Assert.assertTrue(bits[1] == 28);
+        Assert.assertTrue(bits[2] == 40);
+        Assert.assertTrue(bits[3] == 110);
+        Assert.assertTrue(bits[4] == -118);
+        Assert.assertTrue(bits[5] == -92);
+
+        bits = BitBufferHelper.getBits(data, 3, 7); //BYTE extraOffsetBits != 0; extranumBits == 0
+        Assert.assertTrue(bits[0] == 40);
+
+        bits = BitBufferHelper.getBits(data, 13, 16); //Short
+        Assert.assertTrue(bits[0] == -127);
+        Assert.assertTrue(bits[1] == -62);
+
+        bits = BitBufferHelper.getBits(data, 5, 32); //Int
+        Assert.assertTrue(bits[0] == 65);
+        Assert.assertTrue(bits[1] == -127);
+        Assert.assertTrue(bits[2] == -62);
+        Assert.assertTrue(bits[3] == -122);
+
+        bits = BitBufferHelper.getBits(data, 23, 48); //Long
+        Assert.assertTrue(bits[0] == 10);
+        Assert.assertTrue(bits[1] == 27);
+        Assert.assertTrue(bits[2] == -94);
+        Assert.assertTrue(bits[3] == -87);
+        Assert.assertTrue(bits[4] == 48);
+        Assert.assertTrue(bits[5] == -74);
+
+        bits = BitBufferHelper.getBits(data, 66, 9); //BYTE extraOffsetBits != 0; extranumBits != 0
+        Assert.assertTrue(bits[0] == 1);
+        Assert.assertTrue(bits[1] == 107);
+
+        bits = BitBufferHelper.getBits(data, 13, 15); //Short
+        Assert.assertTrue(bits[0] == 64);
+        Assert.assertTrue(bits[1] == -31);
+
+        bits = BitBufferHelper.getBits(data, 5, 29); //Int
+        Assert.assertTrue(bits[0] == 8);
+        Assert.assertTrue(bits[1] == 48);
+        Assert.assertTrue(bits[2] == 56);
+        Assert.assertTrue(bits[3] == 80);
+
+        bits = BitBufferHelper.getBits(data, 31, 43); //Long
+        Assert.assertTrue(bits[0] == 0);
+        Assert.assertTrue(bits[1] == -35);
+        Assert.assertTrue(bits[2] == 21);
+        Assert.assertTrue(bits[3] == 73);
+        Assert.assertTrue(bits[4] == -123);
+        Assert.assertTrue(bits[5] == -75);
+
+        bits = BitBufferHelper.getBits(data, 4, 12); //Short
+        Assert.assertTrue(bits[0] == 10);
+        Assert.assertTrue(bits[1] == 12);
+
+        byte[] data1 = { 0, 8 };
+        bits = BitBufferHelper.getBits(data1, 7, 9); //Short
+        Assert.assertTrue(bits[0] == 0);
+        Assert.assertTrue(bits[1] == 8);
+
+        byte[] data2 = { 2, 8 };
+        bits = BitBufferHelper.getBits(data2, 0, 7); //Short
+        Assert.assertTrue(bits[0] == 1);
+
+        bits = BitBufferHelper.getBits(data2, 7, 9); //Short
+        Assert.assertTrue(bits[0] == 0);
+        Assert.assertTrue(bits[1] == 8);
+    }
+
+    // [01101100][01100000]
+    //     [01100011]
+    @Test
+    public void testGetBytes() throws Exception {
+        byte data[] = { 108, 96, 125, -112, 5, 6, 108, 8, 9, 10, 11, 12, 13,
+                14, 15, 16, 17, 18, 19, 20, 21, 22 };
+        byte[] x;
+
+        Assert.assertTrue(BitBufferHelper.getBits(data, 0, 8)[0] == 108);
+        Assert.assertTrue(BitBufferHelper.getBits(data, 8, 8)[0] == 96);
+
+        x = BitBufferHelper.getBits(data, 0, 10);
+        Assert.assertTrue(x[0] == 1);
+        Assert.assertTrue(x[1] == -79);
+
+        x = BitBufferHelper.getBits(data, 3, 8);
+        Assert.assertTrue(x[0] == 99);
+        //Assert.assertTrue(x[1] == 97);
+
+    }
+
+    @Test
+    public void testMSBMask() {
+        int numBits = 1; //MSB
+        int mask = BitBufferHelper.getMSBMask(numBits);
+        Assert.assertTrue(mask == 128);
+
+        numBits = 8;
+        mask = BitBufferHelper.getMSBMask(numBits);
+        Assert.assertTrue(mask == 255);
+
+        numBits = 2;
+        mask = BitBufferHelper.getMSBMask(numBits);
+        Assert.assertTrue(mask == 192);
+    }
+
+    @Test
+    public void testLSBMask() {
+        int numBits = 1; //LSB
+        int mask = BitBufferHelper.getLSBMask(numBits);
+        Assert.assertTrue(mask == 1);
+
+        numBits = 3;
+        mask = BitBufferHelper.getLSBMask(numBits);
+        Assert.assertTrue(mask == 7);
+
+        numBits = 8;
+        mask = BitBufferHelper.getLSBMask(numBits);
+        Assert.assertTrue(mask == 255);
+    }
+
+    @Test
+    public void testToByteArray() {
+        short sh = Short.MAX_VALUE;
+        byte[] data_sh = new byte[Byte.SIZE / 8];
+        data_sh = BitBufferHelper.toByteArray(sh);
+        Assert.assertTrue(data_sh[0] == 127);
+        Assert.assertTrue(data_sh[1] == -1);
+
+        short sh2 = Short.MIN_VALUE;
+        byte[] data_sh2 = new byte[Byte.SIZE / 8];
+        data_sh2 = BitBufferHelper.toByteArray(sh2);
+        Assert.assertTrue(data_sh2[0] == -128);
+        Assert.assertTrue(data_sh2[1] == 0);
+
+        short sh3 = 16384;
+        byte[] data_sh3 = new byte[Byte.SIZE / 8];
+        data_sh3 = BitBufferHelper.toByteArray(sh3);
+        Assert.assertTrue(data_sh3[0] == 64);
+        Assert.assertTrue(data_sh3[1] == 0);
+
+        short sh4 = 146; //TCP headerlenflags - startoffset = 103
+        byte[] data_sh4 = new byte[Byte.SIZE / 8];
+        data_sh4 = BitBufferHelper.toByteArray(sh4);
+        Assert.assertTrue(data_sh4[0] == 0);
+        Assert.assertTrue(data_sh4[1] == -110);
+
+        short sh4_2 = 5000; //IPv4 Offset - startOffset = 51 (to 63)
+        byte[] data_sh4_2 = new byte[Byte.SIZE / 8];
+        data_sh4_2 = BitBufferHelper.toByteArray(sh4_2);
+        Assert.assertTrue(data_sh4_2[0] == 19);
+        Assert.assertTrue(data_sh4_2[1] == -120);
+
+        short sh4_3 = 5312; //numEndRestBits < numBitstoShiftBy
+        byte[] data_sh4_3 = new byte[Byte.SIZE / 8];
+        data_sh4_3 = BitBufferHelper.toByteArray(sh4_3);
+        Assert.assertTrue(data_sh4_3[0] == 20);
+        Assert.assertTrue(data_sh4_3[1] == -64);
+
+        int Int = Integer.MAX_VALUE;
+        byte[] data_Int = new byte[Integer.SIZE / 8];
+        data_Int = BitBufferHelper.toByteArray(Int);
+        Assert.assertTrue(data_Int[0] == 127);
+        Assert.assertTrue(data_Int[1] == -1);
+        Assert.assertTrue(data_Int[2] == -1);
+        Assert.assertTrue(data_Int[3] == -1);
+
+        int Int2 = Integer.MIN_VALUE;
+        byte[] data_Int2 = new byte[Integer.SIZE / 8];
+        data_Int2 = BitBufferHelper.toByteArray(Int2);
+        Assert.assertTrue(data_Int2[0] == -128);
+        Assert.assertTrue(data_Int2[1] == 0);
+        Assert.assertTrue(data_Int2[2] == 0);
+        Assert.assertTrue(data_Int2[3] == 0);
+
+        int Int3 = 1077952576;
+        byte[] data_Int3 = new byte[Integer.SIZE / 8];
+        data_Int3 = BitBufferHelper.toByteArray(Int3);
+        Assert.assertTrue(data_Int3[0] == 64);
+        Assert.assertTrue(data_Int3[1] == 64);
+        Assert.assertTrue(data_Int3[2] == 64);
+        Assert.assertTrue(data_Int3[3] == 64);
+
+        long Lng = Long.MAX_VALUE;
+        byte[] data_lng = new byte[Long.SIZE / 8];
+        data_lng = BitBufferHelper.toByteArray(Lng);
+        Assert.assertTrue(data_lng[0] == 127);
+        Assert.assertTrue(data_lng[1] == -1);
+        Assert.assertTrue(data_lng[2] == -1);
+        Assert.assertTrue(data_lng[3] == -1);
+        Assert.assertTrue(data_lng[4] == -1);
+        Assert.assertTrue(data_lng[5] == -1);
+        Assert.assertTrue(data_lng[6] == -1);
+        Assert.assertTrue(data_lng[7] == -1);
+
+        long Lng2 = Long.MIN_VALUE;
+        byte[] data_lng2 = new byte[Long.SIZE / 8];
+        data_lng2 = BitBufferHelper.toByteArray(Lng2);
+        Assert.assertTrue(data_lng2[0] == -128);
+        Assert.assertTrue(data_lng2[1] == 0);
+        Assert.assertTrue(data_lng2[2] == 0);
+        Assert.assertTrue(data_lng2[3] == 0);
+        Assert.assertTrue(data_lng2[4] == 0);
+        Assert.assertTrue(data_lng2[5] == 0);
+        Assert.assertTrue(data_lng2[6] == 0);
+        Assert.assertTrue(data_lng2[7] == 0);
+
+        byte B = Byte.MAX_VALUE;
+        byte[] data_B = new byte[Byte.SIZE / 8];
+        data_B = BitBufferHelper.toByteArray(B);
+        Assert.assertTrue(data_B[0] == 127);
+
+        byte B1 = Byte.MIN_VALUE;
+        byte[] data_B1 = new byte[Byte.SIZE / 8];
+        data_B1 = BitBufferHelper.toByteArray(B1);
+        Assert.assertTrue(data_B1[0] == -128);
+
+        byte B2 = 64;
+        byte[] data_B2 = new byte[Byte.SIZE / 8];
+        data_B2 = BitBufferHelper.toByteArray(B2);
+        Assert.assertTrue(data_B2[0] == 64);
+
+        byte B3 = 32;
+        byte[] data_B3 = new byte[Byte.SIZE / 8];
+        data_B3 = BitBufferHelper.toByteArray(B3);
+        Assert.assertTrue(data_B3[0] == 32);
+
+    }
+
+    @Test
+    public void testToByteArrayVariable() {
+        int len = 9;
+        byte[] data_sh;
+        data_sh = BitBufferHelper.toByteArray(511, len);
+        Assert.assertTrue(data_sh[0] == (byte) 255);
+        Assert.assertTrue(data_sh[1] == (byte) 128);
+
+        data_sh = BitBufferHelper.toByteArray((int) 511, len);
+        Assert.assertTrue(data_sh[0] == (byte) 255);
+        Assert.assertTrue(data_sh[1] == (byte) 128);
+
+        data_sh = BitBufferHelper.toByteArray((long) 511, len);
+        Assert.assertTrue(data_sh[0] == (byte) 255);
+        Assert.assertTrue(data_sh[1] == (byte) 128);
+    }
+
+    @Test
+    public void testToInt() {
+        byte data[] = { 1 };
+        Assert.assertTrue(BitBufferHelper.toNumber(data) == 1);
+
+        byte data2[] = { 1, 1 };
+        Assert.assertTrue(BitBufferHelper.toNumber(data2) == 257);
+
+        byte data3[] = { 1, 1, 1 };
+        Assert.assertTrue(BitBufferHelper.toNumber(data3) == 65793);
+    }
+
+    @Test
+    public void testToLongGetter() {
+        byte data[] = { 1, 1 };
+        Assert.assertTrue(BitBufferHelper.getLong(data) == 257L);
+    }
+
+    @Test
+    public void testSetByte() throws Exception {
+        byte input;
+        byte[] data = new byte[20];
+
+        input = 125;
+        BitBufferHelper.setByte(data, input, 0, Byte.SIZE);
+        Assert.assertTrue(data[0] == 125);
+
+        input = 109;
+        BitBufferHelper.setByte(data, input, 152, Byte.SIZE);
+        Assert.assertTrue(data[19] == 109);
+    }
+
+    @Test
+    public void testSetBytes() throws Exception {
+        byte[] input = { 0, 1 };
+        byte[] data = { 6, 0 };
+
+        BitBufferHelper.setBytes(data, input, 7, 9);
+        Assert.assertTrue(data[0] == 6);
+        Assert.assertTrue(data[1] == 1);
+    }
+
+    //@Test
+    //INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+    // [01001011] [01101110] [01101011] [10100000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]*/
+    public void testInsertBits() throws Exception {
+        //CASE 1: startOffset%8 == 0 && numBits%8 == 0
+        byte inputdata[] = { 75, 110, 107, 80, 10, 12, 35, 100, 125, 65 };
+        int startOffset = 0;
+        int numBits = 8;
+
+        byte data1[] = new byte[2];
+        startOffset = 0;
+        numBits = 16;
+        BitBufferHelper.insertBits(data1, inputdata, startOffset, numBits);
+        Assert.assertTrue(data1[0] == 75);
+        Assert.assertTrue(data1[1] == 110);
+
+        byte data2[] = new byte[4];
+        startOffset = 0;
+        numBits = 32;
+        BitBufferHelper.insertBits(data2, inputdata, startOffset, numBits);
+        Assert.assertTrue(data2[0] == 75);
+        Assert.assertTrue(data2[1] == 110);
+        Assert.assertTrue(data2[2] == 107);
+        Assert.assertTrue(data2[3] == 80);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [10100000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               // OUTPUT: [01001011] [01101000] = {75, 104}
+        byte data10[] = new byte[2];
+        startOffset = 0;
+        numBits = 13;
+        BitBufferHelper.insertBits(data10, inputdata, startOffset, numBits);
+        Assert.assertTrue(data10[0] == 75);
+        Assert.assertTrue(data10[1] == 104);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [10100000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               // OUTPUT: [01001000] = {72}
+        byte data11[] = new byte[4];
+        startOffset = 8;
+        numBits = 6;
+        BitBufferHelper.insertBits(data11, inputdata, startOffset, numBits);
+        Assert.assertTrue(data11[1] == 72);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [10100000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [01001011] [01101110] [01101000] = {75, 110, 105}
+        byte data12[] = new byte[4];
+        startOffset = 0;
+        numBits = 23;
+        BitBufferHelper.insertBits(data12, inputdata, startOffset, numBits);
+        Assert.assertTrue(data12[0] == 75);
+        Assert.assertTrue(data12[1] == 110);
+        Assert.assertTrue(data12[2] == 106);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [10100000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [01001011] [01101110] [01100000] = {75, 110, 96}
+        byte data13[] = new byte[4];
+        startOffset = 8;
+        numBits = 20;
+        BitBufferHelper.insertBits(data13, inputdata, startOffset, numBits);
+        Assert.assertTrue(data13[1] == 75);
+        Assert.assertTrue(data13[2] == 110);
+        Assert.assertTrue(data13[3] == 96);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [10100000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [01001011] [01101110] [01101011] [10100000]= {75, 110, 107, 80}
+        byte data14[] = new byte[4];
+        startOffset = 0;
+        numBits = 30;
+        BitBufferHelper.insertBits(data14, inputdata, startOffset, numBits);
+        Assert.assertTrue(data14[0] == 75);
+        Assert.assertTrue(data14[1] == 110);
+        Assert.assertTrue(data14[2] == 107);
+        Assert.assertTrue(data14[3] == 80);
+
+        //CASE 3: startOffset%8 != 0, numBits%8 = 0
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [10100000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [00001001] [11000000] = {72, 96}
+        byte data16[] = new byte[5];
+        startOffset = 3;
+        numBits = 8;
+        BitBufferHelper.insertBits(data16, inputdata, startOffset, numBits);
+        Assert.assertTrue(data16[0] == 9);
+        Assert.assertTrue(data16[1] == 96);
+        Assert.assertTrue(data16[2] == 0);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [01010000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [00000000] [00000100] [10110110] [11100000]= {0, 4, -54, -96}
+        // OUTPUT: [00000100] [1011 0110] [1110 0000] = {4, -54, -96}
+
+        startOffset = 3;
+        numBits = 16;
+        byte data17[] = new byte[5];
+        BitBufferHelper.insertBits(data17, inputdata, startOffset, numBits);
+        Assert.assertTrue(data17[0] == 9);
+        Assert.assertTrue(data17[1] == 109);
+        Assert.assertTrue(data17[2] == -64);
+        Assert.assertTrue(data17[3] == 0);
+
+        // INPUT: {79, 110, 111}
+        // = [01001111] [01101110] [01101111]
+        //OUTPUT: [0000 1001] [1110 1101] [110 00000] = {9, -19, -64}
+        byte data18[] = new byte[5];
+        byte inputdata3[] = { 79, 110, 111 };
+        startOffset = 3;
+        numBits = 16;
+        BitBufferHelper.insertBits(data18, inputdata3, startOffset, numBits);
+        Assert.assertTrue(data18[0] == 9);
+        Assert.assertTrue(data18[1] == -19);
+        Assert.assertTrue(data18[2] == -64);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [01010000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [00000000] [00000100] [10110110] [11100000]= {0, 4, -54, -96}
+        // OUTPUT: [0000 1001] [0110 1101] [1100 1101] [0110 1010] [0000 0001] = {9, 109, -51, 106, 0}
+
+        startOffset = 3;
+        numBits = 32;
+        byte data19[] = new byte[5];
+        BitBufferHelper.insertBits(data19, inputdata, startOffset, numBits);
+        Assert.assertTrue(data19[0] == 9);
+        Assert.assertTrue(data19[1] == 109);
+        Assert.assertTrue(data19[2] == -51);
+        Assert.assertTrue(data19[3] == 106);
+        Assert.assertTrue(data19[4] == 0);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [01010000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [00000000] [00000100] [10110110] [11100000]= {0, 4, -54, -96}
+        // OUTPUT: data[4, 5, 6] = [0 010 0101] [1 011 0111] [0 000 0000] = {37, -73, 0}
+        startOffset = 33;
+        numBits = 16;
+        byte data20[] = new byte[7];
+        BitBufferHelper.insertBits(data20, inputdata, startOffset, numBits);
+        Assert.assertTrue(data20[4] == 37);
+        Assert.assertTrue(data20[5] == -73);
+        Assert.assertTrue(data20[6] == 0);
+
+        //CASE 4: extranumBits != 0 AND extraOffsetBits != 0
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [01010000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [00000000] [00000100] [10110110] [11100000]= {0, 4, -54, -96}
+        // OUTPUT: [0000 1001] [0100 0000]  = {9, 96}
+        startOffset = 3;
+        numBits = 7;
+        byte data21[] = new byte[7];
+        BitBufferHelper.insertBits(data21, inputdata, startOffset, numBits);
+        Assert.assertTrue(data21[0] == 9);
+        Assert.assertTrue(data21[1] == 64);
+        Assert.assertTrue(data21[2] == 0);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [01010000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [00000000] [00000100] [10110110] [11100000]= {0, 4, -54, -96}
+        // OUTPUT: data = [00000 010] [01011 011] [01110 000] = {37, -73, 0}
+        startOffset = 5;
+        numBits = 17;
+        byte data22[] = new byte[7];
+        BitBufferHelper.insertBits(data22, inputdata, startOffset, numBits);
+        Assert.assertTrue(data22[0] == 2);
+        Assert.assertTrue(data22[1] == 91);
+        Assert.assertTrue(data22[2] == 112);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [01010000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [00000000] [00000100] [10110110] [11100000]= {0, 4, -54, -96}
+        // OUTPUT: [0000 1001] [0110 1101] [110 01101] [01 00000] = {9, 109, -51, 64}
+        startOffset = 3;
+        numBits = 23;
+        byte data23[] = new byte[7];
+        BitBufferHelper.insertBits(data23, inputdata, startOffset, numBits);
+        Assert.assertTrue(data23[0] == 9);
+        Assert.assertTrue(data23[1] == 109);
+        Assert.assertTrue(data23[2] == -51);
+        Assert.assertTrue(data23[3] == 64);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [01010000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [00000000] [00000100] [10110110] [11100000]= {0, 4, -54, -96}
+        // OUTPUT: [0000 1001] [0110 1101]  = {9, 109}
+        startOffset = 3;
+        numBits = 13;
+        byte data24[] = new byte[7];
+        BitBufferHelper.insertBits(data24, inputdata, startOffset, numBits);
+        Assert.assertTrue(data24[0] == 9);
+        Assert.assertTrue(data24[1] == 109);
+        Assert.assertTrue(data24[2] == 0);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [01010000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [00000000] [00000100] [10110110] [11100000]= {0, 4, -54, -96}
+        // OUTPUT: [0000 0100] [1011 0110] [1110 0110]  = {4, -74, -26}
+        startOffset = 4;
+        numBits = 20;
+        byte data25[] = new byte[7];
+        BitBufferHelper.insertBits(data25, inputdata, startOffset, numBits);
+        Assert.assertTrue(data25[0] == 4);
+        Assert.assertTrue(data25[1] == -74);
+        Assert.assertTrue(data25[2] == -26);
+        Assert.assertTrue(data25[3] == -0);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [01010000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [00000000] [00000100] [10110110] [11100000]= {0, 4, -54, -96}
+        // OUTPUT: [0000 0010] [0101 1011]   = {0, 2, 91, 0}
+        startOffset = 13;
+        numBits = 11;
+        byte data26[] = new byte[7];
+        BitBufferHelper.insertBits(data26, inputdata, startOffset, numBits);
+        Assert.assertTrue(data26[0] == 0);
+        Assert.assertTrue(data26[1] == 2);
+        Assert.assertTrue(data26[2] == 91);
+        Assert.assertTrue(data26[3] == 0);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [01010000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [00000000] [00000100] [10110110] [11100000]= {0, 4, -54, -96}
+        // OUTPUT: [000 01001] [011 01101] [110 0 0000]   = {9, 109, -64, 0}
+        startOffset = 3;
+        numBits = 17;
+        byte data27[] = new byte[7];
+        BitBufferHelper.insertBits(data27, inputdata, startOffset, numBits);
+        Assert.assertTrue(data27[0] == 9);
+        Assert.assertTrue(data27[1] == 109);
+        Assert.assertTrue(data27[2] == -64);
+        Assert.assertTrue(data27[3] == 0);
+
+        // INPUT: {75, 110, 107, 80, 10, 12, 35, 100, 125, 65} =
+        // [01001011] [01101110] [01101011] [01010000] [00001010] [00001100] [00100011] [01100100] [11111101] [01000001]               //OUTPUT: [00000000] [00000100] [10110110] [11100000]= {0, 4, -54, -96}
+        // OUTPUT: [00 000000] [00 000000] [00 010010] [11 011011] [10 011010] [11 010100] [0000 0000] = {0, 0, 18, -37,-102,-44,0}
+        startOffset = 18;
+        numBits = 34;
+        byte data28[] = new byte[7];
+        BitBufferHelper.insertBits(data28, inputdata, startOffset, numBits);
+        Assert.assertTrue(data28[0] == 0);
+        Assert.assertTrue(data28[1] == 0);
+        Assert.assertTrue(data28[2] == 18);
+        Assert.assertTrue(data28[3] == -37);
+        Assert.assertTrue(data28[4] == -102);
+        Assert.assertTrue(data28[5] == -44);
+        Assert.assertTrue(data28[6] == 0);
+
+    }
+
+    @Test
+    public void testGetShort() throws Exception {
+        byte data[] = new byte[2];
+        data[0] = 7;
+        data[1] = 8;
+        int length = 9; // num bits
+        Assert.assertTrue(BitBufferHelper.getShort(data, length) == 264);
+
+        data[0] = 6;
+        data[1] = 8;
+        short result = BitBufferHelper.getShort(data, length);
+        Assert.assertTrue(result == 8);
+
+        data[0] = 8;
+        data[1] = 47;
+        result = BitBufferHelper.getShort(data, length);
+        Assert.assertTrue(result == 47);
+
+        //[0000 0001] [0001 0100] [0110 0100]
+        byte[] data1 = new byte[2];
+        data1[0] = 1;
+        data1[1] = 20; //data1[2] = 100;
+        length = 15;
+        result = BitBufferHelper.getShort(data1, length);
+        Assert.assertTrue(result == 276);
+
+        byte[] data2 = new byte[2];
+        data2[0] = 64;
+        data2[1] = 99; //data2[2] = 100;
+        length = 13;
+        result = BitBufferHelper.getShort(data2, length);
+        Assert.assertTrue(result == 99);
+
+        byte[] data3 = { 100, 50 };
+        result = BitBufferHelper.getShort(data3);
+        Assert.assertTrue(result == 25650);
+    }
+
+    @Test
+    public void testToIntVarLength() throws Exception {
+        byte data[] = { (byte) 255, (byte) 128 };
+        int length = 9; // num bits
+        Assert.assertTrue(BitBufferHelper.getInt(data, length) == 384);
+
+        byte data2[] = { 0, 8 };
+        Assert.assertTrue(BitBufferHelper.getInt(data2, 9) == 8);
+
+        byte data3[] = { 1, 1, 1 };
+        Assert.assertTrue(BitBufferHelper.getInt(data3) == 65793);
+
+        byte data4[] = { 1, 1, 1 };
+        Assert.assertTrue(BitBufferHelper.getInt(data4) == 65793);
+
+        byte data5[] = { 1, 1 };
+        Assert.assertTrue(BitBufferHelper.getInt(data5) == 257);
+
+    }
+
+    @Test
+    public void testShiftBitstoLSB() {
+        byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+
+        byte[] data2 = { 8, 9, 10 };
+        byte[] shiftedBytes2 = BitBufferHelper.shiftBitsToLSB(data2, 11);
+
+        Assert.assertTrue(shiftedBytes2[0] == 0);
+        Assert.assertTrue(shiftedBytes2[1] == 64);
+        Assert.assertTrue(shiftedBytes2[2] == 72);
+
+        byte[] shiftedBytes = BitBufferHelper.shiftBitsToLSB(data, 49);
+
+        Assert.assertTrue(shiftedBytes[0] == 0);
+        Assert.assertTrue(shiftedBytes[1] == 2);
+        Assert.assertTrue(shiftedBytes[2] == 4);
+        Assert.assertTrue(shiftedBytes[3] == 6);
+        Assert.assertTrue(shiftedBytes[4] == 8);
+        Assert.assertTrue(shiftedBytes[5] == 10);
+        Assert.assertTrue(shiftedBytes[6] == 12);
+        Assert.assertTrue(shiftedBytes[7] == 14);
+        Assert.assertTrue(shiftedBytes[8] == 16);
+        Assert.assertTrue(shiftedBytes[9] == 18);
+
+        byte[] data1 = { 1, 2, 3 };
+        byte[] shiftedBytes1 = BitBufferHelper.shiftBitsToLSB(data1, 18);
+        Assert.assertTrue(shiftedBytes1[0] == 0);
+        Assert.assertTrue(shiftedBytes1[1] == 4);
+        Assert.assertTrue(shiftedBytes1[2] == 8);
+
+    }
+
+    @Test
+    public void testShiftBitstoLSBMSB() {
+        byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
+
+        byte[] clone = BitBufferHelper.shiftBitsToMSB(BitBufferHelper
+                .shiftBitsToLSB(data, 72), 72);
+
+        Assert.assertTrue(clone[0] == 1);
+        Assert.assertTrue(clone[1] == 2);
+        Assert.assertTrue(clone[2] == 3);
+        Assert.assertTrue(clone[3] == 4);
+        Assert.assertTrue(clone[4] == 5);
+        Assert.assertTrue(clone[5] == 6);
+        Assert.assertTrue(clone[6] == 7);
+        Assert.assertTrue(clone[7] == 8);
+        Assert.assertTrue(clone[8] == 9);
+        Assert.assertTrue(clone[9] == 0);
+    }
+
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/EthernetTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/EthernetTest.java
new file mode 100644 (file)
index 0000000..61d5baa
--- /dev/null
@@ -0,0 +1,99 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.packet.Ethernet;
+
+public class EthernetTest {
+
+    @Test
+    public void testGetDestinationMACAddress() {
+        Ethernet eth = new Ethernet();
+        byte mac[] = { 10, 12, 14, 20, 55, 69 };
+        eth.hdrFieldsMap.put("DestinationMACAddress", mac);
+        byte[] dMAC = eth.getDestinationMACAddress();
+        Assert.assertTrue(dMAC[0] == 10);
+        Assert.assertTrue(dMAC[1] == 12);
+        Assert.assertTrue(dMAC[2] == 14);
+        Assert.assertTrue(dMAC[3] == 20);
+        Assert.assertTrue(dMAC[4] == 55);
+        Assert.assertTrue(dMAC[5] == 69);
+
+    }
+
+    @Test
+    public void testSourceMACAddress() {
+        Ethernet eth = new Ethernet();
+        byte mac[] = { 120, 30, 25, 80, 66, 99 };
+        eth.hdrFieldsMap.put("SourceMACAddress", mac);
+        byte[] sMAC = eth.getSourceMACAddress();
+        Assert.assertTrue(sMAC[0] == 120);
+        Assert.assertTrue(sMAC[1] == 30);
+        Assert.assertTrue(sMAC[2] == 25);
+        Assert.assertTrue(sMAC[3] == 80);
+        Assert.assertTrue(sMAC[4] == 66);
+        Assert.assertTrue(sMAC[5] == 99);
+
+    }
+
+    @Test
+    public void testGetEthertype() throws Exception {
+        Ethernet eth = new Ethernet();
+        byte ethType[] = { 8, 6 };
+        eth.hdrFieldsMap.put("EtherType", ethType);
+        short etherType = eth.getEtherType();
+        Assert.assertTrue(etherType == 2054);
+    }
+
+    @Test
+    public void testSetDestinationMACAddress() {
+        Ethernet eth = new Ethernet();
+        byte mac[] = { 10, 12, 14, 20, 55, 69 };
+        eth.setDestinationMACAddress(mac);
+        byte[] dMAC = eth.hdrFieldsMap.get("DestinationMACAddress");
+        Assert.assertTrue(dMAC[0] == 10);
+        Assert.assertTrue(dMAC[1] == 12);
+        Assert.assertTrue(dMAC[2] == 14);
+        Assert.assertTrue(dMAC[3] == 20);
+        Assert.assertTrue(dMAC[4] == 55);
+        Assert.assertTrue(dMAC[5] == 69);
+
+    }
+
+    @Test
+    public void testSetSourceMACAddress() {
+        Ethernet eth = new Ethernet();
+        byte mac[] = { 120, 30, 25, 80, 66, 99 };
+        eth.setSourceMACAddress(mac);
+        byte[] sMAC = eth.hdrFieldsMap.get("SourceMACAddress");
+        Assert.assertTrue(sMAC[0] == 120);
+        Assert.assertTrue(sMAC[1] == 30);
+        Assert.assertTrue(sMAC[2] == 25);
+        Assert.assertTrue(sMAC[3] == 80);
+        Assert.assertTrue(sMAC[4] == 66);
+        Assert.assertTrue(sMAC[5] == 99);
+
+    }
+
+    @Test
+    public void testSetEthertype() throws Exception {
+        Ethernet eth = new Ethernet();
+        short ethType = 2054;
+        eth.setEtherType(ethType);
+        byte[] etherType = eth.hdrFieldsMap.get("EtherType");
+        Assert.assertTrue(etherType[0] == 8);
+        Assert.assertTrue(etherType[1] == 6);
+
+    }
+
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/ICMPTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/ICMPTest.java
new file mode 100644 (file)
index 0000000..445f721
--- /dev/null
@@ -0,0 +1,62 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.packet.ICMP;
+
+public class ICMPTest {
+
+    @Test
+    public void testSetTypeCode() {
+        ICMP icmp = new ICMP();
+        short icmpTypeCode = 2;
+        icmp.setTypeCode(icmpTypeCode);
+        byte[] typeCode = icmp.hdrFieldsMap.get("TypeCode");
+        Assert.assertTrue(typeCode[0] == 0);
+        Assert.assertTrue(typeCode[1] == 2);
+
+    }
+
+    @Test
+    public void testSetChecksum() {
+        ICMP icmp = new ICMP();
+        short icmpChecksum = 200;
+        icmp.setChecksum(icmpChecksum);
+        byte[] checksum = icmp.hdrFieldsMap.get("HeaderChecksum");
+        Assert.assertTrue(checksum[0] == 0);
+        Assert.assertTrue(checksum[1] == -56);
+
+    }
+
+    @Test
+    public void testSetIdentifier() {
+        ICMP icmp = new ICMP();
+        short icmpIdentifier = 1201;
+        icmp.setIdentifier(icmpIdentifier);
+        byte[] identifier = icmp.hdrFieldsMap.get("Identifier");
+        Assert.assertTrue(identifier[0] == 4);
+        Assert.assertTrue(identifier[1] == -79);
+
+    }
+
+    @Test
+    public void testSetSequenceNumber() {
+        ICMP icmp = new ICMP();
+        short icmpSequenceNumber = 5000;
+        icmp.setSequenceNumber(icmpSequenceNumber);
+        byte[] sequenceNumber = icmp.hdrFieldsMap.get("SequenceNumber");
+        Assert.assertTrue(sequenceNumber[0] == 19);
+        Assert.assertTrue(sequenceNumber[1] == -120);
+
+    }
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/IPv4Test.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/IPv4Test.java
new file mode 100644 (file)
index 0000000..beeb7d1
--- /dev/null
@@ -0,0 +1,222 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.packet.ICMP;
+import org.opendaylight.controller.sal.packet.IPv4;
+import org.opendaylight.controller.sal.packet.Packet;
+
+public class IPv4Test {
+
+    @Test
+    public void testGetVersion() {
+        IPv4 ip = new IPv4();
+        byte[] ipVersion = { (byte) 4 };
+        ip.hdrFieldsMap.put("Version", ipVersion);
+        byte version = ip.getVersion();
+        Assert.assertTrue(version == (byte) 4);
+    }
+
+    @Test
+    public void testGetHeaderLength() {
+        IPv4 ip = new IPv4();
+        byte[] ipHeaderLength = { 5 };
+        ip.hdrFieldsMap.put("HeaderLength", ipHeaderLength);
+        byte headerLength = (byte) ip.getHeaderLen();
+        Assert.assertTrue(headerLength == 20);
+    }
+
+    @Test
+    public void testGetDiffServ() {
+        IPv4 ip = new IPv4();
+        byte[] ipDiffServ = { 20 };
+        ip.hdrFieldsMap.put("DiffServ", ipDiffServ);
+        byte diffServ = ip.getDiffServ();
+        Assert.assertTrue(diffServ == 20);
+    }
+
+    @Test
+    public void testGetTotalLength() {
+        IPv4 ip = new IPv4();
+        byte[] iptotLength = { 3, -24 };
+        ip.hdrFieldsMap.put("TotalLength", iptotLength);
+        short totalLength = ip.getTotalLength();
+        //System.out.println(totalLength);
+        Assert.assertTrue(totalLength == 1000);
+    }
+
+    @Test
+    public void testGetIdentification() {
+        IPv4 ip = new IPv4();
+        byte[] ipIdentification = { 7, -48 };
+        ip.hdrFieldsMap.put("Identification", ipIdentification);
+        short identification = ip.getIdentification();
+        Assert.assertTrue(identification == 2000);
+    }
+
+    @Test
+    public void testGetFlags() {
+        IPv4 ip = new IPv4();
+        byte[] ipFlags = { 7 };
+        ip.hdrFieldsMap.put("Flags", ipFlags);
+        byte flags = ip.getFlags();
+        Assert.assertTrue(flags == 7);
+    }
+
+    @Test
+    public void testGetTtl() {
+        IPv4 ip = new IPv4();
+        byte[] ipTtl = { 100 };
+        ip.hdrFieldsMap.put("TTL", ipTtl);
+        byte ttl = ip.getTtl();
+        Assert.assertTrue(ttl == 100);
+    }
+
+    @Test
+    public void testGetProtocol() {
+        IPv4 ip = new IPv4();
+        byte[] ipProtocol = { 1 };
+        ip.hdrFieldsMap.put("Protocol", ipProtocol);
+        byte protocol = ip.getProtocol();
+        Assert.assertTrue(protocol == 1);
+
+        Class<? extends Packet> clazz = ip.protocolClassMap.get(protocol);
+        System.out.printf("clazz = %s\n", clazz.getName());
+        Assert.assertTrue(clazz == ICMP.class);
+    }
+
+    @Test
+    public void testGetFragmentOffset() {
+        IPv4 ip = new IPv4();
+        byte[] ipFragmentOffset = { 6, -35 };
+        ip.hdrFieldsMap.put("FragmentOffset", ipFragmentOffset);
+        short fragmentOffset = ip.getFragmentOffset();
+        Assert.assertTrue(fragmentOffset == 1757);
+    }
+
+    @Test
+    public void testGetSourceAddress() {
+        IPv4 ip = new IPv4();
+        byte[] ipSourceAddress = { 10, 110, 31, 55 };
+        ip.hdrFieldsMap.put("SourceIPAddress", ipSourceAddress);
+        int sourceAddress = ip.getSourceAddress();
+        Assert.assertTrue(sourceAddress == 174989111);
+    }
+
+    @Test
+    public void testGetDestinationAddress() {
+        IPv4 ip = new IPv4();
+        byte[] ipDestinationAddress = { 20, 55, 62, 110 };
+        ip.hdrFieldsMap.put("DestinationIPAddress", ipDestinationAddress);
+        int destinationAddress = ip.getDestinationAddress();
+        Assert.assertTrue(destinationAddress == 339164782);
+    }
+
+    @Test
+    public void testSetVersion() {
+        IPv4 ip = new IPv4();
+        byte ipVersion = (byte) 4;
+        ip.setVersion(ipVersion);
+        byte[] version = ip.hdrFieldsMap.get("Version");
+        Assert.assertTrue(version[0] == (byte) 4);
+    }
+
+    @Test
+    public void testSetHeaderLength() {
+        IPv4 ip = new IPv4();
+        byte ipHeaderLength = 5;
+        ip.setHeaderLength(ipHeaderLength);
+        byte[] headerLength = ip.hdrFieldsMap.get("HeaderLength");
+        Assert.assertTrue(headerLength[0] == 5);
+    }
+
+    @Test
+    public void testSetDiffServ() {
+        IPv4 ip = new IPv4();
+        byte ipDiffServ = 20;
+        ip.setDiffServ(ipDiffServ);
+        byte[] diffServ = ip.hdrFieldsMap.get("DiffServ");
+        Assert.assertTrue(diffServ[0] == 20);
+    }
+
+    @Test
+    public void testSetTotalLength() {
+        IPv4 ip = new IPv4();
+        short iptotLength = 1000;
+        ip.setTotalLength(iptotLength);
+        byte[] totalLength = ip.hdrFieldsMap.get("TotalLength");
+        Assert.assertTrue(totalLength[0] == 3);
+        Assert.assertTrue(totalLength[1] == -24);
+    }
+
+    @Test
+    public void testSetIdentification() {
+        IPv4 ip = new IPv4();
+        short ipIdentification = 2000;
+        ip.setIdentification(ipIdentification);
+        byte[] identification = ip.hdrFieldsMap.get("Identification");
+        Assert.assertTrue(identification[0] == 7);
+        Assert.assertTrue(identification[1] == -48);
+    }
+
+    @Test
+    public void testSetFlags() {
+        IPv4 ip = new IPv4();
+        byte ipFlags = 7;
+        ip.setFlags(ipFlags);
+        byte[] flags = ip.hdrFieldsMap.get("Flags");
+        Assert.assertTrue(flags[0] == 7);
+    }
+
+    @Test
+    public void testSetTtl() {
+        IPv4 ip = new IPv4();
+        byte ipTtl = 100;
+        ip.setTtl(ipTtl);
+        byte[] ttl = ip.hdrFieldsMap.get("TTL");
+        Assert.assertTrue(ttl[0] == 100);
+    }
+
+    @Test
+    public void testSetProtocol() {
+        IPv4 ip = new IPv4();
+        byte ipProtocol = 11;
+        ip.setProtocol(ipProtocol);
+        byte[] protocol = ip.hdrFieldsMap.get("Protocol");
+        Assert.assertTrue(protocol[0] == 11);
+    }
+
+    @Test
+    public void testSetFragmentOffset() {
+        IPv4 ip = new IPv4();
+        short ipFragmentOffset = 1757;
+        ip.setFragmentOffset(ipFragmentOffset);
+        byte[] fragmentOffset = ip.hdrFieldsMap.get("FragmentOffset");
+        Assert.assertTrue(fragmentOffset[0] == 6);
+        Assert.assertTrue(fragmentOffset[1] == -35);
+    }
+
+
+    @Test
+    public void testSetDestinationAddress() {
+        IPv4 ip = new IPv4();
+        int ipDestinationAddress = 339164782;
+        ip.setDestinationAddress(ipDestinationAddress);
+        byte[] destinationAddress = ip.hdrFieldsMap.get("DestinationIPAddress");
+        Assert.assertTrue(destinationAddress[0] == 20);
+        Assert.assertTrue(destinationAddress[1] == 55);
+        Assert.assertTrue(destinationAddress[2] == 62);
+        Assert.assertTrue(destinationAddress[3] == 110);
+    }
+
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/PacketTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/PacketTest.java
new file mode 100644 (file)
index 0000000..8d856b0
--- /dev/null
@@ -0,0 +1,164 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.packet.Ethernet;
+
+public class PacketTest {
+
+    @Test
+    public void testDeserialize() throws NoSuchFieldException, Exception {
+        short startOffset, numBits;
+
+        Ethernet eth = new Ethernet();
+        byte[] data = { 10, 12, 14, 20, 55, 69, //DMAC
+                -90, -20, -100, -82, -78, -97, //SMAC
+                8, 6, //ethype
+                0, 1, // hw type
+                8, 0, // proto (ip)
+                6, // hw addr len
+                4, // proto addr len
+                0, 1, // op codes
+                -90, -20, -100, -82, -78, -97, //src hw addr
+                9, 9, 9, 1, // src proto
+                0, 0, 0, 0, 0, 0, // target hw addr
+                9, 9, 9, -2 }; // target proto
+
+        startOffset = 0;
+        numBits = 42 * 8;
+        eth.deserialize(data, startOffset, numBits);
+
+        byte[] dMAC = eth.getDestinationMACAddress();
+        byte[] sMAC = eth.getSourceMACAddress();
+        short etherType = eth.getEtherType();
+
+        Assert.assertTrue(dMAC[0] == 10);
+        Assert.assertTrue(dMAC[1] == 12);
+        Assert.assertTrue(dMAC[2] == 14);
+        Assert.assertTrue(dMAC[3] == 20);
+        Assert.assertTrue(dMAC[4] == 55);
+        Assert.assertTrue(dMAC[5] == 69);
+
+        Assert.assertTrue(sMAC[0] == -90);
+        Assert.assertTrue(sMAC[1] == -20);
+        Assert.assertTrue(sMAC[2] == -100);
+        Assert.assertTrue(sMAC[3] == -82);
+        Assert.assertTrue(sMAC[4] == -78);
+        Assert.assertTrue(sMAC[5] == -97);
+
+        Assert.assertTrue(etherType == 0x806);
+        
+        ARP arpPacket = (ARP) eth.getPayload();
+        
+        Assert.assertTrue(arpPacket.getHardwareType() == (byte)0x1);
+        Assert.assertTrue(arpPacket.getProtocolType() == 2048);
+        Assert.assertTrue(arpPacket.getHardwareAddressLength() == (byte)0x6);
+        Assert.assertTrue(arpPacket.getProtocolAddressLength() == (byte)0x4);
+        Assert.assertTrue(arpPacket.getOpCode() == 1);
+        
+        byte[] senderHwAddress = arpPacket.getSenderHardwareAddress();
+        byte[] senderProtocolAddress = arpPacket.getSenderProtocolAddress(); 
+        
+        byte[] targetHwAddress = arpPacket.getTargetHardwareAddress();
+        byte[] targetProtocolAddress = arpPacket.getTargetProtocolAddress(); 
+
+        
+        Assert.assertTrue(senderHwAddress[0] == (byte)0xA6);
+        Assert.assertTrue(senderHwAddress[1] == (byte)0xEC);
+        Assert.assertTrue(senderHwAddress[2] == (byte)0x9C);
+        Assert.assertTrue(senderHwAddress[3] == (byte)0xAE);
+        Assert.assertTrue(senderHwAddress[4] == (byte)0xB2);
+        Assert.assertTrue(senderHwAddress[5] == (byte)0x9F);
+        
+        Assert.assertTrue(senderProtocolAddress[0] == (byte)0x9);
+        Assert.assertTrue(senderProtocolAddress[1] == (byte)0x9);
+        Assert.assertTrue(senderProtocolAddress[2] == (byte)0x9);
+        Assert.assertTrue(senderProtocolAddress[3] == (byte)0x1);
+
+        Assert.assertTrue(targetHwAddress[0] == (byte)0x0);
+        Assert.assertTrue(targetHwAddress[1] == (byte)0x0);
+        Assert.assertTrue(targetHwAddress[2] == (byte)0x0);
+        Assert.assertTrue(targetHwAddress[3] == (byte)0x0);
+        Assert.assertTrue(targetHwAddress[4] == (byte)0x0);
+        Assert.assertTrue(targetHwAddress[5] == (byte)0x0);
+
+        Assert.assertTrue(senderProtocolAddress[0] == (byte)0x9);
+        Assert.assertTrue(senderProtocolAddress[1] == (byte)0x9);
+        Assert.assertTrue(senderProtocolAddress[2] == (byte)0x9);
+        Assert.assertTrue(senderProtocolAddress[3] == (byte)0x1);
+
+        Assert.assertTrue(targetProtocolAddress[0] == (byte)0x9);
+        Assert.assertTrue(targetProtocolAddress[1] == (byte)0x9);
+        Assert.assertTrue(targetProtocolAddress[2] == (byte)0x9);
+        Assert.assertTrue(targetProtocolAddress[3] == (byte)0xFE);      
+    }
+
+    @Test
+    public void testSerialize() throws NoSuchFieldException, Exception {
+        Ethernet eth = new Ethernet();
+        Map<String, byte[]> fCValues = eth.hdrFieldsMap;
+
+        byte[] dMAC = { 10, 12, 14, 20, 55, 69 };
+        byte[] sMAC = { 82, 97, 109, 117, 127, -50 };
+        short etherType = 2054;
+
+        byte[] dMACdata, sMACdata, etherTypedata;
+        byte[] data = new byte[20];
+
+        eth.setDestinationMACAddress(dMAC);
+        eth.setSourceMACAddress(sMAC);
+        eth.setEtherType(etherType);
+
+        dMACdata = (byte[]) fCValues.get("DestinationMACAddress");
+        sMACdata = (byte[]) fCValues.get("SourceMACAddress");
+        etherTypedata = (byte[]) fCValues.get("EtherType");
+
+        Assert.assertTrue(dMACdata[0] == 10);
+        Assert.assertTrue(dMACdata[1] == 12);
+        Assert.assertTrue(dMACdata[2] == 14);
+        Assert.assertTrue(dMACdata[3] == 20);
+        Assert.assertTrue(dMACdata[4] == 55);
+        Assert.assertTrue(dMACdata[5] == 69);
+
+        Assert.assertTrue(sMACdata[0] == 82);
+        Assert.assertTrue(sMACdata[1] == 97);
+        Assert.assertTrue(sMACdata[2] == 109);
+        Assert.assertTrue(sMACdata[3] == 117);
+        Assert.assertTrue(sMACdata[4] == 127);
+        Assert.assertTrue(sMACdata[5] == -50);
+
+        Assert.assertTrue(etherTypedata[0] == 8);
+        Assert.assertTrue(etherTypedata[1] == 6);
+        data = eth.serialize();
+
+        Assert.assertTrue(data[0] == 10);
+        Assert.assertTrue(data[1] == 12);
+        Assert.assertTrue(data[2] == 14);
+        Assert.assertTrue(data[3] == 20);
+        Assert.assertTrue(data[4] == 55);
+        Assert.assertTrue(data[5] == 69);
+
+        Assert.assertTrue(data[6] == 82);
+        Assert.assertTrue(data[7] == 97);
+        Assert.assertTrue(data[8] == 109);
+        Assert.assertTrue(data[9] == 117);
+        Assert.assertTrue(data[10] == 127);
+        Assert.assertTrue(data[11] == -50);
+
+        Assert.assertTrue(data[12] == 8);
+        Assert.assertTrue(data[13] == 6);
+
+    }
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/TCPTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/TCPTest.java
new file mode 100644 (file)
index 0000000..90f963c
--- /dev/null
@@ -0,0 +1,108 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.packet.TCP;
+
+public class TCPTest {
+
+    @Test
+    public void testSetSourcePort() {
+        TCP tcp = new TCP();
+        short tcpSourcePort = 118;
+        tcp.setSourcePort(tcpSourcePort);
+        byte[] sourcePort = tcp.hdrFieldsMap.get("SourcePort");
+        Assert.assertTrue(sourcePort[0] == 0);
+        Assert.assertTrue(sourcePort[1] == 118);
+
+    }
+
+    @Test
+    public void testSetDestinationPort() {
+        TCP tcp = new TCP();
+        short tcpDestinationPort = 443;
+        tcp.setDestinationPort(tcpDestinationPort);
+        byte[] destinationPort = tcp.hdrFieldsMap.get("DestinationPort");
+        Assert.assertTrue(destinationPort[0] == 1);
+        Assert.assertTrue(destinationPort[1] == -69);
+
+    }
+
+    @Test
+    public void testSetSequenceNumber() {
+        TCP tcp = new TCP();
+        short tcpSequenceNumber = 700;
+        tcp.setSequenceNumber(tcpSequenceNumber);
+        byte[] sequenceNumber = tcp.hdrFieldsMap.get("SequenceNumber");
+        Assert.assertTrue(sequenceNumber[0] == 0);
+        Assert.assertTrue(sequenceNumber[1] == 0);
+        Assert.assertTrue(sequenceNumber[2] == 2);
+        Assert.assertTrue(sequenceNumber[3] == -68);
+    }
+
+    @Test
+    public void testSetAckNumber() {
+        TCP tcp = new TCP();
+        short tcpAckNumber = 697;
+        tcp.setAckNumber(tcpAckNumber);
+        byte[] ackNumber = tcp.hdrFieldsMap.get("AcknoledgementNumber");
+        Assert.assertTrue(ackNumber[0] == 0);
+        Assert.assertTrue(ackNumber[1] == 0);
+        Assert.assertTrue(ackNumber[2] == 2);
+        Assert.assertTrue(ackNumber[3] == -71);
+    }
+
+    @Test
+    public void testSetHeaderLenFlags() {
+        TCP tcp = new TCP();
+        short tcpFlags = 26;
+        tcp.setHeaderLenFlags(tcpFlags);
+        byte[] headerLenFlags = tcp.hdrFieldsMap.get("HeaderLenFlags");
+        Assert.assertTrue(headerLenFlags[0] == 0);
+        Assert.assertTrue(headerLenFlags[1] == 26);
+
+    }
+
+    @Test
+    public void testSetWindowSize() {
+        TCP tcp = new TCP();
+        short tcpWindowSize = 100;
+        tcp.setWindowSize(tcpWindowSize);
+        byte[] windowSize = tcp.hdrFieldsMap.get("WindowSize");
+        Assert.assertTrue(windowSize[0] == 0);
+        Assert.assertTrue(windowSize[1] == 100);
+
+    }
+
+    @Test
+    public void testSetChecksum() {
+        TCP tcp = new TCP();
+        short tcpChecksum = 134;
+        tcp.setChecksum(tcpChecksum);
+        byte[] checksum = tcp.hdrFieldsMap.get("Checksum");
+        Assert.assertTrue(checksum[0] == 0);
+        Assert.assertTrue(checksum[1] == -122);
+
+    }
+
+    @Test
+    public void testSetUrgentPointer() {
+        TCP tcp = new TCP();
+        short tcpUrgentPointer = 25098;
+        tcp.setUrgentPointer(tcpUrgentPointer);
+        byte[] urgentPointer = tcp.hdrFieldsMap.get("UrgentPointer");
+        Assert.assertTrue(urgentPointer[0] == 98);
+        Assert.assertTrue(urgentPointer[1] == 10);
+
+    }
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/UDPTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/UDPTest.java
new file mode 100644 (file)
index 0000000..26d4980
--- /dev/null
@@ -0,0 +1,99 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.packet;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.packet.UDP;
+
+public class UDPTest {
+
+    @Test
+    public void testGetSourcePort() {
+        UDP udp = new UDP();
+        byte[] udpSourcePort = { 0, 118 };
+        udp.hdrFieldsMap.put("SourcePort", udpSourcePort);
+        short sourcePort = udp.getSourcePort();
+        Assert.assertTrue(sourcePort == 118);
+    }
+
+    @Test
+    public void testGetDestinationPort() {
+        UDP udp = new UDP();
+        byte[] udpDestinationPort = { 1, -69 };
+        udp.hdrFieldsMap.put("DestinationPort", udpDestinationPort);
+        short destinationPort = udp.getDestinationPort();
+        Assert.assertTrue(destinationPort == 443);
+    }
+
+    @Test
+    public void testGetLength() {
+        UDP udp = new UDP();
+        byte[] udpLength = { 0, 20 };
+        udp.hdrFieldsMap.put("Length", udpLength);
+        short length = udp.getLength();
+        Assert.assertTrue(length == 20);
+    }
+
+    @Test
+    public void testGetChecksum() {
+        UDP udp = new UDP();
+        byte[] udpChecksum = { 0, -56 };
+        udp.hdrFieldsMap.put("Checksum", udpChecksum);
+        short checksum = udp.getChecksum();
+        Assert.assertTrue(checksum == 200);
+    }
+
+    @Test
+    public void testSetSourcePort() {
+        UDP udp = new UDP();
+        short tcpSourcePort = 118;
+        udp.setSourcePort(tcpSourcePort);
+        byte[] sourcePort = udp.hdrFieldsMap.get("SourcePort");
+        Assert.assertTrue(sourcePort[0] == 0);
+        Assert.assertTrue(sourcePort[1] == 118);
+
+    }
+
+    @Test
+    public void testSetDestinationPort() {
+        UDP udp = new UDP();
+        short tcpDestinationPort = 443;
+        udp.setDestinationPort(tcpDestinationPort);
+        byte[] destinationPort = udp.hdrFieldsMap.get("DestinationPort");
+        Assert.assertTrue(destinationPort[0] == 1);
+        Assert.assertTrue(destinationPort[1] == -69);
+
+    }
+
+    @Test
+    public void testSetLength() {
+        UDP udp = new UDP();
+        short udpLength = 20;
+        udp.setLength(udpLength);
+        byte[] length = udp.hdrFieldsMap.get("Length");
+        Assert.assertTrue(length[0] == 0);
+        Assert.assertTrue(length[1] == 20);
+
+    }
+
+    @Test
+    public void testSetChecksum() {
+        UDP udp = new UDP();
+        short udpChecksum = 200;
+        udp.setChecksum(udpChecksum);
+        byte[] checksum = udp.hdrFieldsMap.get("Checksum");
+        Assert.assertTrue(checksum[0] == 0);
+        Assert.assertTrue(checksum[1] == -56);
+
+    }
+
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/address/EthernetAddressTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/address/EthernetAddressTest.java
new file mode 100644 (file)
index 0000000..235a754
--- /dev/null
@@ -0,0 +1,113 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   EthernetAddressTest.java
+ *
+ * @brief  Unit Tests for EthernetAddress class
+ *
+ * Unit Tests for EthernetAddress class
+ */
+package org.opendaylight.controller.sal.packet.address;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.packet.address.EthernetAddress;
+
+public class EthernetAddressTest {
+    @Test
+    public void testNonValidConstructor() {
+        EthernetAddress ea1;
+        // Null input array
+        try {
+            ea1 = new EthernetAddress((byte[]) null);
+
+            // Exception is expected if NOT raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        // Array too short
+        try {
+            ea1 = new EthernetAddress(new byte[] { (byte) 0x0, (byte) 0x0 });
+
+            // Exception is expected if NOT raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+
+        // Array too long
+        try {
+            ea1 = new EthernetAddress(new byte[] { (byte) 0x0, (byte) 0x0,
+                    (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0,
+                    (byte) 0x0 });
+
+            // Exception is expected if NOT raised test will fail
+            Assert.assertTrue(false);
+        } catch (ConstructionException e) {
+        }
+    }
+
+    @Test
+    public void testEquality() {
+        EthernetAddress ea1;
+        EthernetAddress ea2;
+        try {
+            ea1 = new EthernetAddress(new byte[] { (byte) 0x0, (byte) 0x0,
+                    (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x1 });
+
+            ea2 = new EthernetAddress(new byte[] { (byte) 0x0, (byte) 0x0,
+                    (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x1 });
+            Assert.assertTrue(ea1.equals(ea2));
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        try {
+            ea1 = new EthernetAddress(new byte[] { (byte) 0x0, (byte) 0x0,
+                    (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x1 });
+
+            ea2 = ea1.clone();
+            Assert.assertTrue(ea1.equals(ea2));
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+
+        // Check for well knowns
+        try {
+            ea1 = EthernetAddress.BROADCASTMAC;
+            ea2 = new EthernetAddress(new byte[] { (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff });
+            Assert.assertTrue(ea1.equals(ea2));
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testUnEquality() {
+        EthernetAddress ea1;
+        EthernetAddress ea2;
+        try {
+            ea1 = new EthernetAddress(new byte[] { (byte) 0x0, (byte) 0x0,
+                    (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x2 });
+
+            ea2 = new EthernetAddress(new byte[] { (byte) 0x0, (byte) 0x0,
+                    (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x1 });
+            Assert.assertTrue(!ea1.equals(ea2));
+        } catch (ConstructionException e) {
+            // Exception is NOT expected if raised test will fail
+            Assert.assertTrue(false);
+        }
+    }
+}
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/reader/FlowOnNodeTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/reader/FlowOnNodeTest.java
new file mode 100644 (file)
index 0000000..61f34aa
--- /dev/null
@@ -0,0 +1,59 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.reader;
+
+import java.util.ArrayList;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.action.Action;
+import org.opendaylight.controller.sal.action.Output;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.flowprogrammer.Flow;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
+import org.opendaylight.controller.sal.reader.FlowOnNode;
+import org.opendaylight.controller.sal.utils.EtherTypes;
+import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
+import org.opendaylight.controller.sal.utils.NodeCreator;
+       
+public class FlowOnNodeTest {
+
+               @Test
+               public void testFlowOnNodeMethods () {
+               Match match = new Match();
+               NodeConnector inNC = NodeConnectorCreator.createNodeConnector((short)10, NodeCreator.createOFNode((long)10));
+               NodeConnector outNC = NodeConnectorCreator.createNodeConnector((short)20, NodeCreator.createOFNode((long)20));
+                       
+               match.setField(MatchType.DL_TYPE, EtherTypes.IPv4.shortValue());
+               match.setField(MatchType.IN_PORT, inNC);
+                       
+               Output output = new Output(outNC);
+               ArrayList<Action> action = new ArrayList<Action>();
+               action.add(output);
+                       
+               Flow flow = new Flow (match, action);
+               
+               FlowOnNode flowOnNode = new FlowOnNode (flow);
+       
+               Assert.assertTrue(flowOnNode.getFlow().equals(flow));
+               
+               flowOnNode.setPacketCount((long)100);
+               flowOnNode.setByteCount((long)800);
+               flowOnNode.setTableId((byte)0x55);
+               flowOnNode.setDurationNanoseconds(40);
+               flowOnNode.setDurationSeconds(45);
+                       
+               Assert.assertTrue(flowOnNode.getPacketCount() == 100);
+               Assert.assertTrue(flowOnNode.getByteCount() == 800);
+               Assert.assertTrue(flowOnNode.getDurationNanoseconds() == 40);
+               Assert.assertTrue(flowOnNode.getDurationSeconds() == 45);
+               Assert.assertTrue(flowOnNode.getTableId() == (byte)0x55);               
+       }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/reader/NodeConnectorStatisticsTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/reader/NodeConnectorStatisticsTest.java
new file mode 100644 (file)
index 0000000..8c2d2e6
--- /dev/null
@@ -0,0 +1,52 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.reader;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
+import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
+import org.opendaylight.controller.sal.utils.NodeCreator;
+import org.junit.Assert;
+
+public class NodeConnectorStatisticsTest {
+
+       @Test
+       public void testNodeConnectorStatisticsMethods() {
+               NodeConnector nc = NodeConnectorCreator.createNodeConnector((short)20, NodeCreator.createOFNode((long)20));
+               NodeConnectorStatistics ncStats = new NodeConnectorStatistics();
+               ncStats.setNodeConnector(nc);
+               ncStats.setReceiveByteCount(800);
+               ncStats.setReceiveCRCErrorCount(10);
+               ncStats.setReceiveDropCount(5);
+               ncStats.setReceiveErrorCount(20);
+               ncStats.setReceiveFrameErrorCount(25);
+               ncStats.setReceiveOverRunErrorCount(30);
+               ncStats.setReceivePacketCount(100);
+               ncStats.setTransmitByteCount(400);
+               ncStats.setTransmitDropCount(15);
+               ncStats.setTransmitErrorCount(18);
+               ncStats.setTransmitPacketCount(50);
+               ncStats.setCollisionCount(2);
+               
+               Assert.assertTrue(ncStats.getCollisionCount() == 2);
+               Assert.assertTrue(ncStats.getTransmitPacketCount() == 50);
+               Assert.assertTrue(ncStats.getTransmitErrorCount() == 18);
+               Assert.assertTrue(ncStats.getTransmitDropCount() == 15);
+               Assert.assertTrue(ncStats.getReceivePacketCount() == 100);
+               Assert.assertTrue(ncStats.getReceiveOverRunErrorCount() == 30);
+               Assert.assertTrue(ncStats.getReceiveFrameErrorCount() == 25);
+               Assert.assertTrue(ncStats.getReceiveDropCount() == 5);
+               Assert.assertTrue(ncStats.getReceiveCRCErrorCount() == 10);
+               Assert.assertTrue(ncStats.getReceiveByteCount() == 800);
+               Assert.assertTrue(ncStats.getNodeConnector().equals(nc));
+       }
+}
+
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/reader/NodeDescriptionTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/reader/NodeDescriptionTest.java
new file mode 100644 (file)
index 0000000..a78182f
--- /dev/null
@@ -0,0 +1,43 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.reader;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.reader.NodeDescription;
+
+public class NodeDescriptionTest {
+       
+       @Test
+       public void testNodeDescriptionMethods() {
+               NodeDescription ncDesc = new NodeDescription();
+               ncDesc.setHardware("Hardware1");
+               ncDesc.setManufacturer("Manufacturer1");
+               ncDesc.setSdnProtocolDescription("SDNProtocol1");
+               ncDesc.setSerialNumber("serialNumber1");
+               ncDesc.setSoftware("Software1");
+               
+               Assert.assertTrue(ncDesc.getHardware().equals("Hardware1"));
+               Assert.assertTrue(ncDesc.getManufacturer().equals("Manufacturer1"));
+               Assert.assertTrue(ncDesc.getSdnProtocolDescription().equals("SDNProtocol1"));
+               Assert.assertTrue(ncDesc.getSerialNumber().equals("serialNumber1"));
+               Assert.assertTrue(ncDesc.getSoftware().equals("Software1"));
+               
+               Assert.assertFalse(ncDesc.getHardware().equals("Hardware2"));
+               Assert.assertFalse(ncDesc.getManufacturer().equals("Manufacturer2"));
+               Assert.assertFalse(ncDesc.getSdnProtocolDescription().equals("SDNProtocol2"));
+               Assert.assertFalse(ncDesc.getSerialNumber().equals("serialNumber2"));
+               Assert.assertFalse(ncDesc.getSoftware().equals("Software2"));
+
+       }
+}
+
+
+
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/EtherTypesTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/EtherTypesTest.java
new file mode 100644 (file)
index 0000000..117da55
--- /dev/null
@@ -0,0 +1,74 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import java.util.ArrayList;
+import org.junit.Assert;
+import org.junit.Test;
+       
+public class EtherTypesTest {
+               
+       @Test
+       public void testEthertypesCreation() {
+               
+               EtherTypes arp = EtherTypes.ARP;
+               
+               Assert.assertTrue(arp.toString().equals("ARP"));
+               Assert.assertTrue(arp.intValue() == 2054);
+               Assert.assertTrue(arp.shortValue() == (short)2054);
+       }
+       
+       @Test
+       public void testGetEtherTypesString() {
+               
+               Assert.assertTrue(EtherTypes.getEtherTypeName(34984).equals("QINQ"));
+               Assert.assertTrue(EtherTypes.getEtherTypeName((short)2048).equals("IPv4"));
+               Assert.assertTrue(EtherTypes.getEtherTypeName(0x010B).equals("PVSTP"));
+               
+               Assert.assertFalse(EtherTypes.getEtherTypeName(0x800).equals("ARP"));
+       }
+       
+       @Test
+       public void testGetEtherTypesNumber() {
+               Assert.assertTrue(EtherTypes.getEtherTypeNumberInt("VLAN Tagged") == 33024);
+               Assert.assertTrue(EtherTypes.getEtherTypeNumberShort("ARP") == 2054);
+               
+               Assert.assertFalse(EtherTypes.getEtherTypeNumberInt("CDP") == 1000);
+       }
+       
+       @Test
+       public void testGetEtherTypesList() {
+               ArrayList<String> etherTypeNames = (ArrayList<String>) EtherTypes.getEtherTypesNameList();
+               Assert.assertTrue(etherTypeNames.get(0).equals("PVSTP"));
+               Assert.assertTrue(etherTypeNames.get(1).equals("CDP"));
+               Assert.assertTrue(etherTypeNames.get(2).equals("VTP"));
+               Assert.assertTrue(etherTypeNames.get(3).equals("IPv4"));
+               Assert.assertTrue(etherTypeNames.get(4).equals("ARP"));
+               Assert.assertTrue(etherTypeNames.get(5).equals("Reverse ARP"));
+               Assert.assertTrue(etherTypeNames.get(6).equals("VLAN Tagged"));
+               Assert.assertTrue(etherTypeNames.get(7).equals("IPv6"));
+               Assert.assertTrue(etherTypeNames.get(8).equals("MPLS Unicast"));
+               Assert.assertTrue(etherTypeNames.get(9).equals("MPLS Multicast"));
+               Assert.assertTrue(etherTypeNames.get(10).equals("QINQ"));
+               Assert.assertTrue(etherTypeNames.get(11).equals("LLDP"));
+               Assert.assertTrue(etherTypeNames.get(12).equals("Old QINQ"));
+               Assert.assertTrue(etherTypeNames.get(13).equals("Cisco QINQ"));         
+       }
+       
+       @Test
+       public void testGetEtherTypesloadFromString() {
+               Assert.assertTrue(EtherTypes.loadFromString("37376").equals(EtherTypes.CISCOQINQ));
+               Assert.assertTrue(EtherTypes.loadFromString("100") == null);
+       }
+
+}
+
+
+
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/HexEncodeTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/HexEncodeTest.java
new file mode 100644 (file)
index 0000000..b9b5f45
--- /dev/null
@@ -0,0 +1,70 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+               
+import org.junit.Assert;
+import org.junit.Test;
+       
+public class HexEncodeTest {
+               
+       @Test
+       public void testbytesToHexString() {
+               byte[] bytes1 = {(byte)0x01, (byte)0x02, (byte)0x03};           
+               String str1 = HexEncode.bytesToHexString(bytes1);
+               Assert.assertTrue(str1.equals("010203"));
+       
+               byte[] bytes2 = {(byte)0x11, (byte)0x22, (byte)0x33};           
+               String str2 = HexEncode.bytesToHexString(bytes2);
+               Assert.assertFalse(str2.equals("010203"));
+
+       }
+
+       @Test
+       public void testLongToHexString() {
+               long value1 = 12345678L;
+               String str1 = HexEncode.longToHexString(value1);
+               Assert.assertTrue(str1.equals("00:00:00:00:00:bc:61:4e"));
+               
+               long value2 = 98765432L;
+               String str2 = HexEncode.longToHexString(value2);
+               Assert.assertFalse(str2.equals("00:44:33:22:11:bc:61:4e"));
+
+       }
+       
+       @Test
+       public void testBytesFromHexString() {
+               String byteStr1 = "00:11:22:33:44:55";
+               byte byteArray1[] = new byte[(byteStr1.length() + 1)/3];
+               byteArray1 = HexEncode.bytesFromHexString(byteStr1);
+               
+               Assert.assertTrue(byteArray1[0] == (byte)0x0);
+               Assert.assertTrue(byteArray1[1] == (byte)0x11);
+               Assert.assertTrue(byteArray1[2] == (byte)0x22);
+               Assert.assertTrue(byteArray1[3] == (byte)0x33);
+               Assert.assertTrue(byteArray1[4] == (byte)0x44);
+               Assert.assertTrue(byteArray1[5] == (byte)0x55);
+               
+               String byteStr2 = "00:11:22:33:44:55";
+               byte byteArray2[] = new byte[(byteStr2.length() + 1)/3];
+               byteArray2 = HexEncode.bytesFromHexString(byteStr2);
+               
+               Assert.assertFalse(byteArray2[0] == (byte)0x55);
+               Assert.assertFalse(byteArray2[1] == (byte)0x44);
+               Assert.assertFalse(byteArray2[2] == (byte)0x33);
+               Assert.assertFalse(byteArray2[3] == (byte)0x22);
+               Assert.assertFalse(byteArray2[4] == (byte)0x11);
+               Assert.assertFalse(byteArray2[5] == (byte)0x0);
+
+       }
+                       
+}
+
+
+
diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/NetUtilsTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/NetUtilsTest.java
new file mode 100644 (file)
index 0000000..77d1fe2
--- /dev/null
@@ -0,0 +1,277 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.utils;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.utils.NetUtils;
+
+public class NetUtilsTest {
+
+    @Test
+    public void testByteArrayMethods() {
+        int ip = 8888;
+        Assert.assertTrue(NetUtils
+                .byteArray4ToInt(NetUtils.intToByteArray4(ip)) == ip);
+
+        ip = 0xffffffff;
+        Assert.assertTrue(NetUtils
+                .byteArray4ToInt(NetUtils.intToByteArray4(ip)) == ip);
+
+        ip = 0;
+        Assert.assertTrue(NetUtils
+                .byteArray4ToInt(NetUtils.intToByteArray4(ip)) == ip);
+
+        ip = 0x1fffffff;
+        Assert.assertTrue(NetUtils
+                .byteArray4ToInt(NetUtils.intToByteArray4(ip)) == ip);
+
+        ip = 0xfffffff;
+        Assert.assertTrue(NetUtils
+                .byteArray4ToInt(NetUtils.intToByteArray4(ip)) == ip);
+
+        ip = 0xf000ffff;
+        Assert.assertTrue(NetUtils
+                .byteArray4ToInt(NetUtils.intToByteArray4(ip)) == ip);
+
+        byte ba[] = { (byte) 0xf, (byte) 0xf, (byte) 0xf, (byte) 0xff };
+        Assert.assertTrue(Arrays.equals(ba, NetUtils.intToByteArray4(NetUtils
+                .byteArray4ToInt(ba))));
+
+        byte ba1[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255 };
+        Assert.assertTrue(Arrays.equals(ba1, NetUtils.intToByteArray4(NetUtils
+                .byteArray4ToInt(ba1))));
+
+        byte ba2[] = { (byte) 255, (byte) 0, (byte) 0, (byte) 0 };
+        Assert.assertTrue(Arrays.equals(ba2, NetUtils.intToByteArray4(NetUtils
+                .byteArray4ToInt(ba2))));
+
+        byte ba3[] = { (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
+        Assert.assertTrue(Arrays.equals(ba3, NetUtils.intToByteArray4(NetUtils
+                .byteArray4ToInt(ba3))));
+
+        byte ba4[] = { (byte) 255, (byte) 128, (byte) 0, (byte) 0 };
+        Assert.assertTrue(Arrays.equals(ba4, NetUtils.intToByteArray4(NetUtils
+                .byteArray4ToInt(ba4))));
+    }
+
+    @Test
+    public void testInetMethods() throws UnknownHostException {
+        int ip = 0xfffffff0;
+        InetAddress inet = InetAddress.getByName("255.255.255.240");
+        Assert.assertTrue(inet.equals(NetUtils.getInetAddress(ip)));
+
+        ip = 0;
+        inet = InetAddress.getByName("0.0.0.0");
+        Assert.assertTrue(inet.equals(NetUtils.getInetAddress(ip)));
+
+        ip = 0x9ffff09;
+        inet = InetAddress.getByName("9.255.255.9");
+        Assert.assertTrue(inet.equals(NetUtils.getInetAddress(ip)));
+    }
+
+    @Test
+    public void testMasksV4() throws UnknownHostException {
+
+        InetAddress mask = InetAddress.getByName("128.0.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(1, false)));
+
+        mask = InetAddress.getByName("192.0.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(2, false)));
+
+        mask = InetAddress.getByName("224.0.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(3, false)));
+
+        mask = InetAddress.getByName("240.0.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(4, false)));
+
+        mask = InetAddress.getByName("248.0.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(5, false)));
+
+        mask = InetAddress.getByName("252.0.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(6, false)));
+
+        mask = InetAddress.getByName("254.0.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(7, false)));
+
+        mask = InetAddress.getByName("255.0.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(8, false)));
+
+        mask = InetAddress.getByName("255.128.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(9, false)));
+
+        mask = InetAddress.getByName("255.192.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(10, false)));
+
+        mask = InetAddress.getByName("255.224.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(11, false)));
+
+        mask = InetAddress.getByName("255.240.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(12, false)));
+
+        mask = InetAddress.getByName("255.248.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(13, false)));
+
+        mask = InetAddress.getByName("255.252.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(14, false)));
+
+        mask = InetAddress.getByName("255.254.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(15, false)));
+
+        mask = InetAddress.getByName("255.255.0.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(16, false)));
+
+        mask = InetAddress.getByName("255.255.128.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(17, false)));
+
+        mask = InetAddress.getByName("255.255.192.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(18, false)));
+
+        mask = InetAddress.getByName("255.255.224.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(19, false)));
+
+        mask = InetAddress.getByName("255.255.240.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(20, false)));
+
+        mask = InetAddress.getByName("255.255.248.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(21, false)));
+
+        mask = InetAddress.getByName("255.255.252.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(22, false)));
+
+        mask = InetAddress.getByName("255.255.254.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(23, false)));
+
+        mask = InetAddress.getByName("255.255.255.0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(24, false)));
+
+        mask = InetAddress.getByName("255.255.255.128");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(25, false)));
+
+        mask = InetAddress.getByName("255.255.255.192");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(26, false)));
+
+        mask = InetAddress.getByName("255.255.255.224");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(27, false)));
+
+        mask = InetAddress.getByName("255.255.255.240");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(28, false)));
+
+        mask = InetAddress.getByName("255.255.255.248");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(29, false)));
+
+        mask = InetAddress.getByName("255.255.255.252");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(30, false)));
+
+        mask = InetAddress.getByName("255.255.255.254");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(31, false)));
+
+        mask = InetAddress.getByName("255.255.255.255");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(32, false)));
+    }
+
+    @Test
+    public void testMasksV6() throws UnknownHostException {
+
+        InetAddress mask = InetAddress.getByName("ff00::0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(8, true)));
+
+        mask = InetAddress.getByName("8000::0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(1, true)));
+
+        mask = InetAddress.getByName("f800::0");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(5, true)));
+
+        mask = InetAddress.getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe");
+        Assert.assertTrue(mask.equals(NetUtils.getInetNetworkMask(127, true)));
+    }
+
+    @Test
+    public void testGetSubnetLen() {
+
+        byte address[] = { (byte) 128, (byte) 0, (byte) 0, 0 };
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address) == 31);
+
+        byte address1[] = { (byte) 255, 0, 0, 0 };
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address1) == 24);
+
+        byte address2[] = { (byte) 255, (byte) 255, (byte) 248, 0 };
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address2) == 11);
+
+        byte address4[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 254 };
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address4) == 1);
+    }
+
+    @Test
+    public void testGetSubnetPrefix() throws UnknownHostException {
+        InetAddress ip = InetAddress.getByName("192.128.64.252");
+        int maskLen = 25;
+        Assert.assertTrue(NetUtils.getSubnetPrefix(ip, maskLen).equals(
+                InetAddress.getByName("192.128.64.128")));
+    }
+
+    @Test
+    public void testIsIPv6Valid() throws UnknownHostException {
+        Assert.assertTrue(NetUtils
+                .isIPv6AddressValid("fe80:0000:0000:0000:0204:61ff:fe9d:f156")); //normal ipv6
+        Assert.assertTrue(NetUtils
+                .isIPv6AddressValid("fe80:0:0:0:204:61ff:fe9d:f156")); //no leading zeroes
+        Assert.assertTrue(NetUtils
+                .isIPv6AddressValid("fe80::204:61ff:fe9d:f156")); //zeroes to ::
+        Assert
+                .assertTrue(NetUtils
+                        .isIPv6AddressValid("fe80:0000:0000:0000:0204:61ff:254.157.241.86")); // ipv4 ending
+        Assert.assertTrue(NetUtils
+                .isIPv6AddressValid("fe80:0:0:0:0204:61ff:254.157.241.86")); // no leading zeroes, ipv4 end
+        Assert.assertTrue(NetUtils
+                .isIPv6AddressValid("fe80::204:61ff:254.157.241.86")); // zeroes ::, no leading zeroes
+
+        Assert.assertTrue(NetUtils.isIPv6AddressValid("2001::")); //link-local prefix
+        Assert.assertTrue(NetUtils.isIPv6AddressValid("::1")); //localhost
+        Assert.assertTrue(NetUtils.isIPv6AddressValid("fe80::")); //global-unicast
+        Assert.assertFalse(NetUtils.isIPv6AddressValid("abcd")); //not valid
+        Assert.assertFalse(NetUtils.isIPv6AddressValid("1")); //not valid
+        Assert.assertFalse(NetUtils
+                .isIPv6AddressValid("fe80:0:0:0:204:61ff:fe9d")); //not valid, too short
+        Assert.assertFalse(NetUtils
+                .isIPv6AddressValid("fe80:::0:0:0:204:61ff:fe9d")); //not valid
+        Assert.assertFalse(NetUtils.isIPv6AddressValid("192.168.1.1")); //not valid,ipv4
+        Assert
+                .assertFalse(NetUtils
+                        .isIPv6AddressValid("2001:0000:1234:0000:10001:C1C0:ABCD:0876")); //not valid, extra number
+        Assert
+                .assertFalse(NetUtils
+                        .isIPv6AddressValid("20010:0000:1234:0000:10001:C1C0:ABCD:0876")); //not valid, extra number
+
+        Assert
+                .assertTrue(NetUtils
+                        .isIPv6AddressValid("2001:0DB8:0000:CD30:0000:0000:0000:0000/60")); //full with mask
+        Assert.assertTrue(NetUtils.isIPv6AddressValid("2001:0DB8:0:CD30::/64")); //shortened with mask
+        Assert.assertTrue(NetUtils.isIPv6AddressValid("2001:0DB8:0:CD30::/0")); //0 subnet with mask
+        Assert.assertTrue(NetUtils.isIPv6AddressValid("::1/128")); //localhost 128 mask
+
+        Assert.assertFalse(NetUtils.isIPv6AddressValid("124.15.6.89/60")); //invalid, ip with mask
+        Assert
+                .assertFalse(NetUtils
+                        .isIPv6AddressValid("2001:0DB8:0000:CD30:0000:0000:0000:0000/130")); //invalid, mask >128
+        Assert
+                .assertFalse(NetUtils
+                        .isIPv6AddressValid("2001:0DB8:0:CD30::/-5")); //invalid, mask < 0
+        Assert.assertFalse(NetUtils
+                .isIPv6AddressValid("fe80:::0:0:0:204:61ff:fe9d/64")); //not valid ip, valid netmask
+        Assert.assertFalse(NetUtils
+                .isIPv6AddressValid("fe80:::0:0:0:204:61ff:fe9d/-1")); //not valid both
+
+    }
+}
diff --git a/opendaylight/sal/implementation/pom.xml b/opendaylight/sal/implementation/pom.xml
new file mode 100644 (file)
index 0000000..32f0a38
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>commons.opendaylight</artifactId>\r
+    <version>1.4.0-SNAPSHOT</version>\r
+    <relativePath>../../commons/opendaylight</relativePath>\r
+  </parent>\r
+\r
+  <groupId>org.opendaylight.controller</groupId>\r
+  <artifactId>sal.implementation</artifactId>\r
+  <version>0.4.0-SNAPSHOT</version>\r
+  <packaging>bundle</packaging>\r
+\r
+  <build>\r
+    <plugins>\r
+      <plugin>\r
+        <groupId>org.apache.felix</groupId>\r
+        <artifactId>maven-bundle-plugin</artifactId>\r
+        <version>2.3.6</version>\r
+        <extensions>true</extensions>\r
+        <configuration>\r
+          <instructions>\r
+            <Import-Package>\r
+              org.slf4j,\r
+              org.apache.commons.lang3.builder,\r
+              org.opendaylight.controller.sal.core,\r
+              org.opendaylight.controller.sal.packet,\r
+              org.opendaylight.controller.sal.inventory,\r
+              org.opendaylight.controller.sal.flowprogrammer,\r
+              org.opendaylight.controller.sal.reader,\r
+              org.opendaylight.controller.sal.topology,\r
+              org.opendaylight.controller.sal.action,\r
+              org.opendaylight.controller.sal.match,\r
+              org.opendaylight.controller.sal.utils,\r
+              org.apache.felix.dm,\r
+              org.eclipse.osgi.framework.console,\r
+                         org.osgi.framework\r
+            </Import-Package>\r
+            <Export-Package>\r
+            </Export-Package>\r
+               <Bundle-Activator>\r
+             org.opendaylight.controller.sal.implementation.internal.Activator\r
+               </Bundle-Activator>\r
+          </instructions>\r
+        </configuration>\r
+      </plugin>\r
+    </plugins>\r
+  </build>\r
+  <dependencies>\r
+    <dependency>\r
+      <groupId>org.opendaylight.controller</groupId>\r
+      <artifactId>sal</artifactId>\r
+      <version>0.4.0-SNAPSHOT</version>\r
+    </dependency>\r
+  </dependencies>\r
+</project>\r
diff --git a/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/Activator.java b/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/Activator.java
new file mode 100644 (file)
index 0000000..1d7732a
--- /dev/null
@@ -0,0 +1,166 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.implementation.internal;
+
+import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
+import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerService;
+import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService;
+import org.opendaylight.controller.sal.inventory.IInventoryService;
+import org.opendaylight.controller.sal.inventory.IListenInventoryUpdates;
+import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService;
+import org.opendaylight.controller.sal.packet.IDataPacketService;
+import org.opendaylight.controller.sal.packet.IListenDataPacket;
+import org.opendaylight.controller.sal.packet.IPluginInDataPacketService;
+import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService;
+import org.opendaylight.controller.sal.reader.IPluginInReadService;
+import org.opendaylight.controller.sal.reader.IReadService;
+import org.opendaylight.controller.sal.topology.IListenTopoUpdates;
+import org.opendaylight.controller.sal.topology.IPluginInTopologyService;
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService;
+import org.opendaylight.controller.sal.topology.ITopologyService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.felix.dm.Component;
+
+public class Activator extends ComponentActivatorAbstractBase {
+    protected static final Logger logger = LoggerFactory
+            .getLogger(Activator.class);
+
+    /**
+     * Function called when the activator starts just after some
+     * initializations are done by the
+     * ComponentActivatorAbstractBase.
+     *
+     */
+    public void init() {
+
+    }
+
+    /**
+     * Function called when the activator stops just before the
+     * cleanup done by ComponentActivatorAbstractBase
+     *
+     */
+    public void destroy() {
+
+    }
+
+    /**
+     * Function that is used to communicate to dependency manager the
+     * list of known implementations for services inside a container
+     *
+     *
+     * @return An array containing all the CLASS objects that will be
+     * instantiated in order to get an fully working implementation
+     * Object
+     */
+    public Object[] getImplementations() {
+        Object[] res = { Topology.class, Inventory.class,
+                FlowProgrammerService.class, ReadService.class,
+                DataPacketService.class };
+        return res;
+    }
+
+    /**
+     * Function that is called when configuration of the dependencies
+     * is required.
+     *
+     * @param c dependency manager Component object, used for
+     * configuring the dependencies exported and imported
+     * @param imp Implementation class that is being configured,
+     * needed as long as the same routine can configure multiple
+     * implementations
+     * @param containerName The containerName being configured, this allow
+     * also optional per-container different behavior if needed, usually
+     * should not be the case though.
+     */
+    public void configureInstance(Component c, Object imp, String containerName) {
+        if (imp.equals(Topology.class)) {
+            // export the service for Apps and Plugins
+            c.setInterface(new String[] {
+                    IPluginOutTopologyService.class.getName(),
+                    ITopologyService.class.getName() }, null);
+
+            // There can be multiple Topology listeners or there could
+            // be none, hence the dependency is optional
+            c.add(createContainerServiceDependency(containerName).setService(
+                    IListenTopoUpdates.class).setCallbacks("setUpdateService",
+                    "unsetUpdateService").setRequired(false));
+
+            // There can be multiple southbound plugins or there could
+            // be none, the dependency is optional
+            c.add(createContainerServiceDependency(containerName).setService(
+                    IPluginInTopologyService.class).setCallbacks(
+                    "setPluginService", "unsetPluginService")
+                    .setRequired(false));
+        }
+
+        if (imp.equals(Inventory.class)) {
+            // export the service
+            c.setInterface(new String[] {
+                    IPluginOutInventoryService.class.getName(),
+                    IInventoryService.class.getName() }, null);
+
+            // Now lets add a service dependency to make sure the
+            // provider of service exists
+            c.add(createContainerServiceDependency(containerName).setService(
+                    IListenInventoryUpdates.class).setCallbacks(
+                    "setUpdateService", "unsetUpdateService")
+                    .setRequired(false));
+            c
+                    .add(createContainerServiceDependency(containerName)
+                            .setService(IPluginInInventoryService.class)
+                            .setCallbacks("setPluginService",
+                                    "unsetPluginService").setRequired(true));
+        }
+
+        if (imp.equals(FlowProgrammerService.class)) {
+            // It is the provider of IFlowProgrammerService
+            c.setInterface(IFlowProgrammerService.class.getName(), null);
+            //It is also the consumer of IPluginInFlowProgrammerService
+            c.add(createServiceDependency().setService(
+                    IPluginInFlowProgrammerService.class).setCallbacks(
+                    "setService", "unsetService").setRequired(true));
+        }
+
+        if (imp.equals(ReadService.class)) {
+            // It is the provider of IReadService
+            c.setInterface(IReadService.class.getName(), null);
+
+            //It is also the consumer of IPluginInReadService
+            c.add(createContainerServiceDependency(containerName).setService(
+                    IPluginInReadService.class).setCallbacks("setService",
+                    "unsetService").setRequired(true));
+        }
+
+        /************************/
+        /* DATA PACKET SERVICES */
+        /************************/
+        if (imp.equals(DataPacketService.class)) {
+            c.setInterface(new String[] {
+                    IPluginOutDataPacketService.class.getName(),
+                    IDataPacketService.class.getName() }, null);
+
+            // Optionally use PluginInDataService if any southbound
+            // protocol plugin exists
+            c.add(createContainerServiceDependency(containerName).setService(
+                    IPluginInDataPacketService.class).setCallbacks(
+                    "setPluginInDataService", "unsetPluginInDataService")
+                    .setRequired(false));
+
+            // Optionally listed to IListenDataPacket services
+            c.add(createContainerServiceDependency(containerName).setService(
+                    IListenDataPacket.class).setCallbacks(
+                    "setListenDataPacket", "unsetListenDataPacket")
+                    .setRequired(false));
+        }
+    }
+}
diff --git a/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/DataPacketService.java b/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/DataPacketService.java
new file mode 100644 (file)
index 0000000..fe525bb
--- /dev/null
@@ -0,0 +1,554 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * @file   DataPacketService.java
+ *
+ * @brief  Implementation of Data Packet services in SAL
+ *
+ * Implementation of Data Packet services in SAL
+ */
+
+package org.opendaylight.controller.sal.implementation.internal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.packet.Ethernet;
+import org.opendaylight.controller.sal.packet.IDataPacketService;
+import org.opendaylight.controller.sal.packet.IListenDataPacket;
+import org.opendaylight.controller.sal.packet.IPluginInDataPacketService;
+import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService;
+import org.opendaylight.controller.sal.packet.LinkEncap;
+import org.opendaylight.controller.sal.packet.Packet;
+import org.opendaylight.controller.sal.packet.PacketResult;
+import org.opendaylight.controller.sal.packet.RawPacket;
+import org.opendaylight.controller.sal.utils.NetUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DataPacketService implements IPluginOutDataPacketService,
+        IDataPacketService {
+    private int RXMAXQUEUESIZE = 1000;
+    private int TXMAXQUEUESIZE = 1000;
+    protected static final Logger logger = LoggerFactory
+            .getLogger(DataPacketService.class);
+    /**
+     * Database that associates one NodeIDType to the
+     * IPluginDataPacketService, in fact we expect that there will be
+     * one instance of IPluginDataPacketService for each southbound
+     * plugin.
+     * Using the ConcurrentHashMap because the threads that will be
+     * adding a new service, removing a service, going through all of
+     * them maybe different.
+     */
+    private ConcurrentHashMap<String, IPluginInDataPacketService>
+        pluginInDataService =
+        new ConcurrentHashMap<String, IPluginInDataPacketService>();
+    private Map<String, AtomicInteger> statistics = new HashMap<String, AtomicInteger>();
+    /**
+     * Queue for packets received from Data Path
+     */
+    private LinkedBlockingQueue<RawPacket> rxQueue = new LinkedBlockingQueue<RawPacket>(
+            RXMAXQUEUESIZE);
+    /**
+     * Queue for packets that need to be transmitted to Data Path
+     */
+    private LinkedBlockingQueue<RawPacket> txQueue = new LinkedBlockingQueue<RawPacket>(
+            RXMAXQUEUESIZE);
+    /**
+     * Transmission thread
+     */
+    private Thread txThread = new Thread(new TxLoop(),
+            "DataPacketService TX thread");
+    /**
+     * Receiving thread
+     */
+    private Thread rxThread = new Thread(new RxLoop(),
+            "DataPacketService RX thread");
+
+    /**
+     * Representation of a Data Packet Listener including of its
+     * properties
+     *
+     */
+    private class DataPacketListener {
+        // Key fields
+        private String listenerName;
+        // Attribute fields
+        private IListenDataPacket listener;
+        private String dependency;
+        private Match match;
+
+        DataPacketListener(String name, IListenDataPacket s, String dependency,
+                Match match) {
+            this.listenerName = name;
+            this.listener = s;
+            this.dependency = dependency;
+            this.match = match;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+            if (obj == this) {
+                return true;
+            }
+            if (obj.getClass() != getClass()) {
+                return false;
+            }
+            DataPacketListener rhs = (DataPacketListener) obj;
+            return new EqualsBuilder().append(this.listenerName,
+                    rhs.listenerName).isEquals();
+        }
+
+        @Override
+        public int hashCode() {
+            return new HashCodeBuilder(13, 31).append(listenerName)
+                    .toHashCode();
+        }
+    }
+
+    /**
+     * This very expensive version of List is being used because it
+     * work well in concurrent situation, as we expect new service
+     * addition, service removal and walk of the service will happen
+     * from different places
+     */
+    private List<List<DataPacketListener>> listenDataPacket = new CopyOnWriteArrayList<List<DataPacketListener>>();
+    // Quick index to make sure there are no duplicate elements
+    private Set<DataPacketListener> indexDataPacket = Collections
+            .synchronizedSet(new HashSet<DataPacketListener>());
+
+    /**
+     * Loop for processing Received packets
+     *
+     */
+    private class RxLoop implements Runnable {
+        public void run() {
+            RawPacket pkt;
+            try {
+                for (pkt = rxQueue.take(); pkt != null; pkt = rxQueue.take()) {
+                    for (List<DataPacketListener> serialListeners : listenDataPacket) {
+                        int i = 0;
+                        for (i = 0; i < serialListeners.size(); i++) {
+                            RawPacket copyPkt = null;
+                            try {
+                                copyPkt = new RawPacket(pkt);
+                            } catch (ConstructionException cex) {
+                                logger.debug("Error while cloning the packet");
+                            }
+                            if (copyPkt == null) {
+                                increaseStat("RXPacketCopyFailed");
+                                continue;
+                            }
+                            DataPacketListener l = serialListeners.get(i);
+                            IListenDataPacket s = (l == null ? null
+                                    : l.listener);
+                            if (s != null) {
+                                try {
+                                    // TODO Make sure to filter based
+                                    // on the match too, later on
+                                    PacketResult res = s
+                                            .receiveDataPacket(copyPkt);
+                                    increaseStat("RXPacketSuccess");
+                                    if (res.equals(PacketResult.CONSUME)) {
+                                        increaseStat("RXPacketSerialExit");
+                                        break;
+                                    }
+                                } catch (Exception e) {
+                                    increaseStat("RXPacketFailedForException");
+                                }
+                            }
+                        }
+                    }
+                }
+            } catch (InterruptedException e) {
+                // Not a big deal
+            }
+        }
+    }
+
+    /**
+     * Loop for processing packets to be transmitted
+     *
+     */
+    private class TxLoop implements Runnable {
+        public void run() {
+            RawPacket pkt;
+            try {
+                for (pkt = txQueue.take(); pkt != null; pkt = txQueue.take()) {
+                    // Retrieve outgoing node connector so to send out
+                    // the packet to corresponding node
+                    NodeConnector p = pkt.getOutgoingNodeConnector();
+                    if (p != null) {
+                        String t = p.getNode()
+                                .getType();
+                        // Now locate the TX dispatcher
+                        IPluginInDataPacketService s = pluginInDataService
+                                .get(t);
+                        if (s != null) {
+                            try {
+                                s.transmitDataPacket(pkt);
+                                increaseStat("TXPacketSuccess");
+                            } catch (Exception e) {
+                                increaseStat("TXPacketFailedForException");
+                            }
+                        } else {
+                            increaseStat("TXpluginNotFound");
+                        }
+                    }
+                }
+            } catch (InterruptedException e) {
+                // Not a big deal
+            }
+        }
+    }
+
+    void setPluginInDataService(Map props, IPluginInDataPacketService s) {
+        if (this.pluginInDataService == null) {
+            logger.error("pluginInDataService store null");
+            return;
+        }
+        String type = null;
+        logger.trace("Received setPluginInDataService request");
+        for (Object e : props.entrySet()) {
+            Map.Entry entry = (Map.Entry) e;
+            logger.trace("Prop key:(" + entry.getKey() + ") value:("
+                    + entry.getValue() + ")");
+        }
+
+        Object value = props.get("protocolPluginType");
+        if (value instanceof String) {
+            type = (String) value;
+        }
+        if (type == null) {
+            logger.error("Received a PluginInDataService without any "
+                    + "protocolPluginType provided");
+        } else {
+            this.pluginInDataService.put(type, s);
+            logger.debug("Stored the PluginInDataService for type:" + type);
+        }
+    }
+
+    void unsetPluginInDataService(Map props, IPluginInDataPacketService s) {
+        if (this.pluginInDataService == null) {
+            logger.error("pluginInDataService store null");
+            return;
+        }
+
+        String type = null;
+        logger.trace("Received unsetPluginInDataService request");
+        for (Object e : props.entrySet()) {
+            Map.Entry entry = (Map.Entry) e;
+            logger.trace("Prop key:(" + entry.getKey() + ") value:("
+                    + entry.getValue() + ")");
+        }
+
+        Object value = props.get("protocoloPluginType");
+        if (value instanceof String) {
+            type = (String) value;
+        }
+        if (type == null) {
+            logger.error("Received a PluginInDataService without any "
+                    + "protocolPluginType provided");
+        } else if (this.pluginInDataService.get(type).equals(s)) {
+            this.pluginInDataService.remove(type);
+            logger.debug("Removed the PluginInDataService for type:" + type);
+        }
+    }
+
+    void setListenDataPacket(Map props, IListenDataPacket s) {
+        if (this.listenDataPacket == null || this.indexDataPacket == null) {
+            logger.error("data structure to store data is NULL");
+            return;
+        }
+        logger.trace("Received setListenDataPacket request");
+        for (Object e : props.entrySet()) {
+            Map.Entry entry = (Map.Entry) e;
+            logger.trace("Prop key:(" + entry.getKey() + ") value:("
+                    + entry.getValue() + ")");
+        }
+
+        String listenerName = null;
+        String listenerDependency = null;
+        Match filter = null;
+        Object value;
+        // Read the listenerName
+        value = props.get("salListenerName");
+        if (value instanceof String) {
+            listenerName = (String) value;
+        }
+
+        if (listenerName == null) {
+            logger.error("Trying to set a listener without a Name");
+            return;
+        }
+
+        //Read the dependency
+        value = props.get("salListenerDependency");
+        if (value instanceof String) {
+            listenerDependency = (String) value;
+        }
+
+        //Read match filter if any
+        value = props.get("salListenerFilter");
+        if (value instanceof Match) {
+            filter = (Match) value;
+        }
+
+        DataPacketListener l = new DataPacketListener(listenerName, s,
+                listenerDependency, filter);
+
+        DataPacketListener lDependency = new DataPacketListener(
+                listenerDependency, null, null, null);
+
+        // Now let see if there is any dependency
+        if (listenerDependency == null) {
+            logger.debug("listener without any dependency");
+            if (this.indexDataPacket.contains(l)) {
+                logger.error("trying to add an existing element");
+            } else {
+                logger.debug("adding listener: " + listenerName);
+                CopyOnWriteArrayList<DataPacketListener> serialListeners = new CopyOnWriteArrayList<DataPacketListener>();
+                serialListeners.add(l);
+                this.listenDataPacket.add(serialListeners);
+                this.indexDataPacket.add(l);
+            }
+        } else {
+            logger.debug("listener with dependency");
+            // Now search for the dependency and put things in order
+            if (this.indexDataPacket.contains(l)) {
+                logger.error("trying to add an existing element");
+            } else {
+                logger.debug("adding listener: " + listenerName);
+                // Lets find the set with the dependency in it, if we
+                // find it lets just add our dependency at the end of
+                // the list.
+                for (List<DataPacketListener> serialListeners : this.listenDataPacket) {
+                    int i = 0;
+                    boolean done = false;
+                    if (serialListeners.contains(lDependency)) {
+                        serialListeners.add(l);
+                        done = true;
+                    }
+                    // If we did fine the element, lets break early
+                    if (done) {
+                        break;
+                    }
+                }
+
+                this.indexDataPacket.add(l);
+            }
+        }
+    }
+
+    void unsetListenDataPacket(Map props, IListenDataPacket s) {
+        if (this.listenDataPacket == null || this.indexDataPacket == null) {
+            logger.error("data structure to store data is NULL");
+            return;
+        }
+        logger.trace("Received UNsetListenDataPacket request");
+        for (Object e : props.entrySet()) {
+            Map.Entry entry = (Map.Entry) e;
+            logger.trace("Prop key:(" + entry.getKey() + ") value:("
+                    + entry.getValue() + ")");
+        }
+
+        String listenerName = null;
+        Object value;
+        // Read the listenerName
+        value = props.get("salListenerName");
+        if (value instanceof String) {
+            listenerName = (String) value;
+        }
+
+        if (listenerName == null) {
+            logger.error("Trying to set a listener without a Name");
+            return;
+        }
+
+        DataPacketListener l = new DataPacketListener(listenerName, s, null,
+                null);
+        if (!this.indexDataPacket.contains(l)) {
+            logger.error("trying to remove a non-existing element");
+        } else {
+            logger.debug("removing listener: " + listenerName);
+            for (List<DataPacketListener> serialListeners : this.listenDataPacket) {
+                int i = 0;
+                boolean done = false;
+                for (i = 0; i < serialListeners.size(); i++) {
+                    if (serialListeners.get(i).equals(l)) {
+                        serialListeners.remove(i);
+                        done = true;
+                        break;
+                    }
+                }
+                // Now remove a serialListener that maybe empty
+                if (serialListeners.isEmpty()) {
+                    this.listenDataPacket.remove(serialListeners);
+                }
+                // If we did fine the element, lets break early
+                if (done) {
+                    break;
+                }
+            }
+
+            this.indexDataPacket.remove(l);
+        }
+    }
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init() {
+        this.txThread.start();
+        this.rxThread.start();
+    }
+
+    /**
+     * Function called by the dependency manager when at least one
+     * dependency become unsatisfied or when the component is shutting
+     * down because for example bundle is being stopped.
+     *
+     */
+    void destroy() {
+        // Make sure to cleanup the data structure we use to track
+        // services
+        this.listenDataPacket.clear();
+        this.indexDataPacket.clear();
+        this.pluginInDataService.clear();
+        this.statistics.clear();
+        this.rxQueue.clear();
+        this.txQueue.clear();
+        this.txThread.interrupt();
+        this.rxThread.interrupt();
+        // Wait for them to be done
+        try {
+            this.txThread.join();
+            this.rxThread.join();
+        } catch (InterruptedException ex) {
+            // Not a big deal
+        }
+    }
+
+    private void increaseStat(String name) {
+        if (this.statistics == null) {
+            return;
+        }
+
+        AtomicInteger currValue = null;
+        synchronized (this.statistics) {
+            currValue = this.statistics.get(name);
+
+            if (currValue == null) {
+                this.statistics.put(name, new AtomicInteger(0));
+                return;
+            }
+        }
+        currValue.incrementAndGet();
+    }
+
+    @Override
+    public PacketResult receiveDataPacket(RawPacket inPkt) {
+        if (inPkt.getIncomingNodeConnector() == null) {
+            increaseStat("nullIncomingNodeConnector");
+            return PacketResult.IGNORED;
+        }
+
+        // If the queue was full don't wait, rather increase a counter
+        // for it
+        if (!this.rxQueue.offer(inPkt)) {
+            increaseStat("fullRXQueue");
+            return PacketResult.IGNORED;
+        }
+
+        // Walk the chain of listener going first throw all the
+        // parallel ones and for each parallel in serial
+        return PacketResult.IGNORED;
+    }
+
+    @Override
+    public void transmitDataPacket(RawPacket outPkt) {
+        if (outPkt.getOutgoingNodeConnector() == null) {
+            increaseStat("nullOutgoingNodeConnector");
+            return;
+        }
+
+        if (!this.txQueue.offer(outPkt)) {
+            increaseStat("fullTXQueue");
+            return;
+        }
+    }
+
+    @Override
+    public Packet decodeDataPacket(RawPacket pkt) {
+        // Sanity checks
+        if (pkt == null) {
+            return null;
+        }
+        byte[] data = pkt.getPacketData();
+        if (data.length <= 0) {
+            return null;
+        }
+        if (pkt.getEncap().equals(LinkEncap.ETHERNET)) {
+            Ethernet res = new Ethernet();
+            try {
+                res.deserialize(data, 0, data.length * NetUtils.NumBitsInAByte);
+            } catch (Exception e) {
+                logger.warn("", e);
+            }
+            return res;
+        }
+        return null;
+    }
+
+    @Override
+    public RawPacket encodeDataPacket(Packet pkt) {
+        // Sanity checks
+        if (pkt == null) {
+            return null;
+        }
+        byte[] data;
+        try {
+            data = pkt.serialize();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+        if (data.length <= 0) {
+            return null;
+        }
+        try {
+            RawPacket res = new RawPacket(data);
+            return res;
+        } catch (ConstructionException cex) {
+        }
+        // If something goes wrong then we have to return null
+        return null;
+    }
+}
diff --git a/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/FlowProgrammerService.java b/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/FlowProgrammerService.java
new file mode 100644 (file)
index 0000000..cb0a5c7
--- /dev/null
@@ -0,0 +1,421 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.implementation.internal;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.osgi.framework.console.CommandInterpreter;
+import org.eclipse.osgi.framework.console.CommandProvider;
+import org.opendaylight.controller.sal.action.Action;
+import org.opendaylight.controller.sal.action.Controller;
+import org.opendaylight.controller.sal.action.Flood;
+import org.opendaylight.controller.sal.action.Output;
+import org.opendaylight.controller.sal.action.PopVlan;
+import org.opendaylight.controller.sal.action.SetNwDst;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Node.NodeIDType;
+import org.opendaylight.controller.sal.flowprogrammer.Flow;
+import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerService;
+import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
+import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.controller.sal.utils.EtherTypes;
+import org.opendaylight.controller.sal.utils.IPProtocols;
+import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
+import org.opendaylight.controller.sal.utils.Status;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The SAL Flow Programmer Service. It dispatches the flow programming
+ * requests to the proper SDN protocol plugin
+ *
+ *
+ *
+ */
+public class FlowProgrammerService implements IFlowProgrammerService,
+        CommandProvider {
+
+    protected static final Logger logger = LoggerFactory
+            .getLogger(FlowProgrammerService.class);
+    private ConcurrentHashMap<String, IPluginInFlowProgrammerService>
+        pluginFlowProgrammer =
+        new ConcurrentHashMap<String, IPluginInFlowProgrammerService>();
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init() {
+        logger.debug("INIT called!");
+    }
+
+    /**
+     * Function called by the dependency manager when at least one
+     * dependency become unsatisfied or when the component is shutting
+     * down because for example bundle is being stopped.
+     *
+     */
+    void destroy() {
+        // Clear previous registration to avoid they are left hanging
+        this.pluginFlowProgrammer.clear();
+        logger.debug("DESTROY called!");
+    }
+
+    /**
+     * Function called by dependency manager after "init ()" is called
+     * and after the services provided by the class are registered in
+     * the service registry
+     *
+     */
+    void start() {
+        logger.debug("START called!");
+        // OSGI console
+        registerWithOSGIConsole();
+    }
+
+    /**
+     * Function called by the dependency manager before the services
+     * exported by the component are unregistered, this will be
+     * followed by a "destroy ()" calls
+     *
+     */
+    void stop() {
+        logger.debug("STOP called!");
+    }
+
+    // Set the reference to the plugin flow programmer
+    public void setService(Map props, IPluginInFlowProgrammerService s) {
+        if (this.pluginFlowProgrammer == null) {
+            logger.error("pluginFlowProgrammer store null");
+            return;
+        }
+
+        logger.trace("Got a service set request {}", s);
+        String type = null;
+        for (Object e : props.entrySet()) {
+            Map.Entry entry = (Map.Entry) e;
+            logger.trace("Prop key:(" + entry.getKey() + ") value:("
+                    + entry.getValue() + ")");
+        }
+
+        Object value = props.get("protocolPluginType");
+        if (value instanceof String) {
+            type = (String) value;
+        }
+        if (type == null) {
+            logger.error("Received a pluginFlowProgrammer without any "
+                    + "protocolPluginType provided");
+        } else {
+            this.pluginFlowProgrammer.put(type, s);
+            logger.debug("Stored the pluginFlowProgrammer for type:" + type);
+        }
+    }
+
+    public void unsetService(Map props,
+                             IPluginInFlowProgrammerService s) {
+        if (this.pluginFlowProgrammer == null) {
+            logger.error("pluginFlowProgrammer store null");
+            return;
+        }
+
+        String type = null;
+        logger.debug("Received unsetpluginFlowProgrammer request");
+        for (Object e : props.entrySet()) {
+            Map.Entry entry = (Map.Entry) e;
+            logger.trace("Prop key:(" + entry.getKey() + ") value:("
+                    + entry.getValue() + ")");
+        }
+
+        Object value = props.get("protocoloPluginType");
+        if (value instanceof String) {
+            type = (String) value;
+        }
+        if (type == null) {
+            logger.error("Received a pluginFlowProgrammer without any "
+                    + "protocolPluginType provided");
+        } else if (this.pluginFlowProgrammer.get(type).equals(s)) {
+            this.pluginFlowProgrammer.remove(type);
+            logger.debug("Removed the pluginFlowProgrammer for type:" + type);
+        }
+    }
+
+    @Override
+    public Status addFlow(Node node, Flow flow) {
+        if (pluginFlowProgrammer != null) {
+            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
+                return this.pluginFlowProgrammer.get(node.getType())
+                    .addFlow(node, flow);
+            }
+        }
+        return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
+    }
+
+    @Override
+    public Status removeFlow(Node node, Flow flow) {
+        if (pluginFlowProgrammer != null) {
+            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
+                return this.pluginFlowProgrammer.get(node.getType())
+                    .removeFlow(node, flow);
+            }
+        }
+        return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
+    }
+
+    @Override
+    public Status removeAllFlows(Node node) {
+        if (pluginFlowProgrammer != null) {
+            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
+                return this.pluginFlowProgrammer.get(node.getType())
+                    .removeAllFlows(node);
+            }
+        }
+        return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
+    }
+
+    @Override
+    public Status modifyFlow(Node node, Flow oldFlow, Flow newFlow) {
+        if (pluginFlowProgrammer != null) {
+            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
+                return this.pluginFlowProgrammer.get(node.getType())
+                    .modifyFlow(node, oldFlow, newFlow);
+            }
+        }
+        return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
+    }
+
+    // ---------------- OSGI TEST CODE ------------------------------//
+
+    private void registerWithOSGIConsole() {
+        BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
+                .getBundleContext();
+        bundleContext.registerService(CommandProvider.class.getName(), this,
+                null);
+    }
+
+    @Override
+    public String getHelp() {
+        StringBuffer help = new StringBuffer();
+        help.append("---SAL Flow Programmer testing commands---\n");
+        help
+                .append("\t addflow <sid> - Add a sample flow to the openflow switch <sid>\n");
+        help
+                .append("\t removeflow <sid> - Remove the sample flow from the openflow switch <sid>\n");
+        return help.toString();
+    }
+
+    public void _addflow(CommandInterpreter ci) throws UnknownHostException {
+        Node node = null;
+        String nodeId = ci.nextArgument();
+        if (nodeId == null) {
+            ci.print("Node id not specified");
+            return;
+        }
+        try {
+            node = new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeId));
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+        } catch (ConstructionException e) {
+            e.printStackTrace();
+        }
+        ci.println(this.addFlow(node, getSampleFlow(node)));
+    }
+
+    public void _modifyflow(CommandInterpreter ci) throws UnknownHostException {
+        Node node = null;
+        String nodeId = ci.nextArgument();
+        if (nodeId == null) {
+            ci.print("Node id not specified");
+            return;
+        }
+        try {
+            node = new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeId));
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+        } catch (ConstructionException e) {
+            e.printStackTrace();
+        }
+        Flow flowA = getSampleFlow(node);
+        Flow flowB = getSampleFlow(node);
+        Match matchB = flowB.getMatch();
+        matchB.setField(MatchType.NW_DST, InetAddress
+                .getByName("190.190.190.190"));
+        flowB.setMatch(matchB);
+        ci.println(this.modifyFlow(node, flowA, flowB));
+    }
+
+    public void _removeflow(CommandInterpreter ci) throws UnknownHostException {
+        Node node = null;
+        String nodeId = ci.nextArgument();
+        if (nodeId == null) {
+            ci.print("Node id not specified");
+            return;
+        }
+        try {
+            node = new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeId));
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+        } catch (ConstructionException e) {
+            e.printStackTrace();
+        }
+        ci.println(this.removeFlow(node, getSampleFlow(node)));
+    }
+
+    public void _addflowv6(CommandInterpreter ci) throws UnknownHostException {
+        Node node = null;
+        String nodeId = ci.nextArgument();
+        if (nodeId == null) {
+            ci.print("Node id not specified");
+            return;
+        }
+        try {
+            node = new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeId));
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+        } catch (ConstructionException e) {
+            e.printStackTrace();
+        }
+        ci.println(this.addFlow(node, getSampleFlowV6(node)));
+    }
+
+    public void _removeflowv6(CommandInterpreter ci)
+            throws UnknownHostException {
+        Node node = null;
+        String nodeId = ci.nextArgument();
+        if (nodeId == null) {
+            ci.print("Node id not specified");
+            return;
+        }
+        try {
+            node = new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeId));
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+        } catch (ConstructionException e) {
+            e.printStackTrace();
+        }
+        ci.println(this.removeFlow(node, getSampleFlowV6(node)));
+    }
+
+    private Flow getSampleFlow(Node node) throws UnknownHostException {
+        NodeConnector port = NodeConnectorCreator.createOFNodeConnector(
+                (short) 24, node);
+        NodeConnector oport = NodeConnectorCreator.createOFNodeConnector(
+                (short) 30, node);
+        byte srcMac[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
+                (byte) 0x9a, (byte) 0xbc };
+        byte dstMac[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
+                (byte) 0x5e, (byte) 0x6f };
+        InetAddress srcIP = InetAddress.getByName("172.28.30.50");
+        InetAddress dstIP = InetAddress.getByName("171.71.9.52");
+        InetAddress newIP = InetAddress.getByName("200.200.100.1");
+        InetAddress ipMask = InetAddress.getByName("255.255.255.0");
+        InetAddress ipMask2 = InetAddress.getByName("255.240.0.0");
+        short ethertype = EtherTypes.IPv4.shortValue();
+        short vlan = (short) 27;
+        byte vlanPr = 3;
+        Byte tos = 4;
+        byte proto = IPProtocols.TCP.byteValue();
+        short src = (short) 55000;
+        short dst = 80;
+
+        /*
+         * Create a SAL Flow aFlow
+         */
+        Match match = new Match();
+        match.setField(MatchType.IN_PORT, port);
+        match.setField(MatchType.DL_SRC, srcMac);
+        match.setField(MatchType.DL_DST, dstMac);
+        match.setField(MatchType.DL_TYPE, ethertype);
+        match.setField(MatchType.DL_VLAN, vlan);
+        match.setField(MatchType.DL_VLAN_PR, vlanPr);
+        match.setField(MatchType.NW_SRC, srcIP, ipMask);
+        match.setField(MatchType.NW_DST, dstIP, ipMask2);
+        match.setField(MatchType.NW_TOS, tos);
+        match.setField(MatchType.NW_PROTO, proto);
+        match.setField(MatchType.TP_SRC, src);
+        match.setField(MatchType.TP_DST, dst);
+
+        List<Action> actions = new ArrayList<Action>();
+        actions.add(new SetNwDst(newIP));
+        actions.add(new Output(oport));
+        actions.add(new PopVlan());
+        actions.add(new Flood());
+        actions.add(new Controller());
+
+        Flow flow = new Flow(match, actions);
+        flow.setPriority((short) 100);
+        flow.setHardTimeout((short) 360);
+
+        return flow;
+    }
+
+    private Flow getSampleFlowV6(Node node) throws UnknownHostException {
+        NodeConnector port = NodeConnectorCreator.createOFNodeConnector(
+                (short) 24, node);
+        NodeConnector oport = NodeConnectorCreator.createOFNodeConnector(
+                (short) 30, node);
+        byte srcMac[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
+                (byte) 0x9a, (byte) 0xbc };
+        byte dstMac[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
+                (byte) 0x5e, (byte) 0x6f };
+        InetAddress srcIP = InetAddress
+                .getByName("2001:420:281:1004:407a:57f4:4d15:c355");
+        InetAddress dstIP = InetAddress
+                .getByName("2001:420:281:1004:e123:e688:d655:a1b0");
+        InetAddress ipMask = null; //InetAddress.getByName("ffff:ffff:ffff:ffff:0:0:0:0"); V6Match implementation assumes no mask is specified
+        InetAddress ipMask2 = null; //InetAddress.getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0");
+        short ethertype = EtherTypes.IPv6.shortValue();
+        short vlan = (short) 27;
+        byte vlanPr = (byte) 3;
+        Byte tos = 4;
+        byte proto = IPProtocols.UDP.byteValue();
+        short src = (short) 5500;
+        //short dst = 80;
+
+        /*
+         * Create a SAL Flow aFlow
+         */
+        Match match = new Match();
+        match.setField(MatchType.IN_PORT, port);
+        match.setField(MatchType.DL_SRC, srcMac);
+        match.setField(MatchType.DL_DST, dstMac);
+        match.setField(MatchType.DL_TYPE, ethertype);
+        match.setField(MatchType.DL_VLAN, vlan);
+        match.setField(MatchType.DL_VLAN_PR, vlanPr); //V6Match does not handle this properly...
+        match.setField(MatchType.NW_SRC, srcIP, ipMask);
+        match.setField(MatchType.NW_DST, dstIP, ipMask2);
+        match.setField(MatchType.NW_TOS, tos);
+        match.setField(MatchType.NW_PROTO, proto);
+        match.setField(MatchType.TP_SRC, src); //V6Match does not handle this properly...
+        //match.setField(MatchType.TP_DST, dst); V6Match does not handle this properly...
+
+        List<Action> actions = new ArrayList<Action>();
+        actions.add(new Output(oport));
+        actions.add(new PopVlan());
+        actions.add(new Flood());
+
+        Flow flow = new Flow(match, actions);
+        flow.setPriority((short) 300);
+        flow.setHardTimeout((short) 240);
+
+        return flow;
+    }
+}
diff --git a/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/Inventory.java b/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/Inventory.java
new file mode 100644 (file)
index 0000000..b5f5e2b
--- /dev/null
@@ -0,0 +1,134 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.implementation.internal;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.UpdateType;
+import org.opendaylight.controller.sal.inventory.IInventoryService;
+import org.opendaylight.controller.sal.inventory.IListenInventoryUpdates;
+import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The class describes SAL service to bridge inventory protocol plugin and upper
+ * applications. One instance per container of the network.
+ */
+public class Inventory implements IPluginOutInventoryService, IInventoryService {
+    protected static final Logger logger = LoggerFactory
+            .getLogger(Inventory.class);
+    private IListenInventoryUpdates updateService = null;
+    private IPluginInInventoryService pluginService = null;
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init() {
+        logger.trace("INIT called!");
+    }
+
+    /**
+     * Function called by the dependency manager when at least one
+     * dependency become unsatisfied or when the component is shutting
+     * down because for example bundle is being stopped.
+     *
+     */
+    void destroy() {
+        logger.trace("DESTROY called!");
+    }
+
+    /**
+     * Function called by dependency manager after "init ()" is called
+     * and after the services provided by the class are registered in
+     * the service registry
+     *
+     */
+    void start() {
+        logger.trace("START called!");
+
+        if (pluginService == null) {
+            logger.debug("plugin service not avaiable");
+            return;
+        }
+    }
+
+    /**
+     * Function called by the dependency manager before the services
+     * exported by the component are unregistered, this will be
+     * followed by a "destroy ()" calls
+     *
+     */
+    void stop() {
+        logger.trace("STOP called!");
+    }
+
+    public void setPluginService(IPluginInInventoryService service) {
+        logger.trace("Got plugin service set request {}", service);
+        this.pluginService = service;
+    }
+
+    public void unsetPluginService(IPluginInInventoryService service) {
+        logger.trace("Got plugin service UNset request");
+        this.pluginService = null;
+    }
+
+    public void setUpdateService(IListenInventoryUpdates service) {
+        logger.trace("Got update service set request {}", service);
+        this.updateService = service;
+    }
+
+    public void unsetUpdateService(IListenInventoryUpdates service) {
+        logger.trace("Got a service UNset request");
+        this.updateService = null;
+    }
+
+    @Override
+    public void updateNode(Node node, UpdateType type, Set<Property> props) {
+        logger.trace("{} {}", node, type);
+        if (updateService != null) {
+            updateService.updateNode(node, type, props);
+        }
+    }
+
+    @Override
+    public void updateNodeConnector(NodeConnector nodeConnector,
+            UpdateType type, Set<Property> props) {
+        logger.trace("{} {}", nodeConnector, type);
+
+        if ((updateService != null) && (type != null)) {
+            updateService.updateNodeConnector(nodeConnector, type, props);
+        }
+    }
+
+    @Override
+    public ConcurrentMap<Node, Map<String, Property>> getNodeProps() {
+        if (pluginService != null)
+            return pluginService.getNodeProps();
+        else
+            return null;
+    }
+
+    @Override
+    public ConcurrentMap<NodeConnector, Map<String, Property>> getNodeConnectorProps() {
+        if (pluginService != null)
+            return pluginService.getNodeConnectorProps(true);
+        else
+            return null;
+    }
+}
diff --git a/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/ReadService.java b/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/ReadService.java
new file mode 100644 (file)
index 0000000..81bfa5b
--- /dev/null
@@ -0,0 +1,500 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.implementation.internal;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.osgi.framework.console.CommandInterpreter;
+import org.eclipse.osgi.framework.console.CommandProvider;
+import org.opendaylight.controller.sal.action.Action;
+import org.opendaylight.controller.sal.action.Controller;
+import org.opendaylight.controller.sal.action.Flood;
+import org.opendaylight.controller.sal.action.Output;
+import org.opendaylight.controller.sal.action.PopVlan;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Node.NodeIDType;
+import org.opendaylight.controller.sal.flowprogrammer.Flow;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
+import org.opendaylight.controller.sal.reader.FlowOnNode;
+import org.opendaylight.controller.sal.reader.IPluginInReadService;
+import org.opendaylight.controller.sal.reader.IReadService;
+import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
+import org.opendaylight.controller.sal.reader.NodeDescription;
+import org.opendaylight.controller.sal.utils.EtherTypes;
+import org.opendaylight.controller.sal.utils.IPProtocols;
+import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
+import org.opendaylight.controller.sal.utils.NodeCreator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The SAL Read Service. It dispatches the read request to
+ * the proper SDN protocol plugin
+ *
+ *
+ *
+ */
+public class ReadService implements IReadService, CommandProvider {
+
+    protected static final Logger logger = LoggerFactory
+            .getLogger(ReadService.class);
+    private ConcurrentHashMap<String, IPluginInReadService>
+        pluginReader =
+        new ConcurrentHashMap<String, IPluginInReadService>();
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init() {
+    }
+
+    /**
+     * Function called by the dependency manager when at least one
+     * dependency become unsatisfied or when the component is shutting
+     * down because for example bundle is being stopped.
+     *
+     */
+    void destroy() {
+        // In case of plugin disactivating make sure we clear the
+        // dependencies
+        this.pluginReader.clear();
+    }
+
+    /**
+     * Function called by dependency manager after "init ()" is called
+     * and after the services provided by the class are registered in
+     * the service registry
+     *
+     */
+    void start() {
+        registerWithOSGIConsole();
+    }
+
+    /**
+     * Function called by the dependency manager before the services
+     * exported by the component are unregistered, this will be
+     * followed by a "destroy ()" calls
+     *
+     */
+    void stop() {
+    }
+
+    // Set the reference to the plugin flow Reader service
+    public void setService(Map props, IPluginInReadService s) {
+        if (this.pluginReader == null) {
+            logger.error("pluginReader store null");
+            return;
+        }
+
+        logger.trace("Got a service set request {}", s);
+        String type = null;
+        for (Object e : props.entrySet()) {
+            Map.Entry entry = (Map.Entry) e;
+            logger.trace("Prop key:(" + entry.getKey() + ") value:("
+                    + entry.getValue() + ")");
+        }
+
+        Object value = props.get("protocolPluginType");
+        if (value instanceof String) {
+            type = (String) value;
+        }
+        if (type == null) {
+            logger.error("Received a pluginReader without any "
+                    + "protocolPluginType provided");
+        } else {
+            this.pluginReader.put(type, s);
+            logger.debug("Stored the pluginReader for type:" + type);
+        }
+    }
+
+    public void unsetService(Map props, IPluginInReadService s) {
+        if (this.pluginReader == null) {
+            logger.error("pluginReader store null");
+            return;
+        }
+
+        String type = null;
+        logger.debug("Received unsetpluginReader request");
+        for (Object e : props.entrySet()) {
+            Map.Entry entry = (Map.Entry) e;
+            logger.trace("Prop key:(" + entry.getKey() + ") value:("
+                    + entry.getValue() + ")");
+        }
+
+        Object value = props.get("protocoloPluginType");
+        if (value instanceof String) {
+            type = (String) value;
+        }
+        if (type == null) {
+            logger.error("Received a pluginReader without any "
+                    + "protocolPluginType provided");
+        } else if (this.pluginReader.get(type).equals(s)) {
+            this.pluginReader.remove(type);
+            logger.debug("Removed the pluginReader for type:" + type);
+        }
+    }
+
+    @Override
+    public FlowOnNode readFlow(Node node, Flow flow) {
+        if (pluginReader != null) {
+            if (this.pluginReader.get(node.getType()) != null) {
+                return this.pluginReader.get(node.getType())
+                    .readFlow(node, flow, true);
+            }
+        }
+        logger.warn("Plugin unuvailable");
+        return null;
+    }
+
+    @Override
+    public FlowOnNode nonCachedReadFlow(Node node, Flow flow) {
+        if (pluginReader != null) {
+            if (this.pluginReader.get(node.getType()) != null) {
+                return this.pluginReader.get(node.getType())
+                    .readFlow(node, flow, false);
+            }
+        }
+        logger.warn("Plugin unuvailable");
+        return null;
+    }
+
+    @Override
+    public List<FlowOnNode> readAllFlows(Node node) {
+        if (pluginReader != null) {
+            if (this.pluginReader.get(node.getType()) != null) {
+                return this.pluginReader.get(node.getType())
+                    .readAllFlow(node, true);
+            }
+        }
+        logger.warn("Plugin unuvailable");
+        return null;
+    }
+
+    @Override
+    public List<FlowOnNode> nonCachedReadAllFlows(Node node) {
+        if (pluginReader != null) {
+            if (this.pluginReader.get(node.getType()) != null) {
+                return this.pluginReader.get(node.getType())
+                    .readAllFlow(node, false);
+            }
+        }
+        logger.warn("Plugin unuvailable");
+        return null;
+    }
+
+    @Override
+    public NodeDescription readDescription(Node node) {
+        if (pluginReader != null) {
+            if (this.pluginReader.get(node.getType()) != null) {
+                return this.pluginReader.get(node.getType())
+                    .readDescription(node, true);
+            }
+        }
+        logger.warn("Plugin unuvailable");
+        return null;
+    }
+
+    @Override
+    public NodeDescription nonCachedReadDescription(Node node) {
+        if (pluginReader != null) {
+            if (this.pluginReader.get(node.getType()) != null) {
+                return this.pluginReader.get(node.getType())
+                    .readDescription(node, false);
+            }
+        }
+        logger.warn("Plugin unuvailable");
+        return null;
+    }
+
+    @Override
+    public NodeConnectorStatistics readNodeConnector(NodeConnector connector) {
+        Node node = connector.getNode();
+        if (pluginReader != null && node != null) {
+            if (this.pluginReader.get(node.getType()) != null) {
+                return this.pluginReader.get(node.getType())
+                    .readNodeConnector(connector, true);
+            }
+        }
+        logger.warn("Plugin unuvailable");
+        return null;
+    }
+
+    @Override
+    public NodeConnectorStatistics nonCachedReadNodeConnector(
+            NodeConnector connector) {
+        Node node = connector.getNode();
+        if (pluginReader != null && node != null) {
+            if (this.pluginReader.get(node.getType()) != null) {
+                return this.pluginReader.get(node.getType())
+                    .readNodeConnector(connector, false);
+            }
+        }
+        logger.warn("Plugin unuvailable");
+        return null;
+    }
+
+    @Override
+    public List<NodeConnectorStatistics> readNodeConnectors(Node node) {
+        if (pluginReader != null) {
+            if (this.pluginReader.get(node.getType()) != null) {
+                return this.pluginReader.get(node.getType())
+                    .readAllNodeConnector(node, true);
+            }
+        }
+        logger.warn("Plugin unuvailable");
+        return null;
+    }
+
+    @Override
+    public List<NodeConnectorStatistics> nonCachedReadNodeConnectors(Node node) {
+        if (pluginReader != null) {
+            if (this.pluginReader.get(node.getType()) != null) {
+                return this.pluginReader.get(node.getType())
+                    .readAllNodeConnector(node, false);
+            }
+        }
+        logger.warn("Plugin unuvailable");
+        return null;
+    }
+
+    @Override
+    public long getTransmitRate(NodeConnector connector) {
+        Node node = connector.getNode();
+        if (pluginReader != null && node != null) {
+            if (this.pluginReader.get(node.getType()) != null) {
+                return this.pluginReader.get(node.getType())
+                    .getTransmitRate(connector);
+            }
+        }
+        logger.warn("Plugin unuvailable");
+        return 0;
+    }
+
+    // ---------------- OSGI TEST CODE ------------------------------//
+
+    private void registerWithOSGIConsole() {
+        BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
+                .getBundleContext();
+        bundleContext.registerService(CommandProvider.class.getName(), this,
+                null);
+    }
+
+    @Override
+    public String getHelp() {
+        StringBuffer help = new StringBuffer();
+        help.append("---SAL Reader testing commands---\n");
+        help
+                .append("\t readflows <sid> <cached>  - Read all the (cached) flows from the openflow switch <sid>\n");
+        help
+                .append("\t readflow  <sid> <cached>  - Read the (cached) sample flow from the openflow switch <sid>\n");
+        help
+                .append("\t readdesc  <sid> <cached>  - Read the (cached) description from openflow switch <sid>\n");
+        help
+                .append("\t           cached=true/false. If false or not specified, the protocol plugin cached info\n");
+        help
+                .append("\t           is returned. If true, the info is directly retrieved from the switch\n");
+        return help.toString();
+    }
+
+    public void _readflows(CommandInterpreter ci) {
+        String nodeId = ci.nextArgument();
+        String cacheReq = ci.nextArgument();
+        boolean cached;
+        if (nodeId == null) {
+            ci.print("Node id not specified");
+            return;
+        }
+        cached = (cacheReq == null) ? true : cacheReq.equals("true");
+        Node node = null;
+        try {
+            node = new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeId));
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+        } catch (ConstructionException e) {
+            e.printStackTrace();
+        }
+        List<FlowOnNode> list = (cached) ? this.readAllFlows(node) : this
+                .nonCachedReadAllFlows(node);
+        if (list != null) {
+            ci.println(list.toString());
+        } else {
+            ci.println("null");
+        }
+    }
+
+    // Requests the hw view for the specific sample flow
+    public void _readflow(CommandInterpreter ci) throws UnknownHostException {
+        String nodeId = ci.nextArgument();
+        String cacheReq = ci.nextArgument();
+        boolean cached;
+        if (nodeId == null) {
+            ci.print("Node id not specified");
+            return;
+        }
+        cached = (cacheReq == null) ? true : cacheReq.equals("true");
+        Node node = null;
+        try {
+            node = new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeId));
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+        } catch (ConstructionException e) {
+            e.printStackTrace();
+        }
+        Flow flow = getSampleFlow(node);
+        FlowOnNode flowOnNode = (cached) ? this.readFlow(node, flow) : this
+                .nonCachedReadFlow(node, flow);
+        if (flowOnNode != null) {
+            ci.println(flowOnNode.toString());
+        } else {
+            ci.println("null");
+        }
+    }
+
+    public void _readports(CommandInterpreter ci) {
+        String nodeId = ci.nextArgument();
+        String cacheReq = ci.nextArgument();
+        boolean cached;
+        if (nodeId == null) {
+            ci.print("Node id not specified");
+            return;
+        }
+        cached = (cacheReq == null) ? true : cacheReq.equals("true");
+        Node node = null;
+        try {
+            node = new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeId));
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+        } catch (ConstructionException e) {
+            e.printStackTrace();
+        }
+        List<NodeConnectorStatistics> list = (cached) ? this
+                .readNodeConnectors(node) : this
+                .nonCachedReadNodeConnectors(node);
+        if (list != null) {
+            ci.println(list.toString());
+        } else {
+            ci.println("null");
+        }
+    }
+
+    public void _readport(CommandInterpreter ci) {
+        String nodeId = ci.nextArgument();
+        String portId = ci.nextArgument();
+        String cacheReq = ci.nextArgument();
+        boolean cached;
+        if (nodeId == null) {
+            ci.print("Node id not specified");
+            return;
+        }
+        if (portId == null) {
+            ci.print("Port id not specified");
+            return;
+        }
+        cached = (cacheReq == null) ? true : cacheReq.equals("true");
+        NodeConnector nodeConnector = null;
+        Node node = NodeCreator.createOFNode(Long.parseLong(nodeId));
+        nodeConnector = NodeConnectorCreator.createNodeConnector(Short
+                .valueOf(portId), node);
+        NodeConnectorStatistics stats = (cached) ? this
+                .readNodeConnector(nodeConnector) : this
+                .nonCachedReadNodeConnector(nodeConnector);
+        if (stats != null) {
+            ci.println(stats.toString());
+        } else {
+            ci.println("null");
+        }
+    }
+
+    public void _readdescr(CommandInterpreter ci) {
+        String nodeId = ci.nextArgument();
+        String cacheReq = ci.nextArgument();
+        boolean cached;
+        if (nodeId == null) {
+            ci.print("Node id not specified");
+            return;
+        }
+        cached = (cacheReq == null) ? true : cacheReq.equals("true");
+
+        Node node = null;
+        try {
+            node = new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeId));
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+        } catch (ConstructionException e) {
+            e.printStackTrace();
+        }
+        NodeDescription desc = (cached) ? this.readDescription(node) : this
+                .nonCachedReadDescription(node);
+        if (desc != null) {
+            ci.println(desc.toString());
+        } else {
+            ci.println("null");
+        }
+    }
+
+    private Flow getSampleFlow(Node node) throws UnknownHostException {
+        NodeConnector port = NodeConnectorCreator.createOFNodeConnector(
+                (short) 24, node);
+        NodeConnector oport = NodeConnectorCreator.createOFNodeConnector(
+                (short) 30, node);
+        byte srcMac[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
+                (byte) 0x9a, (byte) 0xbc };
+        byte dstMac[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
+                (byte) 0x5e, (byte) 0x6f };
+        InetAddress srcIP = InetAddress.getByName("172.28.30.50");
+        InetAddress dstIP = InetAddress.getByName("171.71.9.52");
+        InetAddress ipMask = InetAddress.getByName("255.255.255.0");
+        InetAddress ipMask2 = InetAddress.getByName("255.0.0.0");
+        short ethertype = EtherTypes.IPv4.shortValue();
+        short vlan = (short) 27;
+        byte vlanPr = 3;
+        Byte tos = 4;
+        byte proto = IPProtocols.TCP.byteValue();
+        short src = (short) 55000;
+        short dst = 80;
+
+        /*
+         * Create a SAL Flow aFlow
+         */
+        Match match = new Match();
+        match.setField(MatchType.IN_PORT, port);
+        match.setField(MatchType.DL_SRC, srcMac);
+        match.setField(MatchType.DL_DST, dstMac);
+        match.setField(MatchType.DL_TYPE, ethertype);
+        match.setField(MatchType.DL_VLAN, vlan);
+        match.setField(MatchType.DL_VLAN_PR, vlanPr);
+        match.setField(MatchType.NW_SRC, srcIP, ipMask);
+        match.setField(MatchType.NW_DST, dstIP, ipMask2);
+        match.setField(MatchType.NW_TOS, tos);
+        match.setField(MatchType.NW_PROTO, proto);
+        match.setField(MatchType.TP_SRC, src);
+        match.setField(MatchType.TP_DST, dst);
+
+        List<Action> actions = new ArrayList<Action>();
+        actions.add(new Output(oport));
+        actions.add(new PopVlan());
+        actions.add(new Flood());
+        actions.add(new Controller());
+        return new Flow(match, actions);
+    }
+
+}
diff --git a/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/Topology.java b/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/Topology.java
new file mode 100644 (file)
index 0000000..8df566f
--- /dev/null
@@ -0,0 +1,118 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.implementation.internal;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Collections;
+
+import org.opendaylight.controller.sal.core.Edge;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.UpdateType;
+import org.opendaylight.controller.sal.topology.IListenTopoUpdates;
+import org.opendaylight.controller.sal.topology.IPluginInTopologyService;
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService;
+import org.opendaylight.controller.sal.topology.ITopologyService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Topology implements IPluginOutTopologyService, ITopologyService {
+    protected static final Logger logger = LoggerFactory
+            .getLogger(Topology.class);
+    private Set<IListenTopoUpdates> updateService = Collections
+            .synchronizedSet(new HashSet<IListenTopoUpdates>());
+    private Set<IPluginInTopologyService> pluginService = Collections
+            .synchronizedSet(new HashSet<IPluginInTopologyService>());
+
+    void setPluginService(IPluginInTopologyService s) {
+        if (this.pluginService != null) {
+            this.pluginService.add(s);
+        }
+    }
+
+    void unsetPluginService(IPluginInTopologyService s) {
+        if (this.pluginService != null) {
+            this.pluginService.remove(s);
+        }
+    }
+
+    void setUpdateService(IListenTopoUpdates s) {
+        if (this.updateService != null) {
+            this.updateService.add(s);
+        }
+    }
+
+    void unsetUpdateService(IListenTopoUpdates s) {
+        if (this.updateService != null) {
+            this.updateService.remove(s);
+        }
+    }
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init() {
+    }
+
+    /**
+     * Function called by the dependency manager when at least one
+     * dependency become unsatisfied or when the component is shutting
+     * down because for example bundle is being stopped.
+     *
+     */
+    void destroy() {
+        // Make sure to clear all the data structure we use to track
+        // services
+        if (this.updateService != null) {
+            this.updateService.clear();
+        }
+        if (this.pluginService != null) {
+            this.pluginService.clear();
+        }
+    }
+
+    @Override
+    public void sollicitRefresh() {
+        synchronized (this.pluginService) {
+            for (IPluginInTopologyService s : this.pluginService) {
+                s.sollicitRefresh();
+            }
+        }
+    }
+
+    @Override
+    public void edgeUpdate(Edge e, UpdateType type, Set<Property> props) {
+        synchronized (this.updateService) {
+            for (IListenTopoUpdates s : this.updateService) {
+                s.edgeUpdate(e, type, props);
+            }
+        }
+    }
+
+    @Override
+    public void edgeOverUtilized(Edge edge) {
+        synchronized (this.updateService) {
+            for (IListenTopoUpdates s : this.updateService) {
+                s.edgeOverUtilized(edge);
+            }
+        }
+    }
+
+    @Override
+    public void edgeUtilBackToNormal(Edge edge) {
+        synchronized (this.updateService) {
+            for (IListenTopoUpdates s : this.updateService) {
+                s.edgeUtilBackToNormal(edge);
+            }
+        }
+    }
+}
diff --git a/opendaylight/sal/implementation/src/test/java/org/opendaylight/controller/sal/implementation/DataPacketServiceTest.java b/opendaylight/sal/implementation/src/test/java/org/opendaylight/controller/sal/implementation/DataPacketServiceTest.java
new file mode 100644 (file)
index 0000000..730764a
--- /dev/null
@@ -0,0 +1,180 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.implementation;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.implementation.internal.DataPacketService;
+import org.opendaylight.controller.sal.packet.ARP;
+import org.opendaylight.controller.sal.packet.Ethernet;
+import org.opendaylight.controller.sal.packet.Packet;
+import org.opendaylight.controller.sal.packet.RawPacket;
+
+public class DataPacketServiceTest {
+
+       @Test
+       public void DataPacketServiceDecodeTest() throws ConstructionException, InstantiationException, IllegalAccessException {
+               
+               DataPacketService dService = new DataPacketService();
+               RawPacket rawPkt = null;
+               
+               Assert.assertTrue(dService.decodeDataPacket(rawPkt) == null);
+               
+        byte[] data = { 10, 12, 14, 20, 55, 69, //DMAC
+                -90, -20, -100, -82, -78, -97, //SMAC
+                8, 6, //ethype
+                0, 1, // hw type
+                8, 0, // proto (ip)
+                6, // hw addr len
+                4, // proto addr len
+                0, 1, // op codes
+                -90, -20, -100, -82, -78, -97, //src hw addr
+                9, 9, 9, 1, // src proto
+                0, 0, 0, 0, 0, 0, // target hw addr
+                9, 9, 9, -2 }; // target proto
+        
+        rawPkt = new RawPacket(data);
+        
+        Packet decodedPkt = dService.decodeDataPacket(rawPkt);
+        Class<? extends Packet> payloadClass = ARP.class;
+        Assert.assertTrue(payloadClass == decodedPkt.getPayload().getClass());
+                
+        ARP arpPacket = (ARP) decodedPkt.getPayload();
+        
+        Assert.assertTrue(arpPacket.getHardwareType() == (byte)0x1);
+        Assert.assertTrue(arpPacket.getProtocolType() == 2048);
+        Assert.assertTrue(arpPacket.getHardwareAddressLength() == (byte)0x6);
+        Assert.assertTrue(arpPacket.getProtocolAddressLength() == (byte)0x4);
+        Assert.assertTrue(arpPacket.getOpCode() == 1);
+        
+        byte[] senderHwAddress = arpPacket.getSenderHardwareAddress();
+        byte[] senderProtocolAddress = arpPacket.getSenderProtocolAddress(); 
+        
+        byte[] targetHwAddress = arpPacket.getTargetHardwareAddress();
+        byte[] targetProtocolAddress = arpPacket.getTargetProtocolAddress(); 
+
+        
+        Assert.assertTrue(senderHwAddress[0] == (byte)0xA6);
+        Assert.assertTrue(senderHwAddress[1] == (byte)0xEC);
+        Assert.assertTrue(senderHwAddress[2] == (byte)0x9C);
+        Assert.assertTrue(senderHwAddress[3] == (byte)0xAE);
+        Assert.assertTrue(senderHwAddress[4] == (byte)0xB2);
+        Assert.assertTrue(senderHwAddress[5] == (byte)0x9F);
+        
+        Assert.assertTrue(senderProtocolAddress[0] == (byte)0x9);
+        Assert.assertTrue(senderProtocolAddress[1] == (byte)0x9);
+        Assert.assertTrue(senderProtocolAddress[2] == (byte)0x9);
+        Assert.assertTrue(senderProtocolAddress[3] == (byte)0x1);
+
+        Assert.assertTrue(targetHwAddress[0] == (byte)0x0);
+        Assert.assertTrue(targetHwAddress[1] == (byte)0x0);
+        Assert.assertTrue(targetHwAddress[2] == (byte)0x0);
+        Assert.assertTrue(targetHwAddress[3] == (byte)0x0);
+        Assert.assertTrue(targetHwAddress[4] == (byte)0x0);
+        Assert.assertTrue(targetHwAddress[5] == (byte)0x0);
+
+        Assert.assertTrue(senderProtocolAddress[0] == (byte)0x9);
+        Assert.assertTrue(senderProtocolAddress[1] == (byte)0x9);
+        Assert.assertTrue(senderProtocolAddress[2] == (byte)0x9);
+        Assert.assertTrue(senderProtocolAddress[3] == (byte)0x1);
+
+        Assert.assertTrue(targetProtocolAddress[0] == (byte)0x9);
+        Assert.assertTrue(targetProtocolAddress[1] == (byte)0x9);
+        Assert.assertTrue(targetProtocolAddress[2] == (byte)0x9);
+        Assert.assertTrue(targetProtocolAddress[3] == (byte)0xFE);      
+       }
+       
+       @Test
+       public void DataPacketServiceEncodeTest() throws ConstructionException, InstantiationException, IllegalAccessException {
+               
+               DataPacketService dService = new DataPacketService();
+               Ethernet eth = new Ethernet();
+        ARP arp = new ARP();
+
+               byte[] data = null;
+               RawPacket rawPkt;
+
+
+        byte[] dMAC = { 10, 12, 14, 20, 55, 69 };
+        byte[] sMAC = { 82, 97, 109, 117, 127, -50 };
+        short etherType = 2054;
+        
+        eth.setDestinationMACAddress(dMAC);
+        eth.setSourceMACAddress(sMAC);
+        eth.setEtherType(etherType);
+               
+        arp.setHardwareType((short)1);
+        arp.setProtocolType((short)2048);
+        arp.setHardwareAddressLength((byte)0x6);
+        arp.setProtocolAddressLength((byte)0x4);
+        arp.setOpCode((byte)0x1);
+        
+        byte[] senderHardwareAddress = {(byte)0xA6, (byte)0xEC, (byte)0x9C, (byte)0xAE,
+                                                                       (byte)0xB2, (byte)0x9F};
+        byte[] senderProtocolAddress = {(byte)0x09, (byte)0x09, (byte)0x09, (byte)0x01};
+        byte[] targetProtocolAddress = {(byte)0x09, (byte)0x09, (byte)0x09, (byte)0xFE};
+        byte[] targetHardwareAddress = {(byte)0x0, (byte)0x0, (byte)0x0, (byte)0x0, (byte)0x0, (byte)0x0};
+        arp.setSenderHardwareAddress(senderHardwareAddress);
+        arp.setSenderProtocolAddress(senderProtocolAddress);
+        arp.setTargetHardwareAddress(targetHardwareAddress);
+        arp.setTargetProtocolAddress(targetProtocolAddress);
+                
+        arp.setParent(eth);
+        eth.setPayload(arp);
+        
+        rawPkt = dService.encodeDataPacket(eth);
+        data = rawPkt.getPacketData();
+        
+        Assert.assertTrue(data[0] == (byte)0x0A);//Destination MAC
+        Assert.assertTrue(data[1] == (byte)0x0C);
+        Assert.assertTrue(data[2] == (byte)0x0E);
+        Assert.assertTrue(data[3] == (byte)0x14);
+        Assert.assertTrue(data[4] == (byte)0x37);
+        Assert.assertTrue(data[5] == (byte)0x45);
+        Assert.assertTrue(data[6] == (byte)0x52);//Source MAC
+        Assert.assertTrue(data[7] == (byte)0x61);
+        Assert.assertTrue(data[8] == (byte)0x6D);
+        Assert.assertTrue(data[9] == (byte)0x75);
+        Assert.assertTrue(data[10] == (byte)0x7F);
+        Assert.assertTrue(data[11] == (byte)0xCE);
+        Assert.assertTrue(data[12] == (byte)0x08);//EtherType
+        Assert.assertTrue(data[13] == (byte)0x06);
+        Assert.assertTrue(data[14] == (byte)0x00);//Hardware Type
+        Assert.assertTrue(data[15] == (byte)0x01);
+        Assert.assertTrue(data[16] == (byte)0x08);//Protocol Type
+        Assert.assertTrue(data[17] == (byte)0x0);
+        Assert.assertTrue(data[18] == (byte)0x6);//Hardware Address Length
+        Assert.assertTrue(data[19] == (byte)0x4);//Protocol Address Length
+        Assert.assertTrue(data[20] == (byte)0x0);//Opcode
+        Assert.assertTrue(data[21] == (byte)0x1);//Opcode
+        Assert.assertTrue(data[22] == (byte)0xA6);//Sender Hardware Address
+        Assert.assertTrue(data[23] == (byte)0xEC);
+        Assert.assertTrue(data[24] == (byte)0x9C);
+        Assert.assertTrue(data[25] == (byte)0xAE);
+        Assert.assertTrue(data[26] == (byte)0xB2);
+        Assert.assertTrue(data[27] == (byte)0x9F);
+        Assert.assertTrue(data[28] == (byte)0x09);//Sender Protocol Address
+        Assert.assertTrue(data[29] == (byte)0x09);
+        Assert.assertTrue(data[30] == (byte)0x09);
+        Assert.assertTrue(data[31] == (byte)0x01);//Target Hardware Address
+        Assert.assertTrue(data[32] == (byte)0x00);
+        Assert.assertTrue(data[33] == (byte)0x00);
+        Assert.assertTrue(data[34] == (byte)0x00);
+        Assert.assertTrue(data[35] == (byte)0x00);
+        Assert.assertTrue(data[36] == (byte)0x00);
+        Assert.assertTrue(data[37] == (byte)0x00);
+        Assert.assertTrue(data[38] == (byte)0x09);//Target Protocol Address
+        Assert.assertTrue(data[39] == (byte)0x09);
+        Assert.assertTrue(data[40] == (byte)0x09);
+        Assert.assertTrue(data[41] == (byte)0xFE);    
+       }
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/.gitignore b/opendaylight/sal/yang-prototype/code-generator/.gitignore
new file mode 100644 (file)
index 0000000..40a85ff
--- /dev/null
@@ -0,0 +1 @@
+/.settings
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-api/pom.xml b/opendaylight/sal/yang-prototype/code-generator/binding-generator-api/pom.xml
new file mode 100644 (file)
index 0000000..a45b6f3
--- /dev/null
@@ -0,0 +1,21 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>binding-generator</artifactId>\r
+    <version>1.0</version>\r
+  </parent>\r
+  <artifactId>binding-generator-api</artifactId>\r
+  <dependencies>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>binding-model-api</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>sal-schema-repository-api</artifactId>\r
+          <version>1.0-SNAPSHOT</version>\r
+      </dependency>\r
+  </dependencies>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-api/src/main/java/org/opendaylight/controller/sal/binding/generator/api/BindingGenerator.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-api/src/main/java/org/opendaylight/controller/sal/binding/generator/api/BindingGenerator.java
new file mode 100644 (file)
index 0000000..686f364
--- /dev/null
@@ -0,0 +1,19 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.generator.api;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.GeneratedType;\r
+import org.opendaylight.controller.yang.model.api.Module;\r
+\r
+public interface BindingGenerator {\r
+\r
+    public List<GeneratedType> generateTypes(final Module module);\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-api/src/main/java/org/opendaylight/controller/sal/binding/generator/api/package-info.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-api/src/main/java/org/opendaylight/controller/sal/binding/generator/api/package-info.java
new file mode 100644 (file)
index 0000000..237690c
--- /dev/null
@@ -0,0 +1,8 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.binding.generator.api;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/pom.xml b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/pom.xml
new file mode 100644 (file)
index 0000000..9b178c0
--- /dev/null
@@ -0,0 +1,32 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>binding-generator</artifactId>\r
+    <version>1.0</version>\r
+  </parent>\r
+  <artifactId>binding-generator-impl</artifactId>\r
+  <dependencies>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>binding-generator-util</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>yang-model-parser-impl</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>binding-generator-api</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>binding-generator-spi</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+  </dependencies>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/BindingGeneratorImpl.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/BindingGeneratorImpl.java
new file mode 100644 (file)
index 0000000..d346352
--- /dev/null
@@ -0,0 +1,420 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.binding.generator.impl;
+
+import java.net.URI;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.controller.binding.generator.util.CodeGeneratorHelper;
+import org.opendaylight.controller.binding.generator.util.Types;
+import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
+import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;
+import org.opendaylight.controller.sal.binding.model.api.GeneratedType;
+import org.opendaylight.controller.sal.binding.model.api.Type;
+import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
+import org.opendaylight.controller.sal.binding.model.api.type.builder.MethodSignatureBuilder;
+import org.opendaylight.controller.sal.binding.yang.types.TypeProviderImpl;
+import org.opendaylight.controller.yang.common.QName;
+import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.controller.yang.model.api.DataNodeContainer;
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;
+import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
+import org.opendaylight.controller.yang.model.api.ListSchemaNode;
+import org.opendaylight.controller.yang.model.api.Module;
+import org.opendaylight.controller.yang.model.api.SchemaPath;
+import org.opendaylight.controller.yang.model.api.TypeDefinition;
+
+public class BindingGeneratorImpl implements BindingGenerator {
+
+    private static DateFormat simpleDateFormat = new SimpleDateFormat(
+            "yyyy-MM-dd");
+    private static Calendar calendar = new GregorianCalendar();
+
+    private final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;
+    private final List<ContainerSchemaNode> schemaContainers;
+    private final List<ListSchemaNode> schemaLists;
+
+    private final TypeProvider typeProvider;
+
+    private String basePackageName;
+
+    public BindingGeneratorImpl() {
+        super();
+        genTypeBuilders = new HashMap<String, Map<String, GeneratedTypeBuilder>>();
+        schemaContainers = new ArrayList<ContainerSchemaNode>();
+        schemaLists = new ArrayList<ListSchemaNode>();
+
+        // TODO: reimplement in better way
+        typeProvider = new TypeProviderImpl();
+    }
+
+    @Override
+    public List<GeneratedType> generateTypes(final Module module) {
+        final List<GeneratedType> genTypes = new ArrayList<GeneratedType>();
+
+        basePackageName = resolveBasePackageName(module.getNamespace(),
+                module.getYangVersion());
+
+        traverseModule(module);
+        if (schemaContainers.size() > 0) {
+            for (final ContainerSchemaNode container : schemaContainers) {
+                genTypes.add(containerToGenType(container));
+            }
+        }
+
+        if (schemaLists.size() > 0) {
+            for (final ListSchemaNode list : schemaLists) {
+                genTypes.add(listToGenType(list));
+            }
+        }
+
+        return genTypes;
+    }
+
+    private String resolveGeneratedTypePackageName(final SchemaPath schemaPath) {
+        final StringBuilder builder = new StringBuilder();
+        builder.append(basePackageName);
+        if ((schemaPath != null) && (schemaPath.getPath() != null)) {
+            final List<QName> pathToNode = schemaPath.getPath();
+            for (int i = 0; i < pathToNode.size(); ++i) {
+                builder.append(".");
+                String nodeLocalName = pathToNode.get(i).getLocalName();
+
+                // TODO: create method
+                nodeLocalName = nodeLocalName.replace(":", ".");
+                nodeLocalName = nodeLocalName.replace("-", ".");
+                builder.append(nodeLocalName);
+            }
+            return builder.toString();
+        }
+        return null;
+    }
+
+    private GeneratedType containerToGenType(ContainerSchemaNode container) {
+        if (container == null) {
+            return null;
+        }
+        final Set<DataSchemaNode> schemaNodes = container.getChildNodes();
+        final GeneratedTypeBuilder typeBuilder = addRawInterfaceDefinition(container);
+
+        for (final DataSchemaNode node : schemaNodes) {
+            if (node instanceof LeafSchemaNode) {
+                resolveLeafSchemaNode(typeBuilder, (LeafSchemaNode) node);
+            } else if (node instanceof LeafListSchemaNode) {
+                resolveLeafListSchemaNode(typeBuilder,
+                        (LeafListSchemaNode) node);
+
+            } else if (node instanceof ContainerSchemaNode) {
+                resolveContainerSchemaNode(typeBuilder,
+                        (ContainerSchemaNode) node);
+            } else if (node instanceof ListSchemaNode) {
+                resolveListSchemaNode(typeBuilder, (ListSchemaNode) node);
+            }
+        }
+        return typeBuilder.toInstance();
+    }
+
+    private boolean resolveLeafSchemaNode(
+            final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode node) {
+        if ((node != null) && (typeBuilder != null)) {
+            final String nodeName = node.getQName().getLocalName();
+            String nodeDesc = node.getDescription();
+            if (nodeDesc == null) {
+                nodeDesc = "";
+            }
+
+            if (nodeName != null) {
+                final TypeDefinition<?> typeDef = node.getType();
+                final Type javaType = typeProvider
+                        .javaTypeForSchemaDefinitionType(typeDef);
+
+                constructGetter(typeBuilder, nodeName, nodeDesc, javaType);
+                if (!node.isConfiguration()) {
+                    constructSetter(typeBuilder, nodeName, nodeDesc, javaType);
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean resolveLeafListSchemaNode(
+            final GeneratedTypeBuilder typeBuilder,
+            final LeafListSchemaNode node) {
+        if ((node != null) && (typeBuilder != null)) {
+            final String nodeName = node.getQName().getLocalName();
+            String nodeDesc = node.getDescription();
+            if (nodeDesc == null) {
+                nodeDesc = "";
+            }
+
+            if (nodeName != null) {
+                final TypeDefinition<?> type = node.getType();
+                final Type listType = Types.listTypeFor(typeProvider
+                        .javaTypeForSchemaDefinitionType(type));
+
+                constructGetter(typeBuilder, nodeName, nodeDesc, listType);
+                if (!node.isConfiguration()) {
+                    constructSetter(typeBuilder, nodeName, nodeDesc, listType);
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean resolveContainerSchemaNode(
+            final GeneratedTypeBuilder typeBuilder,
+            final ContainerSchemaNode node) {
+        if ((node != null) && (typeBuilder != null)) {
+            final String nodeName = node.getQName().getLocalName();
+
+            if (nodeName != null) {
+                final GeneratedTypeBuilder rawGenType = addRawInterfaceDefinition(node);
+                constructGetter(typeBuilder, nodeName, "", rawGenType);
+
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean resolveListSchemaNode(
+            final GeneratedTypeBuilder typeBuilder, final ListSchemaNode node) {
+        if ((node != null) && (typeBuilder != null)) {
+            final String nodeName = node.getQName().getLocalName();
+
+            if (nodeName != null) {
+                final GeneratedTypeBuilder rawGenType = addRawInterfaceDefinition(node);
+                constructGetter(typeBuilder, nodeName, "",
+                        Types.listTypeFor(rawGenType));
+                if (!node.isConfiguration()) {
+                    constructSetter(typeBuilder, nodeName, "",
+                            Types.listTypeFor(rawGenType));
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private GeneratedTypeBuilder addRawInterfaceDefinition(
+            final DataSchemaNode schemaNode) {
+        if (schemaNode == null) {
+            return null;
+        }
+
+        final String packageName = resolveGeneratedTypePackageName(schemaNode
+                .getPath());
+        final String schemaNodeName = schemaNode.getQName().getLocalName();
+
+        if ((packageName != null) && (schemaNode != null)
+                && (schemaNodeName != null)) {
+            final String genTypeName = CodeGeneratorHelper
+                    .parseToClassName(schemaNodeName);
+            final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(
+                    packageName, genTypeName);
+
+            if (!genTypeBuilders.containsKey(packageName)) {
+                final Map<String, GeneratedTypeBuilder> builders = new HashMap<String, GeneratedTypeBuilder>();
+                builders.put(genTypeName, newType);
+                genTypeBuilders.put(packageName, builders);
+            } else {
+                final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders
+                        .get(packageName);
+                if (!builders.containsKey(genTypeName)) {
+                    builders.put(genTypeName, newType);
+                }
+            }
+
+            return newType;
+        }
+        return null;
+    }
+
+    private String getterMethodName(final String methodName) {
+        final StringBuilder method = new StringBuilder();
+        method.append("get");
+        method.append(CodeGeneratorHelper.parseToClassName(methodName));
+        return method.toString();
+    }
+
+    private String setterMethodName(final String methodName) {
+        final StringBuilder method = new StringBuilder();
+        method.append("set");
+        method.append(CodeGeneratorHelper.parseToClassName(methodName));
+        return method.toString();
+    }
+
+    private MethodSignatureBuilder constructGetter(
+            final GeneratedTypeBuilder interfaceBuilder,
+            final String schemaNodeName, final String comment,
+            final Type returnType) {
+        final MethodSignatureBuilder getMethod = interfaceBuilder
+                .addMethod(getterMethodName(schemaNodeName));
+
+        getMethod.addComment(comment);
+        getMethod.addReturnType(returnType);
+
+        return getMethod;
+    }
+
+    private MethodSignatureBuilder constructSetter(
+            final GeneratedTypeBuilder interfaceBuilder,
+            final String schemaNodeName, final String comment,
+            final Type parameterType) {
+        final MethodSignatureBuilder setMethod = interfaceBuilder
+                .addMethod(setterMethodName(schemaNodeName));
+
+        setMethod.addComment(comment);
+        setMethod.addParameter(parameterType,
+                CodeGeneratorHelper.parseToParamName(schemaNodeName));
+        setMethod.addReturnType(Types.voidType());
+
+        return setMethod;
+    }
+
+    private boolean isCompositeKey(final String keyDefinition) {
+        if (keyDefinition.contains(" ")) {
+            return true;
+        }
+        return false;
+    }
+
+    private String resolveBasePackageName(final URI moduleNamespace,
+            final String yangVersion) {
+        final StringBuilder packageNameBuilder = new StringBuilder();
+
+        packageNameBuilder.append("com.cisco.yang.gen.v");
+        packageNameBuilder.append(yangVersion);
+        packageNameBuilder.append(".rev");
+        packageNameBuilder.append(calendar.get(Calendar.YEAR));
+        packageNameBuilder.append((calendar.get(Calendar.MONTH) + 1));
+        packageNameBuilder.append(calendar.get(Calendar.DAY_OF_MONTH));
+        packageNameBuilder.append(".");
+
+        String namespace = moduleNamespace.toString();
+        namespace = namespace.replace(":", ".");
+        namespace = namespace.replace("-", ".");
+
+        packageNameBuilder.append(namespace);
+
+        return packageNameBuilder.toString();
+    }
+
+    private GeneratedType listToGenType(ListSchemaNode list) {
+        if (list == null) {
+            return null;
+        }
+        final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(list);
+
+        final Set<DataSchemaNode> schemaNodes = list.getChildNodes();
+        for (final DataSchemaNode node : schemaNodes) {
+            if (node instanceof LeafSchemaNode) {
+                resolveLeafSchemaNode(typeBuilder, (LeafSchemaNode) node);
+            } else if (node instanceof LeafListSchemaNode) {
+                resolveLeafListSchemaNode(typeBuilder,
+                        (LeafListSchemaNode) node);
+            } else if (node instanceof ContainerSchemaNode) {
+                resolveContainerSchemaNode(typeBuilder,
+                        (ContainerSchemaNode) node);
+            } else if (node instanceof ListSchemaNode) {
+                resolveListSchemaNode(typeBuilder, (ListSchemaNode) node);
+            }
+        }
+        return typeBuilder.toInstance();
+    }
+
+    private GeneratedTypeBuilder resolveListTypeBuilder(
+            final ListSchemaNode list) {
+        final String packageName = resolveGeneratedTypePackageName(list
+                .getPath());
+        final String schemaNodeName = list.getQName().getLocalName();
+        final String genTypeName = CodeGeneratorHelper
+                .parseToClassName(schemaNodeName);
+
+        GeneratedTypeBuilder typeBuilder = null;
+        if (genTypeBuilders.containsKey(packageName)) {
+            final Map<String, GeneratedTypeBuilder> builders = new HashMap<String, GeneratedTypeBuilder>();
+            typeBuilder = builders.get(genTypeName);
+
+            if (null == typeBuilder) {
+                typeBuilder = addRawInterfaceDefinition(list);
+            }
+        }
+        return typeBuilder;
+    }
+
+    private void traverseModule(final Module module) {
+        final Set<DataSchemaNode> schemaNodes = module.getChildNodes();
+
+        for (DataSchemaNode node : schemaNodes) {
+            if (node instanceof ContainerSchemaNode) {
+                schemaContainers.add((ContainerSchemaNode) node);
+                traverse((ContainerSchemaNode) node);
+            }
+        }
+    }
+
+    private void traverse(final DataNodeContainer dataNode) {
+        if (!containChildDataNodeContainer(dataNode)) {
+            return;
+        }
+
+        final Set<DataSchemaNode> childs = dataNode.getChildNodes();
+        if (childs != null) {
+            for (DataSchemaNode childNode : childs) {
+                if (childNode instanceof ContainerSchemaNode) {
+                    final ContainerSchemaNode container = (ContainerSchemaNode) childNode;
+                    schemaContainers.add(container);
+                    traverse(container);
+                }
+
+                if (childNode instanceof ListSchemaNode) {
+                    final ListSchemaNode list = (ListSchemaNode) childNode;
+                    schemaLists.add(list);
+                    traverse(list);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns <code>true</code> if and only if the child node contain at least
+     * one child container schema node or child list schema node, otherwise will
+     * always returns <code>false</code>
+     * 
+     * @param container
+     * @return <code>true</code> if and only if the child node contain at least
+     *         one child container schema node or child list schema node,
+     *         otherwise will always returns <code>false</code>
+     */
+    private boolean containChildDataNodeContainer(
+            final DataNodeContainer container) {
+        if (container != null) {
+            final Set<DataSchemaNode> childs = container.getChildNodes();
+            if ((childs != null) && (childs.size() > 0)) {
+                for (final DataSchemaNode childNode : childs) {
+                    if (childNode instanceof DataNodeContainer) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/ConstantBuilderImpl.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/ConstantBuilderImpl.java
new file mode 100644 (file)
index 0000000..cb2fc87
--- /dev/null
@@ -0,0 +1,189 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.generator.impl;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.Constant;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+import org.opendaylight.controller.sal.binding.model.api.type.builder.ConstantBuilder;\r
+\r
+final class ConstantBuilderImpl implements ConstantBuilder {\r
+\r
+    private final Type type;\r
+    private final String name;\r
+    private Object value;\r
+\r
+    public ConstantBuilderImpl(Type type, String name, Object value) {\r
+        super();\r
+        this.type = type;\r
+        this.name = name;\r
+        this.value = value;\r
+    }\r
+\r
+    public ConstantBuilderImpl(Type type, String name) {\r
+        super();\r
+        this.type = type;\r
+        this.name = name;\r
+    }\r
+\r
+    @Override\r
+    public void assignValue(Object value) {\r
+        this.value = value;\r
+    }\r
+\r
+    @Override\r
+    public Constant toInstance(final Type definingType) {\r
+        return new ConstantImpl(definingType, type, name, value);\r
+    }\r
+\r
+    private static final class ConstantImpl implements Constant {\r
+\r
+        final Type definingType;\r
+        private final Type type;\r
+        private final String name;\r
+        private final Object value;\r
+\r
+        public ConstantImpl(final Type definingType, final Type type,\r
+                final String name, final Object value) {\r
+            super();\r
+            this.definingType = definingType;\r
+            this.type = type;\r
+            this.name = name;\r
+            this.value = value;\r
+        }\r
+\r
+        @Override\r
+        public Type getDefiningType() {\r
+            return definingType;\r
+        }\r
+\r
+        @Override\r
+        public Type getType() {\r
+            return type;\r
+        }\r
+\r
+        @Override\r
+        public String getName() {\r
+            return name;\r
+        }\r
+\r
+        @Override\r
+        public Object getValue() {\r
+            return value;\r
+        }\r
+\r
+        @Override\r
+        public String toFormattedString() {\r
+            StringBuilder builder = new StringBuilder();\r
+            builder.append(type);\r
+            builder.append(" ");\r
+            builder.append(name);\r
+            builder.append(" ");\r
+            builder.append(value);\r
+            return builder.toString();\r
+        }\r
+\r
+        /*\r
+         * (non-Javadoc)\r
+         * \r
+         * @see java.lang.Object#hashCode()\r
+         */\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+            result = prime * result + ((type == null) ? 0 : type.hashCode());\r
+            result = prime * result + ((value == null) ? 0 : value.hashCode());\r
+            if (definingType != null) {\r
+                result = prime\r
+                        * result\r
+                        + ((definingType.getPackageName() == null) ? 0\r
+                                : definingType.getPackageName().hashCode());\r
+                result = prime\r
+                        * result\r
+                        + ((definingType.getName() == null) ? 0 : definingType\r
+                                .getName().hashCode());\r
+            }\r
+            return result;\r
+        }\r
+\r
+        /*\r
+         * (non-Javadoc)\r
+         * \r
+         * @see java.lang.Object#equals(java.lang.Object)\r
+         */\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj) {\r
+                return true;\r
+            }\r
+            if (obj == null) {\r
+                return false;\r
+            }\r
+            if (getClass() != obj.getClass()) {\r
+                return false;\r
+            }\r
+            ConstantImpl other = (ConstantImpl) obj;\r
+            if (name == null) {\r
+                if (other.name != null) {\r
+                    return false;\r
+                }\r
+            } else if (!name.equals(other.name)) {\r
+                return false;\r
+            }\r
+            if (type == null) {\r
+                if (other.type != null) {\r
+                    return false;\r
+                }\r
+            } else if (!type.equals(other.type)) {\r
+                return false;\r
+            }\r
+            if (value == null) {\r
+                if (other.value != null) {\r
+                    return false;\r
+                }\r
+            } else if (!value.equals(other.value)) {\r
+                return false;\r
+            }\r
+            if (definingType == null) {\r
+                if (other.definingType != null) {\r
+                    return false;\r
+                }\r
+            } else if ((definingType != null) && (other.definingType != null)) {\r
+                if (!definingType.getPackageName().equals(\r
+                        other.definingType.getPackageName())\r
+                        && !definingType.getName().equals(\r
+                                other.definingType.getName())) {\r
+                    return false;\r
+                }\r
+            }\r
+            return true;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            StringBuilder builder = new StringBuilder();\r
+            builder.append("ConstantImpl [type=");\r
+            builder.append(type);\r
+            builder.append(", name=");\r
+            builder.append(name);\r
+            builder.append(", value=");\r
+            builder.append(value);\r
+            if (definingType != null) {\r
+                builder.append(", definingType=");\r
+                builder.append(definingType.getPackageName());\r
+                builder.append(".");\r
+                builder.append(definingType.getName());\r
+            } else {\r
+                builder.append(", definingType= null");\r
+            }\r
+            builder.append("]");\r
+            return builder.toString();\r
+        }\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/EnumerationBuilderImpl.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/EnumerationBuilderImpl.java
new file mode 100644 (file)
index 0000000..6eadb76
--- /dev/null
@@ -0,0 +1,365 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.generator.impl;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.Enumeration;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+import org.opendaylight.controller.sal.binding.model.api.type.builder.EnumBuilder;\r
+\r
+final class EnumerationBuilderImpl implements EnumBuilder {\r
+    private final String packageName;\r
+    private final String name;\r
+    private final List<Enumeration.Pair> values;\r
+\r
+    public EnumerationBuilderImpl(final String packageName, final String name) {\r
+        super();\r
+        this.packageName = packageName;\r
+        this.name = name;\r
+        values = new ArrayList<Enumeration.Pair>();\r
+    }\r
+\r
+    @Override\r
+    public void addValue(final String name, final Integer value) {\r
+        values.add(new EnumPairImpl(name, value));\r
+    }\r
+\r
+    @Override\r
+    public Enumeration toInstance(final Type definingType) {\r
+        return new EnumerationImpl(definingType, packageName, name, values);\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see java.lang.Object#hashCode()\r
+     */\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+        result = prime * result\r
+                + ((packageName == null) ? 0 : packageName.hashCode());\r
+        return result;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see java.lang.Object#equals(java.lang.Object)\r
+     */\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        EnumerationBuilderImpl other = (EnumerationBuilderImpl) obj;\r
+        if (name == null) {\r
+            if (other.name != null) {\r
+                return false;\r
+            }\r
+        } else if (!name.equals(other.name)) {\r
+            return false;\r
+        }\r
+        if (packageName == null) {\r
+            if (other.packageName != null) {\r
+                return false;\r
+            }\r
+        } else if (!packageName.equals(other.packageName)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see java.lang.Object#toString()\r
+     */\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("EnumerationBuilderImpl [packageName=");\r
+        builder.append(packageName);\r
+        builder.append(", name=");\r
+        builder.append(name);\r
+        builder.append(", values=");\r
+        builder.append(values);\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+\r
+    private static final class EnumPairImpl implements Enumeration.Pair {\r
+\r
+        private final String name;\r
+        private final Integer value;\r
+\r
+        public EnumPairImpl(String name, Integer value) {\r
+            super();\r
+            this.name = name;\r
+            this.value = value;\r
+        }\r
+\r
+        @Override\r
+        public String getName() {\r
+            return name;\r
+        }\r
+\r
+        @Override\r
+        public Integer getValue() {\r
+            return value;\r
+        }\r
+\r
+        /*\r
+         * (non-Javadoc)\r
+         * \r
+         * @see java.lang.Object#hashCode()\r
+         */\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+            result = prime * result + ((value == null) ? 0 : value.hashCode());\r
+            return result;\r
+        }\r
+\r
+        /*\r
+         * (non-Javadoc)\r
+         * \r
+         * @see java.lang.Object#equals(java.lang.Object)\r
+         */\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj) {\r
+                return true;\r
+            }\r
+            if (obj == null) {\r
+                return false;\r
+            }\r
+            if (getClass() != obj.getClass()) {\r
+                return false;\r
+            }\r
+            EnumPairImpl other = (EnumPairImpl) obj;\r
+            if (name == null) {\r
+                if (other.name != null) {\r
+                    return false;\r
+                }\r
+            } else if (!name.equals(other.name)) {\r
+                return false;\r
+            }\r
+            if (value == null) {\r
+                if (other.value != null) {\r
+                    return false;\r
+                }\r
+            } else if (!value.equals(other.value)) {\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
+\r
+        /*\r
+         * (non-Javadoc)\r
+         * \r
+         * @see java.lang.Object#toString()\r
+         */\r
+        @Override\r
+        public String toString() {\r
+            StringBuilder builder = new StringBuilder();\r
+            builder.append("EnumPairImpl [name=");\r
+            builder.append(name);\r
+            builder.append(", value=");\r
+            builder.append(value);\r
+            builder.append("]");\r
+            return builder.toString();\r
+        }\r
+    }\r
+\r
+    private static final class EnumerationImpl implements Enumeration {\r
+\r
+        private final Type definingType;\r
+        private final String packageName;\r
+        private final String name;\r
+        private final List<Pair> values;\r
+\r
+        public EnumerationImpl(final Type definingType,\r
+                final String packageName, final String name,\r
+                final List<Pair> values) {\r
+            super();\r
+            this.definingType = definingType;\r
+            this.packageName = packageName;\r
+            this.name = name;\r
+            this.values = Collections.unmodifiableList(values);\r
+        }\r
+\r
+        @Override\r
+        public Type getDefiningType() {\r
+            return definingType;\r
+        }\r
+\r
+        @Override\r
+        public String getPackageName() {\r
+            return packageName;\r
+        }\r
+\r
+        @Override\r
+        public String getName() {\r
+            return name;\r
+        }\r
+\r
+        @Override\r
+        public List<Pair> getValues() {\r
+            return values;\r
+        }\r
+\r
+        @Override\r
+        public String toFormattedString() {\r
+            StringBuilder builder = new StringBuilder();\r
+            builder.append("public enum");\r
+            builder.append(" ");\r
+            builder.append(name);\r
+            builder.append(" {");\r
+            builder.append("\n");\r
+\r
+            int i = 0;\r
+            for (final Enumeration.Pair valPair : values) {\r
+                builder.append("\t");\r
+                builder.append(" ");\r
+                builder.append(valPair.getName());\r
+                builder.append(" (");\r
+                builder.append(valPair.getValue());\r
+\r
+                if (i == (values.size() - 1)) {\r
+                    builder.append(" );");\r
+                } else {\r
+                    builder.append(" ),");\r
+                }\r
+                ++i;\r
+            }\r
+            return builder.toString();\r
+        }\r
+\r
+        /*\r
+         * (non-Javadoc)\r
+         * \r
+         * @see java.lang.Object#hashCode()\r
+         */\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+            result = prime * result\r
+                    + ((packageName == null) ? 0 : packageName.hashCode());\r
+            result = prime * result\r
+                    + ((values == null) ? 0 : values.hashCode());\r
+\r
+            if (definingType != null) {\r
+                result = prime\r
+                        * result\r
+                        + ((definingType.getPackageName() == null) ? 0\r
+                                : definingType.getPackageName().hashCode());\r
+                result = prime\r
+                        * result\r
+                        + ((definingType.getName() == null) ? 0 : definingType\r
+                                .getName().hashCode());\r
+            }\r
+\r
+            return result;\r
+        }\r
+\r
+        /*\r
+         * (non-Javadoc)\r
+         * \r
+         * @see java.lang.Object#equals(java.lang.Object)\r
+         */\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj) {\r
+                return true;\r
+            }\r
+            if (obj == null) {\r
+                return false;\r
+            }\r
+            if (getClass() != obj.getClass()) {\r
+                return false;\r
+            }\r
+            EnumerationImpl other = (EnumerationImpl) obj;\r
+            if (name == null) {\r
+                if (other.name != null) {\r
+                    return false;\r
+                }\r
+            } else if (!name.equals(other.name)) {\r
+                return false;\r
+            }\r
+            if (packageName == null) {\r
+                if (other.packageName != null) {\r
+                    return false;\r
+                }\r
+            } else if (!packageName.equals(other.packageName)) {\r
+                return false;\r
+            }\r
+            if (values == null) {\r
+                if (other.values != null) {\r
+                    return false;\r
+                }\r
+            } else if (!values.equals(other.values)) {\r
+                return false;\r
+            }\r
+            if (definingType == null) {\r
+                if (other.definingType != null) {\r
+                    return false;\r
+                }\r
+            } else if ((definingType != null) && (other.definingType != null)) {\r
+                if (!definingType.getPackageName().equals(\r
+                        other.definingType.getPackageName())\r
+                        && !definingType.getName().equals(\r
+                                other.definingType.getName())) {\r
+                    return false;\r
+                }\r
+            }\r
+            return true;\r
+        }\r
+\r
+        /*\r
+         * (non-Javadoc)\r
+         * \r
+         * @see java.lang.Object#toString()\r
+         */\r
+        @Override\r
+        public String toString() {\r
+            StringBuilder builder = new StringBuilder();\r
+            builder.append("EnumerationImpl [packageName=");\r
+            builder.append(packageName);\r
+            if (definingType != null) {\r
+                builder.append(", definingType=");\r
+                builder.append(definingType.getPackageName());\r
+                builder.append(".");\r
+                builder.append(definingType.getName());\r
+            } else {\r
+                builder.append(", definingType= null");\r
+            }\r
+            builder.append(", name=");\r
+            builder.append(name);\r
+            builder.append(", values=");\r
+            builder.append(values);\r
+            builder.append("]");\r
+            return builder.toString();\r
+        }\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/GeneratedTOBuilderImpl.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/GeneratedTOBuilderImpl.java
new file mode 100644 (file)
index 0000000..90b2ebf
--- /dev/null
@@ -0,0 +1,560 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.generator.impl;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.AccessModifier;\r
+import org.opendaylight.controller.sal.binding.model.api.Constant;\r
+import org.opendaylight.controller.sal.binding.model.api.Enumeration;\r
+import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty;\r
+import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;\r
+import org.opendaylight.controller.sal.binding.model.api.MethodSignature;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+import org.opendaylight.controller.sal.binding.model.api.type.builder.ConstantBuilder;\r
+import org.opendaylight.controller.sal.binding.model.api.type.builder.EnumBuilder;\r
+import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;\r
+import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTOBuilder;\r
+\r
+final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {\r
+\r
+    private final String packageName;\r
+    private final String name;\r
+\r
+    private final List<EnumBuilder> enumerations = new ArrayList<EnumBuilder>();\r
+    private final List<GeneratedPropertyBuilder> properties = new ArrayList<GeneratedPropertyBuilder>();\r
+    private final List<GeneratedPropertyBuilder> equalsProperties = new ArrayList<GeneratedPropertyBuilder>();\r
+    private final List<GeneratedPropertyBuilder> hashProperties = new ArrayList<GeneratedPropertyBuilder>();\r
+    private final List<GeneratedPropertyBuilder> toStringProperties = new ArrayList<GeneratedPropertyBuilder>();\r
+\r
+    public GeneratedTOBuilderImpl(String packageName, String name) {\r
+        super();\r
+        this.packageName = packageName;\r
+        this.name = name;\r
+    }\r
+\r
+    @Override\r
+    public String getPackageName() {\r
+        return packageName;\r
+    }\r
+\r
+    @Override\r
+    public String getName() {\r
+        return name;\r
+    }\r
+\r
+    @Override\r
+    public EnumBuilder addEnumeration(String name) {\r
+        final EnumBuilder builder = new EnumerationBuilderImpl(packageName,\r
+                name);\r
+        enumerations.add(builder);\r
+        return builder;\r
+    }\r
+\r
+    @Override\r
+    public GeneratedPropertyBuilder addProperty(String name) {\r
+        final GeneratedPropertyBuilder builder = new GeneratedPropertyBuilderImpl(\r
+                name);\r
+        properties.add(builder);\r
+        return builder;\r
+    }\r
+\r
+    @Override\r
+    public boolean addEqualsIdentity(GeneratedPropertyBuilder property) {\r
+        return equalsProperties.add(property);\r
+    }\r
+\r
+    @Override\r
+    public boolean addHashIdentity(GeneratedPropertyBuilder property) {\r
+        return hashProperties.add(property);\r
+    }\r
+\r
+    @Override\r
+    public boolean addToStringProperty(GeneratedPropertyBuilder property) {\r
+        return toStringProperties.add(property);\r
+    }\r
+\r
+    @Override\r
+    public GeneratedTransferObject toInstance() {\r
+        return new GeneratedTransferObjectImpl(packageName, name, enumerations,\r
+                properties, equalsProperties, hashProperties,\r
+                toStringProperties);\r
+    }\r
+\r
+    private static final class GeneratedPropertyBuilderImpl implements\r
+            GeneratedPropertyBuilder {\r
+\r
+        private final String name;\r
+        private Type returnType;\r
+        private final List<MethodSignature.Parameter> parameters;\r
+        private String comment = "";\r
+        private AccessModifier accessModifier;\r
+        private boolean isFinal;\r
+        private boolean isReadOnly;\r
+\r
+        public GeneratedPropertyBuilderImpl(final String name) {\r
+            super();\r
+            this.name = name;\r
+            parameters = new ArrayList<MethodSignature.Parameter>();\r
+            isFinal = true;\r
+            this.isReadOnly = true;\r
+            accessModifier = AccessModifier.PUBLIC;\r
+        }\r
+\r
+        public String getName() {\r
+            return name;\r
+        }\r
+\r
+        @Override\r
+        public boolean addReturnType(Type returnType) {\r
+            if (returnType != null) {\r
+                this.returnType = returnType;\r
+                this.parameters.add(new MethodParameterImpl(name, returnType));\r
+                return true;\r
+            }\r
+            return false;\r
+        }\r
+\r
+        @Override\r
+        public void accessorModifier(final AccessModifier modifier) {\r
+            accessModifier = modifier;\r
+        }\r
+\r
+        @Override\r
+        public void addComment(String comment) {\r
+            if (comment != null) {\r
+                this.comment = comment;\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void setFinal(boolean isFinal) {\r
+            this.isFinal = isFinal;\r
+        }\r
+\r
+        @Override\r
+        public void setReadOnly(boolean isReadOnly) {\r
+            this.isReadOnly = isReadOnly;\r
+        }\r
+\r
+        @Override\r
+        public GeneratedProperty toInstance(final Type definingType) {\r
+            return new GeneratedPropertyImpl(name, comment, definingType,\r
+                    returnType, isFinal, isReadOnly, parameters, accessModifier);\r
+        }\r
+    }\r
+\r
+    private static final class GeneratedPropertyImpl implements\r
+            GeneratedProperty {\r
+\r
+        private final String name;\r
+        private final String comment;\r
+        private final Type parent;\r
+        private final Type returnType;\r
+        private final boolean isFinal;\r
+        private final boolean isReadOnly;\r
+        private final List<MethodSignature.Parameter> parameters;\r
+        private final AccessModifier modifier;\r
+\r
+        public GeneratedPropertyImpl(final String name, final String comment,\r
+                final Type parent, final Type returnType,\r
+                final boolean isFinal, final boolean isReadOnly,\r
+                final List<Parameter> parameters, final AccessModifier modifier) {\r
+            super();\r
+            this.name = name;\r
+            this.comment = comment;\r
+            this.parent = parent;\r
+            this.returnType = returnType;\r
+            this.isFinal = isFinal;\r
+            this.isReadOnly = isReadOnly;\r
+            this.parameters = Collections.unmodifiableList(parameters);\r
+            this.modifier = modifier;\r
+        }\r
+\r
+        @Override\r
+        public String getName() {\r
+            return name;\r
+        }\r
+\r
+        @Override\r
+        public String getComment() {\r
+            return comment;\r
+        }\r
+\r
+        @Override\r
+        public Type getDefiningType() {\r
+            return parent;\r
+        }\r
+\r
+        @Override\r
+        public Type getReturnType() {\r
+            return returnType;\r
+        }\r
+\r
+        @Override\r
+        public List<Parameter> getParameters() {\r
+            return parameters;\r
+        }\r
+\r
+        @Override\r
+        public AccessModifier getAccessModifier() {\r
+            return modifier;\r
+        }\r
+\r
+        @Override\r
+        public boolean isReadOnly() {\r
+            return isReadOnly;\r
+        }\r
+\r
+        @Override\r
+        public boolean isFinal() {\r
+            return isFinal;\r
+        }\r
+\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result\r
+                    + ((comment == null) ? 0 : comment.hashCode());\r
+            result = prime * result + (isFinal ? 1231 : 1237);\r
+            result = prime * result + (isReadOnly ? 1231 : 1237);\r
+            result = prime * result\r
+                    + ((modifier == null) ? 0 : modifier.hashCode());\r
+            result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+            result = prime * result\r
+                    + ((parameters == null) ? 0 : parameters.hashCode());\r
+\r
+            if (parent != null) {\r
+                result = prime\r
+                        * result\r
+                        + ((parent.getPackageName() == null) ? 0 : parent\r
+                                .getPackageName().hashCode());\r
+                result = prime\r
+                        * result\r
+                        + ((parent.getName() == null) ? 0 : parent.getName()\r
+                                .hashCode());\r
+            }\r
+\r
+            result = prime * result\r
+                    + ((returnType == null) ? 0 : returnType.hashCode());\r
+            return result;\r
+        }\r
+\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj) {\r
+                return true;\r
+            }\r
+            if (obj == null) {\r
+                return false;\r
+            }\r
+            if (getClass() != obj.getClass()) {\r
+                return false;\r
+            }\r
+            GeneratedPropertyImpl other = (GeneratedPropertyImpl) obj;\r
+            if (comment == null) {\r
+                if (other.comment != null) {\r
+                    return false;\r
+                }\r
+            } else if (!comment.equals(other.comment)) {\r
+                return false;\r
+            }\r
+            if (isFinal != other.isFinal) {\r
+                return false;\r
+            }\r
+            if (isReadOnly != other.isReadOnly) {\r
+                return false;\r
+            }\r
+            if (modifier != other.modifier) {\r
+                return false;\r
+            }\r
+            if (name == null) {\r
+                if (other.name != null) {\r
+                    return false;\r
+                }\r
+            } else if (!name.equals(other.name)) {\r
+                return false;\r
+            }\r
+            if (parameters == null) {\r
+                if (other.parameters != null) {\r
+                    return false;\r
+                }\r
+            } else if (!parameters.equals(other.parameters)) {\r
+                return false;\r
+            }\r
+            if (parent == null) {\r
+                if (other.parent != null) {\r
+                    return false;\r
+                }\r
+            } else if ((parent != null) && (other.parent != null)) {\r
+                if (!parent.getPackageName().equals(\r
+                        other.parent.getPackageName())\r
+                        && !parent.getName().equals(other.parent.getName())) {\r
+                    return false;\r
+                }\r
+            }\r
+            if (returnType == null) {\r
+                if (other.returnType != null) {\r
+                    return false;\r
+                }\r
+            } else if (!returnType.equals(other.returnType)) {\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            StringBuilder builder = new StringBuilder();\r
+            builder.append("GeneratedPropertyImpl [name=");\r
+            builder.append(name);\r
+            builder.append(", comment=");\r
+            builder.append(comment);\r
+            if (parent != null) {\r
+                builder.append(", parent=");\r
+                builder.append(parent.getPackageName());\r
+                builder.append(".");\r
+                builder.append(parent.getName());\r
+            } else {\r
+                builder.append(", parent= null");\r
+            }\r
+            builder.append(", returnType=");\r
+            builder.append(returnType);\r
+            builder.append(", isFinal=");\r
+            builder.append(isFinal);\r
+            builder.append(", isReadOnly=");\r
+            builder.append(isReadOnly);\r
+            builder.append(", parameters=");\r
+            builder.append(parameters);\r
+            builder.append(", modifier=");\r
+            builder.append(modifier);\r
+            builder.append("]");\r
+            return builder.toString();\r
+        }\r
+    }\r
+\r
+    private static final class GeneratedTransferObjectImpl implements\r
+            GeneratedTransferObject {\r
+\r
+        private final String packageName;\r
+        private final String name;\r
+        // private final List<Constant> constants;\r
+        private final List<Enumeration> enumerations;\r
+        private final List<GeneratedProperty> properties;\r
+        private final List<GeneratedProperty> equalsProperties;\r
+        private final List<GeneratedProperty> hashCodeProperties;\r
+        private final List<GeneratedProperty> stringProperties;\r
+\r
+        private List<Enumeration> toUnmodifiableEnumerations(\r
+                final List<EnumBuilder> enumBuilders) {\r
+            final List<Enumeration> enumerations = new ArrayList<Enumeration>();\r
+            for (final EnumBuilder builder : enumBuilders) {\r
+                enumerations.add(builder.toInstance(this));\r
+            }\r
+            return Collections.unmodifiableList(enumerations);\r
+        }\r
+\r
+        private List<Constant> toUnmodifiableConstant(\r
+                final List<ConstantBuilder> constBuilders) {\r
+            final List<Constant> constants = new ArrayList<Constant>();\r
+            for (final ConstantBuilder builder : constBuilders) {\r
+                constants.add(builder.toInstance(this));\r
+            }\r
+            return Collections.unmodifiableList(constants);\r
+        }\r
+\r
+        private List<GeneratedProperty> toUnmodifiableProperties(\r
+                final List<GeneratedPropertyBuilder> propBuilders) {\r
+            final List<GeneratedProperty> constants = new ArrayList<GeneratedProperty>();\r
+            for (final GeneratedPropertyBuilder builder : propBuilders) {\r
+                constants.add(builder.toInstance(this));\r
+            }\r
+            return Collections.unmodifiableList(constants);\r
+        }\r
+\r
+        public GeneratedTransferObjectImpl(String packageName, String name,\r
+                List<EnumBuilder> enumBuilders,\r
+                List<GeneratedPropertyBuilder> propBuilers,\r
+                List<GeneratedPropertyBuilder> equalsBuilers,\r
+                List<GeneratedPropertyBuilder> hashCodeBuilers,\r
+                List<GeneratedPropertyBuilder> stringBuilers) {\r
+            super();\r
+            this.packageName = packageName;\r
+            this.name = name;\r
+            this.enumerations = toUnmodifiableEnumerations(enumBuilders);\r
+            this.properties = toUnmodifiableProperties(propBuilers);\r
+            this.equalsProperties = toUnmodifiableProperties(equalsBuilers);\r
+            this.hashCodeProperties = toUnmodifiableProperties(hashCodeBuilers);\r
+            this.stringProperties = toUnmodifiableProperties(stringBuilers);\r
+        }\r
+\r
+        @Override\r
+        public String getPackageName() {\r
+            return packageName;\r
+        }\r
+\r
+        @Override\r
+        public String getName() {\r
+            return name;\r
+        }\r
+\r
+        @Override\r
+        public List<Enumeration> getEnumDefintions() {\r
+            return enumerations;\r
+        }\r
+\r
+        @Override\r
+        public List<GeneratedProperty> getProperties() {\r
+            return properties;\r
+        }\r
+\r
+        @Override\r
+        public List<GeneratedProperty> getEqualsIdentifiers() {\r
+            return equalsProperties;\r
+        }\r
+\r
+        @Override\r
+        public List<GeneratedProperty> getHashCodeIdentifiers() {\r
+            return hashCodeProperties;\r
+        }\r
+\r
+        @Override\r
+        public List<GeneratedProperty> getToStringIdentifiers() {\r
+            return stringProperties;\r
+        }\r
+\r
+        /*\r
+         * (non-Javadoc)\r
+         * \r
+         * @see java.lang.Object#hashCode()\r
+         */\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result\r
+                    + ((enumerations == null) ? 0 : enumerations.hashCode());\r
+            result = prime\r
+                    * result\r
+                    + ((equalsProperties == null) ? 0 : equalsProperties\r
+                            .hashCode());\r
+            result = prime\r
+                    * result\r
+                    + ((hashCodeProperties == null) ? 0 : hashCodeProperties\r
+                            .hashCode());\r
+            result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+            result = prime * result\r
+                    + ((packageName == null) ? 0 : packageName.hashCode());\r
+            result = prime * result\r
+                    + ((properties == null) ? 0 : properties.hashCode());\r
+            result = prime\r
+                    * result\r
+                    + ((stringProperties == null) ? 0 : stringProperties\r
+                            .hashCode());\r
+            return result;\r
+        }\r
+\r
+        /*\r
+         * (non-Javadoc)\r
+         * \r
+         * @see java.lang.Object#equals(java.lang.Object)\r
+         */\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj) {\r
+                return true;\r
+            }\r
+            if (obj == null) {\r
+                return false;\r
+            }\r
+            if (getClass() != obj.getClass()) {\r
+                return false;\r
+            }\r
+            GeneratedTransferObjectImpl other = (GeneratedTransferObjectImpl) obj;\r
+            if (enumerations == null) {\r
+                if (other.enumerations != null) {\r
+                    return false;\r
+                }\r
+            } else if (!enumerations.equals(other.enumerations)) {\r
+                return false;\r
+            }\r
+            if (equalsProperties == null) {\r
+                if (other.equalsProperties != null) {\r
+                    return false;\r
+                }\r
+            } else if (!equalsProperties.equals(other.equalsProperties)) {\r
+                return false;\r
+            }\r
+            if (hashCodeProperties == null) {\r
+                if (other.hashCodeProperties != null) {\r
+                    return false;\r
+                }\r
+            } else if (!hashCodeProperties.equals(other.hashCodeProperties)) {\r
+                return false;\r
+            }\r
+            if (name == null) {\r
+                if (other.name != null) {\r
+                    return false;\r
+                }\r
+            } else if (!name.equals(other.name)) {\r
+                return false;\r
+            }\r
+            if (packageName == null) {\r
+                if (other.packageName != null) {\r
+                    return false;\r
+                }\r
+            } else if (!packageName.equals(other.packageName)) {\r
+                return false;\r
+            }\r
+            if (properties == null) {\r
+                if (other.properties != null) {\r
+                    return false;\r
+                }\r
+            } else if (!properties.equals(other.properties)) {\r
+                return false;\r
+            }\r
+            if (stringProperties == null) {\r
+                if (other.stringProperties != null) {\r
+                    return false;\r
+                }\r
+            } else if (!stringProperties.equals(other.stringProperties)) {\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
+\r
+        /*\r
+         * (non-Javadoc)\r
+         * \r
+         * @see java.lang.Object#toString()\r
+         */\r
+        @Override\r
+        public String toString() {\r
+            StringBuilder builder = new StringBuilder();\r
+            builder.append("GeneratedTransferObjectImpl [packageName=");\r
+            builder.append(packageName);\r
+            builder.append(", name=");\r
+            builder.append(name);\r
+            builder.append(", enumerations=");\r
+            builder.append(enumerations);\r
+            builder.append(", properties=");\r
+            builder.append(properties);\r
+            builder.append(", equalsProperties=");\r
+            builder.append(equalsProperties);\r
+            builder.append(", hashCodeProperties=");\r
+            builder.append(hashCodeProperties);\r
+            builder.append(", stringProperties=");\r
+            builder.append(stringProperties);\r
+            builder.append("]");\r
+            return builder.toString();\r
+        }\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/GeneratedTypeBuilderImpl.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/GeneratedTypeBuilderImpl.java
new file mode 100644 (file)
index 0000000..c861b54
--- /dev/null
@@ -0,0 +1,503 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.generator.impl;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.AccessModifier;\r
+import org.opendaylight.controller.sal.binding.model.api.Constant;\r
+import org.opendaylight.controller.sal.binding.model.api.Enumeration;\r
+import org.opendaylight.controller.sal.binding.model.api.GeneratedType;\r
+import org.opendaylight.controller.sal.binding.model.api.MethodSignature;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+import org.opendaylight.controller.sal.binding.model.api.type.builder.ConstantBuilder;\r
+import org.opendaylight.controller.sal.binding.model.api.type.builder.EnumBuilder;\r
+import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTypeBuilder;\r
+import org.opendaylight.controller.sal.binding.model.api.type.builder.MethodSignatureBuilder;\r
+\r
+public final class GeneratedTypeBuilderImpl implements GeneratedTypeBuilder {\r
+\r
+    private final String packageName;\r
+    private String comment;\r
+    private final String name;\r
+    private final List<EnumBuilder> enumDefinitions = new ArrayList<EnumBuilder>();\r
+    private final List<ConstantBuilder> constantDefintions = new ArrayList<ConstantBuilder>();\r
+    private final List<MethodSignatureBuilder> methodDefinitions = new ArrayList<MethodSignatureBuilder>();\r
+\r
+    public GeneratedTypeBuilderImpl(final String packageName, final String name) {\r
+        this.packageName = packageName;\r
+        this.name = name;\r
+    }\r
+\r
+    @Override\r
+    public Type getParentType() {\r
+        return this;\r
+    }\r
+\r
+    @Override\r
+    public String getPackageName() {\r
+        return packageName;\r
+    }\r
+\r
+    @Override\r
+    public String getName() {\r
+        return name;\r
+    }\r
+\r
+    @Override\r
+    public void addComment(String comment) {\r
+        this.comment = comment;\r
+    }\r
+\r
+    @Override\r
+    public ConstantBuilder addConstant(Type type, String name, Object value) {\r
+        final ConstantBuilder builder = new ConstantBuilderImpl(type, name,\r
+                value);\r
+        constantDefintions.add(builder);\r
+\r
+        return builder;\r
+    }\r
+\r
+    @Override\r
+    public EnumBuilder addEnumeration(final String name) {\r
+        final EnumBuilder builder = new EnumerationBuilderImpl(packageName,\r
+                name);\r
+        enumDefinitions.add(builder);\r
+        return builder;\r
+    }\r
+\r
+    @Override\r
+    public MethodSignatureBuilder addMethod(final String name) {\r
+        final MethodSignatureBuilder builder = new MethodSignatureBuilderImpl(\r
+                this, name);\r
+        methodDefinitions.add(builder);\r
+        return builder;\r
+    }\r
+\r
+    @Override\r
+    public GeneratedType toInstance() {\r
+        return new GeneratedTypeImpl(this, packageName, name, enumDefinitions,\r
+                constantDefintions, methodDefinitions);\r
+    }\r
+\r
+    private static final class MethodSignatureBuilderImpl implements\r
+            MethodSignatureBuilder {\r
+\r
+        private final String name;\r
+        private Type returnType;\r
+        private final List<MethodSignature.Parameter> parameters;\r
+        private String comment = "";\r
+        private final Type parent;\r
+\r
+        public MethodSignatureBuilderImpl(final Type parent, final String name) {\r
+            super();\r
+            this.name = name;\r
+            this.parent = parent;\r
+            parameters = new ArrayList<MethodSignature.Parameter>();\r
+        }\r
+\r
+        @Override\r
+        public void addReturnType(Type returnType) {\r
+            if (returnType != null) {\r
+                this.returnType = returnType;\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void addParameter(Type type, String name) {\r
+            parameters.add(new MethodParameterImpl(name, type));\r
+        }\r
+\r
+        @Override\r
+        public void addComment(String comment) {\r
+            this.comment = comment;\r
+        }\r
+\r
+        @Override\r
+        public MethodSignature toInstance(Type definingType) {\r
+            return new MethodSignatureImpl(definingType, name, comment,\r
+                    returnType, parameters);\r
+        }\r
+\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+            return result;\r
+        }\r
+\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj) {\r
+                return true;\r
+            }\r
+            if (obj == null) {\r
+                return false;\r
+            }\r
+            if (getClass() != obj.getClass()) {\r
+                return false;\r
+            }\r
+            MethodSignatureBuilderImpl other = (MethodSignatureBuilderImpl) obj;\r
+            if (name == null) {\r
+                if (other.name != null) {\r
+                    return false;\r
+                }\r
+            } else if (!name.equals(other.name)) {\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            StringBuilder builder = new StringBuilder();\r
+            builder.append("MethodBuilderImpl [name=");\r
+            builder.append(name);\r
+            builder.append(", returnType=");\r
+            builder.append(returnType);\r
+            builder.append(", parameters=");\r
+            builder.append(parameters);\r
+            builder.append(", comment=");\r
+            builder.append(comment);\r
+            builder.append(", parent=");\r
+            builder.append(parent.getName());\r
+            builder.append("]");\r
+            return builder.toString();\r
+        }\r
+\r
+    }\r
+\r
+    private static final class MethodSignatureImpl implements MethodSignature {\r
+\r
+        private final String name;\r
+        private final String comment;\r
+        private final Type definingType;\r
+        private final Type returnType;\r
+        private final List<Parameter> params;\r
+\r
+        public MethodSignatureImpl(final Type definingType, final String name,\r
+                final String comment, final Type returnType,\r
+                final List<Parameter> params) {\r
+            super();\r
+            this.name = name;\r
+            this.comment = comment;\r
+            this.definingType = definingType;\r
+            this.returnType = returnType;\r
+            this.params = Collections.unmodifiableList(params);\r
+        }\r
+\r
+        @Override\r
+        public String getName() {\r
+            return name;\r
+        }\r
+\r
+        @Override\r
+        public String getComment() {\r
+            return comment;\r
+        }\r
+\r
+        @Override\r
+        public Type getDefiningType() {\r
+            return definingType;\r
+        }\r
+\r
+        @Override\r
+        public Type getReturnType() {\r
+            return returnType;\r
+        }\r
+\r
+        @Override\r
+        public List<Parameter> getParameters() {\r
+            return params;\r
+        }\r
+\r
+        @Override\r
+        public AccessModifier getAccessModifier() {\r
+            return AccessModifier.PUBLIC;\r
+        }\r
+\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result\r
+                    + ((comment == null) ? 0 : comment.hashCode());\r
+            result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+            result = prime * result\r
+                    + ((params == null) ? 0 : params.hashCode());\r
+            result = prime * result\r
+                    + ((returnType == null) ? 0 : returnType.hashCode());\r
+\r
+            if (definingType != null) {\r
+                result = prime\r
+                        * result\r
+                        + ((definingType.getPackageName() == null) ? 0\r
+                                : definingType.getPackageName().hashCode());\r
+                result = prime\r
+                        * result\r
+                        + ((definingType.getName() == null) ? 0 : definingType\r
+                                .getName().hashCode());\r
+            }\r
+\r
+            return result;\r
+        }\r
+\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj) {\r
+                return true;\r
+            }\r
+            if (obj == null) {\r
+                return false;\r
+            }\r
+            if (getClass() != obj.getClass()) {\r
+                return false;\r
+            }\r
+            MethodSignatureImpl other = (MethodSignatureImpl) obj;\r
+            if (comment == null) {\r
+                if (other.comment != null) {\r
+                    return false;\r
+                }\r
+            } else if (!comment.equals(other.comment)) {\r
+                return false;\r
+            }\r
+            if (name == null) {\r
+                if (other.name != null) {\r
+                    return false;\r
+                }\r
+            } else if (!name.equals(other.name)) {\r
+                return false;\r
+            }\r
+            if (params == null) {\r
+                if (other.params != null) {\r
+                    return false;\r
+                }\r
+            } else if (!params.equals(other.params)) {\r
+                return false;\r
+            }\r
+            if (definingType == null) {\r
+                if (other.definingType != null) {\r
+                    return false;\r
+                }\r
+            } else if ((definingType != null) && (other.definingType != null)) {\r
+                if (!definingType.getPackageName().equals(\r
+                        other.definingType.getPackageName())\r
+                        && !definingType.getName().equals(\r
+                                other.definingType.getName())) {\r
+                    return false;\r
+                }\r
+            }\r
+            if (returnType == null) {\r
+                if (other.returnType != null) {\r
+                    return false;\r
+                }\r
+            } else if (!returnType.equals(other.returnType)) {\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            StringBuilder builder = new StringBuilder();\r
+            builder.append("MethodImpl [name=");\r
+            builder.append(name);\r
+            builder.append(", comment=");\r
+            builder.append(comment);\r
+            if (definingType != null) {\r
+                builder.append(", definingType=");\r
+                builder.append(definingType.getPackageName());\r
+                builder.append(".");\r
+                builder.append(definingType.getName());\r
+            } else {\r
+                builder.append(", definingType= null");\r
+            }\r
+            builder.append(", returnType=");\r
+            builder.append(returnType);\r
+            builder.append(", params=");\r
+            builder.append(params);\r
+            builder.append("]");\r
+            return builder.toString();\r
+        }\r
+    }\r
+\r
+    private static final class GeneratedTypeImpl implements GeneratedType {\r
+\r
+        private final Type parent;\r
+        private final String packageName;\r
+        private final String name;\r
+        private final List<Enumeration> enumDefinitions;\r
+        private final List<Constant> constantDefintions;\r
+        private final List<MethodSignature> methodDefinitions;\r
+\r
+        public GeneratedTypeImpl(final Type parent, final String packageName,\r
+                final String name, final List<EnumBuilder> enumBuilders,\r
+                final List<ConstantBuilder> constantBuilders,\r
+                final List<MethodSignatureBuilder> methodBuilders) {\r
+            super();\r
+            this.parent = parent;\r
+            this.packageName = packageName;\r
+            this.name = name;\r
+\r
+            this.constantDefintions = toUnmodifiableConstants(constantBuilders);\r
+            this.enumDefinitions = toUnmodifiableEnums(enumBuilders);\r
+            this.methodDefinitions = toUnmodifiableMethods(methodBuilders);\r
+        }\r
+\r
+        private List<MethodSignature> toUnmodifiableMethods(\r
+                List<MethodSignatureBuilder> methodBuilders) {\r
+            final List<MethodSignature> methods = new ArrayList<MethodSignature>();\r
+            for (final MethodSignatureBuilder methodBuilder : methodBuilders) {\r
+                methods.add(methodBuilder.toInstance(this));\r
+            }\r
+            return Collections.unmodifiableList(methods);\r
+        }\r
+\r
+        private List<Enumeration> toUnmodifiableEnums(\r
+                List<EnumBuilder> enumBuilders) {\r
+            final List<Enumeration> enums = new ArrayList<Enumeration>();\r
+            for (final EnumBuilder enumBuilder : enumBuilders) {\r
+                enums.add(enumBuilder.toInstance(this));\r
+            }\r
+            return Collections.unmodifiableList(enums);\r
+        }\r
+\r
+        private List<Constant> toUnmodifiableConstants(\r
+                List<ConstantBuilder> constantBuilders) {\r
+            final List<Constant> constants = new ArrayList<Constant>();\r
+            for (final ConstantBuilder enumBuilder : constantBuilders) {\r
+                constants.add(enumBuilder.toInstance(this));\r
+            }\r
+            return Collections.unmodifiableList(constants);\r
+        }\r
+\r
+        @Override\r
+        public String getPackageName() {\r
+            return packageName;\r
+        }\r
+\r
+        @Override\r
+        public String getName() {\r
+            return name;\r
+        }\r
+\r
+        @Override\r
+        public Type getParentType() {\r
+            return parent;\r
+        }\r
+\r
+        @Override\r
+        public List<Enumeration> getEnumDefintions() {\r
+            return enumDefinitions;\r
+        }\r
+\r
+        @Override\r
+        public List<Constant> getConstantDefinitions() {\r
+            return constantDefintions;\r
+        }\r
+\r
+        @Override\r
+        public List<MethodSignature> getMethodDefinitions() {\r
+            return methodDefinitions;\r
+        }\r
+\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime\r
+                    * result\r
+                    + ((constantDefintions == null) ? 0 : constantDefintions\r
+                            .hashCode());\r
+            result = prime\r
+                    * result\r
+                    + ((enumDefinitions == null) ? 0 : enumDefinitions\r
+                            .hashCode());\r
+            result = prime\r
+                    * result\r
+                    + ((methodDefinitions == null) ? 0 : methodDefinitions\r
+                            .hashCode());\r
+            result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+            result = prime * result\r
+                    + ((packageName == null) ? 0 : packageName.hashCode());\r
+            return result;\r
+        }\r
+\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj) {\r
+                return true;\r
+            }\r
+            if (obj == null) {\r
+                return false;\r
+            }\r
+            if (getClass() != obj.getClass()) {\r
+                return false;\r
+            }\r
+            GeneratedTypeImpl other = (GeneratedTypeImpl) obj;\r
+            if (constantDefintions == null) {\r
+                if (other.constantDefintions != null) {\r
+                    return false;\r
+                }\r
+            } else if (!constantDefintions.equals(other.constantDefintions)) {\r
+                return false;\r
+            }\r
+            if (enumDefinitions == null) {\r
+                if (other.enumDefinitions != null) {\r
+                    return false;\r
+                }\r
+            } else if (!enumDefinitions.equals(other.enumDefinitions)) {\r
+                return false;\r
+            }\r
+            if (methodDefinitions == null) {\r
+                if (other.methodDefinitions != null) {\r
+                    return false;\r
+                }\r
+            } else if (!methodDefinitions.equals(other.methodDefinitions)) {\r
+                return false;\r
+            }\r
+            if (name == null) {\r
+                if (other.name != null) {\r
+                    return false;\r
+                }\r
+            } else if (!name.equals(other.name)) {\r
+                return false;\r
+            }\r
+            if (packageName == null) {\r
+                if (other.packageName != null) {\r
+                    return false;\r
+                }\r
+            } else if (!packageName.equals(other.packageName)) {\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            StringBuilder builder = new StringBuilder();\r
+            builder.append("GeneratedTypeImpl [parent=");\r
+            builder.append(parent.getName());\r
+            builder.append(", packageName=");\r
+            builder.append(packageName);\r
+            builder.append(", name=");\r
+            builder.append(name);\r
+            builder.append(", enumDefinitions=");\r
+            builder.append(enumDefinitions);\r
+            builder.append(", constantDefintions=");\r
+            builder.append(constantDefintions);\r
+            builder.append(", methodDefinitions=");\r
+            builder.append(methodDefinitions);\r
+            builder.append("]");\r
+            return builder.toString();\r
+        }\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/MethodParameterImpl.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/MethodParameterImpl.java
new file mode 100644 (file)
index 0000000..08eab60
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.binding.generator.impl;
+
+import org.opendaylight.controller.sal.binding.model.api.Type;
+import org.opendaylight.controller.sal.binding.model.api.MethodSignature.Parameter;
+
+final class MethodParameterImpl implements Parameter {
+
+    private final String name;
+    private final Type type;
+
+    public MethodParameterImpl(final String name, final Type type) {
+        super();
+        this.name = name;
+        this.type = type;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public Type getType() {
+        return type;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((type == null) ? 0 : type.hashCode());
+        return result;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        MethodParameterImpl other = (MethodParameterImpl) obj;
+        if (name == null) {
+            if (other.name != null) {
+                return false;
+            }
+        } else if (!name.equals(other.name)) {
+            return false;
+        }
+        if (type == null) {
+            if (other.type != null) {
+                return false;
+            }
+        } else if (!type.equals(other.type)) {
+            return false;
+        }
+        return true;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("MethodParameterImpl [name=");
+        builder.append(name);
+        builder.append(", type=");
+        builder.append(type.getPackageName());
+        builder.append(".");
+        builder.append(type.getName());
+        builder.append("]");
+        return builder.toString();
+    }
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/package-info.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/package-info.java
new file mode 100644 (file)
index 0000000..741aeef
--- /dev/null
@@ -0,0 +1,8 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.binding.generator.impl;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/BaseYangTypes.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/BaseYangTypes.java
new file mode 100644 (file)
index 0000000..d00b73d
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.yang.types;\r
+\r
+import java.math.BigDecimal;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.opendaylight.controller.binding.generator.util.Types;\r
+import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public class BaseYangTypes {\r
+\r
+    private static Map<String, Type> typeMap = new HashMap<String, Type>();\r
+\r
+    public static final Type BOOLEAN_TYPE = Types.typeForClass(Boolean.class);\r
+    public static final Type INT8_TYPE = Types.typeForClass(Byte.class);\r
+    public static final Type INT16_TYPE = Types.typeForClass(Short.class);\r
+    public static final Type INT32_TYPE = Types.typeForClass(Integer.class);\r
+    public static final Type INT64_TYPE = Types.typeForClass(Long.class);\r
+    public static final Type STRING_TYPE = Types.typeForClass(String.class);\r
+    public static final Type DECIMAL64_TYPE = Types.typeForClass(Double.class);\r
+    public static final Type UINT8_TYPE = Types.typeForClass(Short.class);\r
+    public static final Type UINT16_TYPE = Types.typeForClass(Integer.class);\r
+    public static final Type UINT32_TYPE = Types.typeForClass(Long.class);\r
+    public static final Type UINT64_TYPE = Types.typeForClass(BigDecimal.class);\r
+\r
+    static {\r
+        typeMap.put("boolean", BOOLEAN_TYPE);\r
+        typeMap.put("int8", INT8_TYPE);\r
+        typeMap.put("int16", INT16_TYPE);\r
+        typeMap.put("int32", INT32_TYPE);\r
+        typeMap.put("int64", INT64_TYPE);\r
+        typeMap.put("string", STRING_TYPE);\r
+        typeMap.put("decimal64", DECIMAL64_TYPE);\r
+        typeMap.put("uint8", UINT8_TYPE);\r
+        typeMap.put("uint16", UINT16_TYPE);\r
+        typeMap.put("uint32", UINT32_TYPE);\r
+        typeMap.put("uint64", UINT64_TYPE);\r
+\r
+    }\r
+\r
+    public static final TypeProvider BASE_YANG_TYPES_PROVIDER = new TypeProvider() {\r
+\r
+        @Override\r
+        public Type javaTypeForYangType(String type) {\r
+            return typeMap.get(type);\r
+        }\r
+\r
+        @Override\r
+        public Type javaTypeForSchemaDefinitionType(TypeDefinition<?> type) {\r
+            if (type != null) {\r
+                return typeMap.get(type.getQName().getLocalName());\r
+            }\r
+\r
+            return null;\r
+        }\r
+    };\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/TypeProviderImpl.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/TypeProviderImpl.java
new file mode 100644 (file)
index 0000000..2cc774a
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.yang.types;\r
+\r
+import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public class TypeProviderImpl implements TypeProvider {\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.type.provider.TypeProvider#\r
+     * javaTypeForYangType(java.lang.String)\r
+     */\r
+    @Override\r
+    public Type javaTypeForYangType(String type) {\r
+        Type t = BaseYangTypes.BASE_YANG_TYPES_PROVIDER\r
+                .javaTypeForYangType(type);\r
+        // TODO: this needs to be implemented in better way\r
+        // if(t == null) {\r
+        // t = BaseYangTypes.IETF_INET_TYPES_PROVIDER.javaTypeForYangType(type);\r
+        // }\r
+        return t;\r
+    }\r
+\r
+    @Override\r
+    public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type) {\r
+        if (type != null) {\r
+            Type t = BaseYangTypes.BASE_YANG_TYPES_PROVIDER\r
+                    .javaTypeForSchemaDefinitionType(type);\r
+\r
+            if (t != null) {\r
+                return t;\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/package-info.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/package-info.java
new file mode 100644 (file)
index 0000000..199dfb9
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.sal.binding.yang.types;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/yang/types/test/BaseTypeProvider.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/yang/types/test/BaseTypeProvider.java
new file mode 100644 (file)
index 0000000..d771946
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.yang.types.test;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertTrue;\r
+\r
+import org.junit.Test;\r
+import org.opendaylight.controller.binding.generator.util.Types;\r
+import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;\r
+import org.opendaylight.controller.sal.binding.model.api.ConcreteType;\r
+import org.opendaylight.controller.sal.binding.model.api.ParameterizedType;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+import org.opendaylight.controller.sal.binding.yang.types.BaseYangTypes;\r
+\r
+public class BaseTypeProvider {\r
+\r
+    @Test\r
+    public void test() {\r
+        TypeProvider provider = BaseYangTypes.BASE_YANG_TYPES_PROVIDER;\r
+\r
+        Type stringType = provider.javaTypeForYangType("string");\r
+        assertEquals("java.lang", stringType.getPackageName());\r
+        assertEquals("String", stringType.getName());\r
+        assertTrue(stringType instanceof ConcreteType);\r
+        ParameterizedType stringBooleanMap = Types.mapTypeFor(\r
+                provider.javaTypeForYangType("string"),\r
+                provider.javaTypeForYangType("boolean"));\r
+        assertTrue(stringBooleanMap instanceof ConcreteType);\r
+        assertEquals("java.util", stringBooleanMap.getPackageName());\r
+        assertEquals("Map", stringBooleanMap.getName());\r
+        assertEquals(2, stringBooleanMap.getActualTypeArguments().length);\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/yang/types/test/DefinedTypesProviderTest.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/yang/types/test/DefinedTypesProviderTest.java
new file mode 100644 (file)
index 0000000..3177a55
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.yang.types.test;\r
+\r
+public class DefinedTypesProviderTest {\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/yang/types/test/GeneratedTypesTest.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/yang/types/test/GeneratedTypesTest.java
new file mode 100644 (file)
index 0000000..049f8d9
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.binding.yang.types.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.ParseTreeWalker;
+import org.junit.Test;
+import org.opendaylight.controller.antlrv4.code.gen.YangLexer;
+import org.opendaylight.controller.antlrv4.code.gen.YangParser;
+import org.opendaylight.controller.model.parser.builder.ModuleBuilder;
+import org.opendaylight.controller.model.parser.impl.YangModelParserImpl;
+import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
+import org.opendaylight.controller.sal.binding.generator.impl.BindingGeneratorImpl;
+import org.opendaylight.controller.sal.binding.model.api.GeneratedType;
+import org.opendaylight.controller.sal.binding.model.api.MethodSignature;
+import org.opendaylight.controller.yang.model.api.Module;
+
+public class GeneratedTypesTest {
+
+    private Module resolveModuleFromFile(final String filePath) {
+        try {
+            final InputStream inStream = getClass().getResourceAsStream(
+                    filePath);
+            if (inStream != null) {
+                ANTLRInputStream input = new ANTLRInputStream(inStream);
+                final YangLexer lexer = new YangLexer(input);
+                final CommonTokenStream tokens = new CommonTokenStream(lexer);
+                final YangParser parser = new YangParser(tokens);
+
+                final ParseTree tree = parser.yang();
+                final ParseTreeWalker walker = new ParseTreeWalker();
+
+                final YangModelParserImpl modelParser = new YangModelParserImpl();
+                walker.walk(modelParser, tree);
+
+                final ModuleBuilder genModule = modelParser.getModuleBuilder();
+                final Module module = genModule.build();
+
+                return module;
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    @Test
+    public void testContainerResolving() {
+        final Module module = resolveModuleFromFile("/simple-container-demo.yang");
+        assertTrue(module != null);
+
+        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final List<GeneratedType> genTypes = bindingGen.generateTypes(module);
+
+        assertTrue(genTypes != null);
+        assertEquals(genTypes.size(), 2);
+
+        final GeneratedType simpleContainer = genTypes.get(0);
+        final GeneratedType nestedContainer = genTypes.get(1);
+
+        assertEquals(simpleContainer.getName(), "SimpleContainer");
+        assertEquals(nestedContainer.getName(), "NestedContainer");
+
+        assertEquals(simpleContainer.getMethodDefinitions().size(), 4);
+        assertEquals(nestedContainer.getMethodDefinitions().size(), 4);
+
+        int methodsCount = 0;
+        for (final MethodSignature method : simpleContainer
+                .getMethodDefinitions()) {
+            if (method.getName().equals("getFoo")) {
+                method.getReturnType().getName().equals("Integer");
+                methodsCount++;
+            }
+
+            if (method.getName().equals("setFoo")) {
+                methodsCount++;
+                final MethodSignature.Parameter param = method.getParameters()
+                        .get(0);
+                assertEquals(param.getName(), "foo");
+                assertEquals(param.getType().getName(), "Integer");
+            }
+
+            if (method.getName().equals("getBar")) {
+                method.getReturnType().getName().equals("String");
+                methodsCount++;
+            }
+
+            if (method.getName().equals("getNestedContainer")) {
+                method.getReturnType().getName().equals("NestedContainer");
+                methodsCount++;
+            }
+        }
+        assertEquals(methodsCount, 4);
+
+        methodsCount = 0;
+        for (final MethodSignature method : nestedContainer
+                .getMethodDefinitions()) {
+            if (method.getName().equals("getFoo")) {
+                method.getReturnType().getName().equals("Short");
+                methodsCount++;
+            }
+
+            if (method.getName().equals("setFoo")) {
+                methodsCount++;
+                final MethodSignature.Parameter param = method.getParameters()
+                        .get(0);
+                assertEquals(param.getName(), "foo");
+                assertEquals(param.getType().getName(), "Short");
+            }
+
+            if (method.getName().equals("getBar")) {
+                method.getReturnType().getName().equals("String");
+                methodsCount++;
+            }
+
+            if (method.getName().equals("setBar")) {
+                method.getReturnType().getName().equals("String");
+                methodsCount++;
+            }
+        }
+        assertEquals(methodsCount, 4);
+    }
+
+    @Test
+    public void testLeafListResolving() {
+        final Module module = resolveModuleFromFile("/simple-leaf-list-demo.yang");
+        assertTrue(module != null);
+
+        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final List<GeneratedType> genTypes = bindingGen.generateTypes(module);
+
+        assertTrue(genTypes != null);
+        assertEquals(genTypes.size(), 2);
+
+        final GeneratedType simpleContainer = genTypes.get(0);
+        final GeneratedType nestedContainer = genTypes.get(1);
+
+        assertEquals(simpleContainer.getName(), "SimpleContainer");
+        assertEquals(nestedContainer.getName(), "NestedContainer");
+
+        // FIXME: uncomment after fix in DOM tree parser - LeafSchemaNode bad
+        // isConfig resolving
+        assertEquals(simpleContainer.getMethodDefinitions().size(), 4);
+        assertEquals(nestedContainer.getMethodDefinitions().size(), 3);
+
+        int methodsCount = 0;
+        for (final MethodSignature method : simpleContainer
+                .getMethodDefinitions()) {
+            if (method.getName().equals("getFoo")) {
+                method.getReturnType().getName().equals("List");
+                methodsCount++;
+            }
+
+            if (method.getName().equals("setFoo")) {
+                methodsCount++;
+                final MethodSignature.Parameter param = method.getParameters()
+                        .get(0);
+                assertEquals(param.getName(), "foo");
+                assertEquals(param.getType().getName(), "List");
+            }
+
+            if (method.getName().equals("getBar")) {
+                method.getReturnType().getName().equals("String");
+                methodsCount++;
+            }
+
+            if (method.getName().equals("getNestedContainer")) {
+                method.getReturnType().getName().equals("NestedContainer");
+                methodsCount++;
+            }
+        }
+        assertEquals(methodsCount, 4);
+
+        methodsCount = 0;
+        for (final MethodSignature method : nestedContainer
+                .getMethodDefinitions()) {
+            if (method.getName().equals("getFoo")) {
+                method.getReturnType().getName().equals("Short");
+                methodsCount++;
+            }
+
+            if (method.getName().equals("setFoo")) {
+                methodsCount++;
+                final MethodSignature.Parameter param = method.getParameters()
+                        .get(0);
+                assertEquals(param.getName(), "foo");
+                assertEquals(param.getType().getName(), "Short");
+            }
+
+            if (method.getName().equals("getBar")) {
+                method.getReturnType().getName().equals("List");
+                methodsCount++;
+            }
+        }
+        assertEquals(methodsCount, 3);
+    }
+
+    @Test
+    public void testListResolving() {
+        final Module module = resolveModuleFromFile("/simple-list-demo.yang");
+        assertTrue(module != null);
+
+        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final List<GeneratedType> genTypes = bindingGen.generateTypes(module);
+
+        assertTrue(genTypes != null);
+        assertEquals(genTypes.size(), 3);
+    }
+
+    @Test
+    public void testGeneratedTypes() {
+        final Module module = resolveModuleFromFile("/demo-topology.yang");
+        assertTrue(module != null);
+
+        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final List<GeneratedType> genTypes = bindingGen.generateTypes(module);
+
+        assertTrue(genTypes != null);
+        assertEquals(genTypes.size(), 10);
+    }
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/yang/types/test/package-info.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/yang/types/test/package-info.java
new file mode 100644 (file)
index 0000000..76e8a9b
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.sal.binding.yang.types.test;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/demo-topology.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/demo-topology.yang
new file mode 100644 (file)
index 0000000..ba46b6f
--- /dev/null
@@ -0,0 +1,122 @@
+module demo-topology {
+       yang-version 1;
+    namespace "";
+    prefix "tp";
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "
+               This module contains the definitions of elements that creates network 
+               topology i.e. definition of network nodes and links. This module is
+               not designed to be used solely for network representation. This module
+               SHOULD be used as base module in defining the network topology.
+       ";
+
+    revision "2013-02-08"{
+               reference " WILL BE DEFINED LATER";
+       }
+
+       container topology {
+        description "
+                       This is the model of abstract topology which contains only Network
+                       Nodes and Network Links. Each topology MUST be identified by
+                       unique topology-id for reason that the store could contain many
+                       topologies.
+               ";
+
+        leaf topology-id {
+            type string;
+            description "
+                               It is presumed that datastore will contain many topologies. To
+                               distinguish between topologies it is vital to have UNIQUE
+                               topology identifier.
+                       ";
+        }
+
+        container network-nodes {
+               list network-node {
+                   description "The list of network nodes defined for topology.";
+
+                       key "node-id";
+
+                       leaf node-id {
+                               type string;
+                               description "The Topology identifier of network-node.";
+                       }
+                
+                list network-interface {
+                    key "interface-id";
+                    
+                    leaf interface-id {
+                        type uint8;
+                    }
+                    
+                    leaf interface-address {
+                        type string;
+                    }
+                }
+                
+                   container node-attributes {
+                                       description "
+                                               Additional attributes that can Network Node contains.
+                                       ";
+
+                                       leaf geo-latitude {
+                                               type decimal64 {
+                                                       fraction-digits 2;
+                                               }
+                                               config true;
+                                       }
+
+                                       leaf geo-longitude {
+                                               type decimal64 {
+                                                       fraction-digits 2;
+                                               }
+                                               config true;
+                                       }
+                               }
+               }
+        }
+        
+        container network-links {
+               list network-link {
+                   description "
+                                       The Network Link which is defined by Local (Source) and
+                                       Remote (Destination) Network Nodes. Every link MUST be
+                                       defined either by identifier and his local and remote
+                                       Network Nodes (in real applications it is common that many
+                                       links are originated from one node and end up in same
+                                       remote node). To ensure that we would always know to
+                                       distinguish between links, every link SHOULD have
+                                       identifier.
+                               ";
+                       key "link-id";
+
+                       leaf link-id {
+                               type string;
+                               description "";
+                       }
+
+                   container source {
+                                       leaf node-id {
+                                               type string;
+                                               description "Source node identifier.";
+                                       }
+                               }
+
+                               container destination {
+                                       leaf node-id {
+                                               type string;
+                                               description "Destination node identifier.";
+                                       }
+                               }
+
+                               container link-attributes {
+                                       description "Aditional attributes that can Network Link contains.";
+                               }
+                   }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/simple-container-demo.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/simple-container-demo.yang
new file mode 100644 (file)
index 0000000..560c3ec
--- /dev/null
@@ -0,0 +1,46 @@
+module simple-container-demo {
+       yang-version 1;
+    namespace "urn:simple.container.demo";
+    prefix "scd";
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "
+        This module contains the definitions of elements that creates network 
+        topology i.e. definition of network nodes and links. This module is
+        not designed to be used solely for network representation. This module
+        SHOULD be used as base module in defining the network topology.
+    ";
+
+    revision "2012-02-08" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    revision "2010-02-08" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    container simple-container {
+
+       leaf foo {
+               type int32;
+       }
+
+       leaf bar {
+               type string;
+               config true;
+       }
+
+       container nested-container {
+               leaf foo {
+                       type uint8;
+               }
+
+               leaf bar {
+                       type string;
+               }
+       }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/simple-leaf-list-demo.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/simple-leaf-list-demo.yang
new file mode 100644 (file)
index 0000000..78017bb
--- /dev/null
@@ -0,0 +1,47 @@
+module simple-leaf-list-demo {
+    yang-version 1;
+    namespace "urn:simple.leaf-list.demo";
+    prefix "scd";
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "
+        This module contains the definitions of elements that creates network 
+        topology i.e. definition of network nodes and links. This module is
+        not designed to be used solely for network representation. This module
+        SHOULD be used as base module in defining the network topology.
+    ";
+
+    revision "2012-02-08" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    revision "2010-02-08" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    container simple-container {
+
+        leaf-list foo {
+            type int32;
+        }
+
+        leaf bar {
+            type string;
+            config true;
+        }
+
+        container nested-container {
+            leaf foo {
+                type uint8;
+            }
+
+            leaf-list bar {
+                type string;
+                config true;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/simple-list-demo.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/simple-list-demo.yang
new file mode 100644 (file)
index 0000000..059bc08
--- /dev/null
@@ -0,0 +1,50 @@
+module simple-list-demo {
+       yang-version 1;
+    namespace "urn:simple.container.demo";
+    prefix "scd";
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "
+        This module contains the definitions of elements that creates network 
+        topology i.e. definition of network nodes and links. This module is
+        not designed to be used solely for network representation. This module
+        SHOULD be used as base module in defining the network topology.
+    ";
+
+    revision "2013-02-27" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    container list-parent-container {
+
+       list simple-list {
+               key "list-key";
+
+               leaf list-key {
+                       type int8;
+               }
+            
+            container list-child-container {
+                leaf foo {
+                    type uint8;
+                }
+            }
+            
+               leaf foo {
+                       type int32;
+               }
+            
+            leaf-list simple-leaf-list {
+                type int32;
+            }
+            
+               leaf bar {
+                       type string;
+                       config true;
+               }       
+       }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/pom.xml b/opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/pom.xml
new file mode 100644 (file)
index 0000000..97e5780
--- /dev/null
@@ -0,0 +1,21 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>binding-generator</artifactId>\r
+    <version>1.0</version>\r
+  </parent>\r
+  <artifactId>binding-generator-spi</artifactId>\r
+  <dependencies>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>binding-model-api</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>yang-model-api</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+  </dependencies>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/BindingGeneratorServiceProvider.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/BindingGeneratorServiceProvider.java
new file mode 100644 (file)
index 0000000..2677221
--- /dev/null
@@ -0,0 +1,13 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.generator.spi;\r
+\r
+public interface BindingGeneratorServiceProvider {\r
+\r
+    public void registerTypeProvider(final TypeProvider provider);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/TypeProvider.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/TypeProvider.java
new file mode 100644 (file)
index 0000000..3c00dee
--- /dev/null
@@ -0,0 +1,19 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.generator.spi;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface TypeProvider {\r
+\r
+    @Deprecated\r
+    Type javaTypeForYangType(String type);\r
+\r
+    Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/TypeProviderFactory.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/TypeProviderFactory.java
new file mode 100644 (file)
index 0000000..1b9156d
--- /dev/null
@@ -0,0 +1,13 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.generator.spi;\r
+\r
+public interface TypeProviderFactory {\r
+\r
+    TypeProvider providerFor(YANGModuleIdentifier module);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/YANGModuleIdentifier.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/YANGModuleIdentifier.java
new file mode 100644 (file)
index 0000000..8c547f4
--- /dev/null
@@ -0,0 +1,17 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.generator.spi;\r
+\r
+import java.net.URI;\r
+import java.util.Date;\r
+\r
+public class YANGModuleIdentifier {\r
+    String name;\r
+    URI namespace;\r
+    Date revision;\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/package-info.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-spi/src/main/java/org/opendaylight/controller/sal/binding/generator/spi/package-info.java
new file mode 100644 (file)
index 0000000..bf15d86
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.generator.spi;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/pom.xml b/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/pom.xml
new file mode 100644 (file)
index 0000000..8022cf4
--- /dev/null
@@ -0,0 +1,16 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>binding-generator</artifactId>\r
+    <version>1.0</version>\r
+  </parent>\r
+  <artifactId>binding-generator-util</artifactId>\r
+  <dependencies>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>binding-model-api</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+  </dependencies>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/AbstractBaseType.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/AbstractBaseType.java
new file mode 100644 (file)
index 0000000..5496cf9
--- /dev/null
@@ -0,0 +1,71 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.binding.generator.util;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+\r
+public class AbstractBaseType implements Type {\r
+\r
+    private final String packageName;\r
+    private final String name;\r
+\r
+    @Override\r
+    public String getPackageName() {\r
+        return packageName;\r
+    }\r
+\r
+    @Override\r
+    public String getName() {\r
+\r
+        return name;\r
+    }\r
+\r
+    protected AbstractBaseType(String pkName, String name) {\r
+        this.packageName = pkName;\r
+        this.name = name;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+        result = prime * result\r
+                + ((packageName == null) ? 0 : packageName.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj)\r
+            return true;\r
+        if (obj == null)\r
+            return false;\r
+        if (getClass() != obj.getClass())\r
+            return false;\r
+        Type other = (Type) obj;\r
+        if (name == null) {\r
+            if (other.getName() != null)\r
+                return false;\r
+        } else if (!name.equals(other.getPackageName()))\r
+            return false;\r
+        if (packageName == null) {\r
+            if (other.getPackageName() != null)\r
+                return false;\r
+        } else if (!packageName.equals(other.getPackageName()))\r
+            return false;\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+\r
+        return "Type (" + packageName + "." + name + ")";\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/CodeGeneratorHelper.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/CodeGeneratorHelper.java
new file mode 100644 (file)
index 0000000..552be98
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.binding.generator.util;\r
+\r
+public class CodeGeneratorHelper {\r
+\r
+    public static String parseToClassName(String token) {\r
+        String correctStr = parseToCamelCase(token);\r
+\r
+        // make first char upper-case\r
+        char first = Character.toUpperCase(correctStr.charAt(0));\r
+        correctStr = first + correctStr.substring(1);\r
+        return correctStr;\r
+    }\r
+\r
+    public static String parseToParamName(String token) {\r
+        String correctStr = parseToCamelCase(token);\r
+\r
+        // make first char lower-case\r
+        char first = Character.toLowerCase(correctStr.charAt(0));\r
+        correctStr = first + correctStr.substring(1);\r
+        return correctStr;\r
+    }\r
+\r
+    private static String parseToCamelCase(String token) {\r
+        if (token == null) {\r
+            throw new NullPointerException("Name can not be null");\r
+        }\r
+\r
+        String correctStr = token.trim();\r
+        if (correctStr.length() == 0) {\r
+            throw new IllegalArgumentException("Name can not be emty");\r
+        }\r
+\r
+        correctStr = replaceWithCamelCase(correctStr, ' ');\r
+        correctStr = replaceWithCamelCase(correctStr, '-');\r
+        correctStr = replaceWithCamelCase(correctStr, '_');\r
+        return correctStr;\r
+    }\r
+\r
+    private static String replaceWithCamelCase(String text, char removalChar) {\r
+        StringBuilder sb = new StringBuilder(text);\r
+        String toBeRemoved = String.valueOf(removalChar);\r
+\r
+        int toBeRemovedPos = sb.indexOf(toBeRemoved);\r
+        while (toBeRemovedPos != -1) {\r
+            sb.replace(toBeRemovedPos, toBeRemovedPos + 1, "");\r
+            // check if 'toBeRemoved' character is not the only character in\r
+            // 'text'\r
+            if (sb.length() == 0) {\r
+                throw new IllegalArgumentException("Name can not be '"\r
+                        + toBeRemoved + "'");\r
+            }\r
+            String replacement = String.valueOf(sb.charAt(toBeRemovedPos))\r
+                    .toUpperCase();\r
+            sb.setCharAt(toBeRemovedPos, replacement.charAt(0));\r
+            toBeRemovedPos = sb.indexOf(toBeRemoved);\r
+        }\r
+        return sb.toString();\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/Types.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/Types.java
new file mode 100644 (file)
index 0000000..8c65b4a
--- /dev/null
@@ -0,0 +1,122 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.binding.generator.util;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.ConcreteType;\r
+import org.opendaylight.controller.sal.binding.model.api.ParameterizedType;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+\r
+public class Types {\r
+    private static final Type SET_TYPE = typeForClass(Set.class);\r
+    private static final Type LIST_TYPE = typeForClass(List.class);\r
+    private static final Type MAP_TYPE = typeForClass(Map.class);\r
+\r
+    private Types() {\r
+    }\r
+\r
+    public static ConcreteType voidType() {\r
+        return new ConcreteTypeImpl(Void.class.getPackage().getName(),\r
+                Void.class.getSimpleName());\r
+    }\r
+\r
+    /**\r
+     * Returns an instance of {@link ConcreteType} describing the class\r
+     * \r
+     * @param cls\r
+     *            Class to describe\r
+     * @return Description of class\r
+     */\r
+    public static ConcreteType typeForClass(Class<?> cls) {\r
+        return new ConcreteTypeImpl(cls.getPackage().getName(),\r
+                cls.getSimpleName());\r
+    }\r
+\r
+    /**\r
+     * Returns an instance of {@link ParameterizedType} describing the typed\r
+     * {@link Map}<K,V>\r
+     * \r
+     * @param keyType\r
+     *            Key Type\r
+     * @param valueType\r
+     *            Value Type\r
+     * @return Description of generic type instance\r
+     */\r
+    public static ParameterizedType mapTypeFor(Type keyType, Type valueType) {\r
+        return parameterizedTypeFor(MAP_TYPE, keyType, valueType);\r
+    }\r
+\r
+    /**\r
+     * Returns an instance of {@link ParameterizedType} describing the typed\r
+     * {@link Set}<V> with concrete type of value.\r
+     * \r
+     * @param valueType\r
+     *            Value Type\r
+     * @return Description of generic type instance of Set\r
+     */\r
+    public static ParameterizedType setTypeFor(Type valueType) {\r
+        return parameterizedTypeFor(SET_TYPE, valueType);\r
+    }\r
+\r
+    /**\r
+     * Returns an instance of {@link ParameterizedType} describing the typed\r
+     * {@link List}<V> with concrete type of value.\r
+     * \r
+     * @param valueType\r
+     *            Value Type\r
+     * @return Description of type instance of List\r
+     */\r
+    public static ParameterizedType listTypeFor(Type valueType) {\r
+        return parameterizedTypeFor(LIST_TYPE, valueType);\r
+    }\r
+\r
+    /**\r
+     * \r
+     * @param type\r
+     * @param parameters\r
+     * @return\r
+     */\r
+    public static ParameterizedType parameterizedTypeFor(Type type,\r
+            Type... parameters) {\r
+        return new ParametrizedTypeImpl(type, parameters);\r
+    }\r
+\r
+    private static class ConcreteTypeImpl extends AbstractBaseType implements\r
+            ConcreteType {\r
+        private ConcreteTypeImpl(String pkName, String name) {\r
+            super(pkName, name);\r
+        }\r
+    }\r
+\r
+    private static class ParametrizedTypeImpl extends AbstractBaseType\r
+            implements ParameterizedType {\r
+        private Type[] actualTypes;\r
+        private Type rawType;\r
+\r
+        @Override\r
+        public Type[] getActualTypeArguments() {\r
+\r
+            return actualTypes;\r
+        }\r
+\r
+        @Override\r
+        public Type getRawType() {\r
+            return rawType;\r
+        }\r
+\r
+        public ParametrizedTypeImpl(Type rawType, Type[] actTypes) {\r
+            super(rawType.getPackageName(), rawType.getName());\r
+            this.rawType = rawType;\r
+            this.actualTypes = actTypes;\r
+        }\r
+\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/package-info.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/package-info.java
new file mode 100644 (file)
index 0000000..a5aa2a0
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.binding.generator.util;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/pom.xml b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/pom.xml
new file mode 100644 (file)
index 0000000..661dcaa
--- /dev/null
@@ -0,0 +1,22 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>binding-generator</artifactId>\r
+    <version>1.0</version>\r
+  </parent>\r
+  <artifactId>binding-java-api-generator</artifactId>\r
+  <dependencies>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>binding-model-api</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>binding-generator-impl</artifactId>\r
+          <version>1.0</version>\r
+          <scope>test</scope>\r
+      </dependency>\r
+  </dependencies>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/CompositeKeyGenerator.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/CompositeKeyGenerator.java
new file mode 100644 (file)
index 0000000..4e50f60
--- /dev/null
@@ -0,0 +1,54 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.java.api.generator;\r
+\r
+import static org.opendaylight.controller.sal.java.api.generator.Constants.*;\r
+\r
+import java.io.IOException;\r
+import java.io.StringWriter;\r
+import java.io.Writer;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.CodeGenerator;\r
+import org.opendaylight.controller.sal.binding.model.api.Constant;\r
+import org.opendaylight.controller.sal.binding.model.api.GeneratedType;\r
+\r
+public class CompositeKeyGenerator implements CodeGenerator {\r
+\r
+    @Override\r
+    public Writer generate(GeneratedType type) throws IOException {\r
+        final Writer writer = new StringWriter();\r
+        final List<Constant> fields = type.getConstantDefinitions();\r
+\r
+        writer.write(GeneratorUtil.createClassDeclarationWithPkgName(\r
+                type.getPackageName(), type.getName(), ""));\r
+        writer.write(NL);\r
+        writer.write(NL);\r
+\r
+        if (fields != null) {\r
+            for (Constant field : fields) {\r
+                writer.write(GeneratorUtil.createField(field, TAB) + NL);\r
+            }\r
+            writer.write(NL);\r
+\r
+            for (Constant field : fields) {\r
+                writer.write(GeneratorUtil.createGetter(field, TAB) + NL);\r
+            }\r
+            writer.write(NL);\r
+\r
+            writer.write(GeneratorUtil.createHashCode(fields, TAB) + NL);\r
+            writer.write(GeneratorUtil.createEquals(type, fields, TAB) + NL);\r
+            writer.write(GeneratorUtil.createToString(type, fields, TAB) + NL);\r
+\r
+            writer.write(RCB);\r
+        }\r
+\r
+        return writer;\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/Constants.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/Constants.java
new file mode 100644 (file)
index 0000000..37408bc
--- /dev/null
@@ -0,0 +1,34 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.java.api.generator;\r
+\r
+public class Constants {\r
+\r
+    public static final String IFC = "interface";\r
+    public static final String CLASS = "class";\r
+    public static final String PKG = "package";\r
+    public static final String ENUM = "enum";\r
+\r
+    public static final String LCB = "{";\r
+    public static final String RCB = "}";\r
+\r
+    public static final String LB = "(";\r
+    public static final String RB = ")";\r
+\r
+    public static final String GAP = " ";\r
+    public static final String COMMA = ",";\r
+    public static final String NL = "\n";\r
+    public static final String SC = ";";\r
+    public static final String TAB = "\t";\r
+\r
+    public static final String PUBLIC = "public";\r
+    public static final String PRIVATE = "private";\r
+    public static final String STATIC = "static";\r
+    public static final String FINAL = "final";\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorJavaFile.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorJavaFile.java
new file mode 100644 (file)
index 0000000..7944875
--- /dev/null
@@ -0,0 +1,110 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.java.api.generator;\r
+\r
+import java.io.BufferedWriter;\r
+import java.io.File;\r
+import java.io.FileWriter;\r
+import java.io.IOException;\r
+import java.io.Writer;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.CodeGenerator;\r
+import org.opendaylight.controller.sal.binding.model.api.GeneratedType;\r
+\r
+public class GeneratorJavaFile {\r
+\r
+    private final CodeGenerator codeGenerator;\r
+    private final Set<GeneratedType> types;\r
+\r
+    public GeneratorJavaFile(CodeGenerator codeGenerator,\r
+            Set<GeneratedType> types) {\r
+        this.codeGenerator = codeGenerator;\r
+        this.types = types;\r
+    }\r
+\r
+    public boolean generateToFile() {\r
+        return generateToFile(null);\r
+    }\r
+\r
+    public boolean generateToFile(String path) {\r
+        try {\r
+            for (GeneratedType type : types) {\r
+                String parentPath = generateParentPath(path,\r
+                        type.getPackageName());\r
+\r
+                File file = new File(parentPath, type.getName() + ".java");\r
+                File parent = file.getParentFile();\r
+                if (!parent.exists()) {\r
+                    parent.mkdirs();\r
+                }\r
+\r
+                if (!file.exists()) {\r
+                    FileWriter fw = null;\r
+                    BufferedWriter bw = null;\r
+\r
+                    file.createNewFile();\r
+                    fw = new FileWriter(file);\r
+                    bw = new BufferedWriter(fw);\r
+                    Writer writer = codeGenerator.generate(type);\r
+                    bw.write(writer.toString());\r
+\r
+                    if (bw != null) {\r
+                        try {\r
+                            bw.close();\r
+                        } catch (IOException e) {\r
+                            // TODO: log?\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            return true;\r
+        } catch (IOException e) {\r
+            // TODO: log?\r
+            return false;\r
+        }\r
+    }\r
+\r
+    private String generateParentPath(String path, String pkg) {\r
+        List<String> dirs = new ArrayList<String>();\r
+        String pkgPath = "";\r
+        if (pkg != null) {\r
+            if (pkg.length() > 0) {\r
+                if (pkg.contains(".")) {\r
+                    String[] split = pkg.split("\\.");\r
+                    for (String dir : split) {\r
+                        dirs.add(dir);\r
+                    }\r
+                } else {\r
+                    dirs.add(pkg);\r
+                }\r
+                for (int i = 0; i < dirs.size(); i++) {\r
+                    if (i == 0) {\r
+                        pkgPath += dirs.get(i);\r
+                    } else {\r
+                        pkgPath += File.separator + dirs.get(i);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        String fullPath = "";\r
+        if (path != null) {\r
+            if (path.endsWith(File.separator)) {\r
+                fullPath = path + pkgPath;\r
+            } else {\r
+                fullPath = path + File.separator + pkgPath;\r
+            }\r
+        } else {\r
+            fullPath = pkgPath;\r
+        }\r
+        return fullPath;\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java
new file mode 100644 (file)
index 0000000..673d37e
--- /dev/null
@@ -0,0 +1,286 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.java.api.generator;\r
+\r
+import static org.opendaylight.controller.sal.java.api.generator.Constants.*;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.Constant;\r
+import org.opendaylight.controller.sal.binding.model.api.Enumeration;\r
+import org.opendaylight.controller.sal.binding.model.api.MethodSignature;\r
+import org.opendaylight.controller.sal.binding.model.api.ParameterizedType;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+import org.opendaylight.controller.sal.binding.model.api.Enumeration.Pair;\r
+import org.opendaylight.controller.sal.binding.model.api.MethodSignature.Parameter;\r
+\r
+public class GeneratorUtil {\r
+\r
+    private GeneratorUtil() {\r
+    }\r
+\r
+    public static String createIfcDeclarationWithPkgName(String packageName,\r
+            String name, String indent) {\r
+        return createFileDeclarationWithPkgName(IFC, packageName, name, indent);\r
+    }\r
+\r
+    public static String createClassDeclarationWithPkgName(String packageName,\r
+            String name, String indent) {\r
+        return createFileDeclarationWithPkgName(CLASS, packageName, name,\r
+                indent);\r
+    }\r
+\r
+    private static String createFileDeclarationWithPkgName(String type,\r
+            String packageName, String name, String indent) {\r
+        StringBuilder sb = new StringBuilder();\r
+        sb.append(PKG + GAP + packageName + SC);\r
+        sb.append(NL);\r
+        sb.append(NL);\r
+        sb.append(PUBLIC + GAP + type + GAP + name + GAP + LCB);\r
+        return sb.toString();\r
+    }\r
+\r
+    public static String createConstant(Constant constant, String indent) {\r
+        StringBuilder sb = new StringBuilder();\r
+        sb.append(indent + PUBLIC + GAP + STATIC + GAP + FINAL + GAP);\r
+        sb.append(getExplicitType(constant.getType()) + GAP\r
+                + constant.getName());\r
+        sb.append(GAP + "=" + GAP);\r
+        sb.append(constant.getValue() + SC);\r
+        return sb.toString();\r
+    }\r
+\r
+    public static String createField(Constant field, String indent) {\r
+        StringBuilder sb = new StringBuilder();\r
+        sb.append(indent + PRIVATE + GAP);\r
+        sb.append(getExplicitType(field.getType()) + GAP + field.getName());\r
+        sb.append(GAP + "=" + GAP);\r
+        sb.append(field.getValue() + SC);\r
+        return sb.toString();\r
+    }\r
+\r
+    /**\r
+     * Create method declaration in interface.\r
+     * \r
+     * @param method\r
+     * @param indent\r
+     * @return\r
+     */\r
+    public static String createMethodDeclaration(MethodSignature method,\r
+            String indent) {\r
+        String comment = method.getComment();\r
+        Type type = method.getReturnType();\r
+        String name = method.getName();\r
+        List<Parameter> parameters = method.getParameters();\r
+\r
+        StringBuilder sb = new StringBuilder();\r
+        createComment(sb, comment, indent);\r
+\r
+        sb.append(indent + getExplicitType(type) + GAP + name);\r
+        sb.append(LB);\r
+        for (int i = 0; i < parameters.size(); i++) {\r
+            Parameter p = parameters.get(i);\r
+            String separator = COMMA;\r
+            if (i + 1 == parameters.size()) {\r
+                separator = "";\r
+            }\r
+            sb.append(getExplicitType(p.getType()) + GAP + p.getName()\r
+                    + separator);\r
+        }\r
+        sb.append(RB);\r
+        sb.append(SC);\r
+\r
+        return sb.toString();\r
+    }\r
+\r
+    public static String createGetter(Constant field, String indent) {\r
+        StringBuilder sb = new StringBuilder();\r
+\r
+        Type type = field.getType();\r
+        String varName = field.getName();\r
+        char first = Character.toUpperCase(varName.charAt(0));\r
+        String methodName = "get" + first + varName.substring(1);\r
+\r
+        sb.append(indent + PUBLIC + GAP + getExplicitType(type) + GAP\r
+                + methodName);\r
+        sb.append(LB + RB + LCB + NL);\r
+\r
+        String currentIndent = indent + TAB;\r
+\r
+        sb.append(currentIndent + "return " + varName + SC + NL);\r
+\r
+        sb.append(indent + RCB);\r
+        return sb.toString();\r
+    }\r
+\r
+    public static String createHashCode(List<Constant> fields, String indent) {\r
+        StringBuilder sb = new StringBuilder();\r
+        sb.append(indent + "public int hashCode() {" + NL);\r
+        sb.append(indent + TAB + "final int prime = 31;" + NL);\r
+        sb.append(indent + TAB + "int result = 1;" + NL);\r
+\r
+        for (Constant field : fields) {\r
+            String fieldName = field.getName();\r
+            sb.append(indent + TAB + "result = prime * result + ((" + fieldName\r
+                    + " == null) ? 0 : " + fieldName + ".hashCode());" + NL);\r
+        }\r
+\r
+        sb.append(indent + TAB + "return result;" + NL);\r
+        sb.append(indent + RCB + NL);\r
+        return sb.toString();\r
+    }\r
+\r
+    public static String createEquals(Type type, List<Constant> fields,\r
+            String indent) {\r
+        StringBuilder sb = new StringBuilder();\r
+        final String indent1 = indent + TAB;\r
+        final String indent2 = indent + TAB + TAB;\r
+        final String indent3 = indent + TAB + TAB + TAB;\r
+\r
+        sb.append(indent + "public boolean equals(Object obj) {" + NL);\r
+        sb.append(indent1 + "if (this == obj) {" + NL);\r
+        sb.append(indent2 + "return true;" + NL);\r
+        sb.append(indent1 + "}" + NL);\r
+        sb.append(indent1 + "if (obj == null) {" + NL);\r
+        sb.append(indent2 + "return false;" + NL);\r
+        sb.append(indent1 + "}" + NL);\r
+        sb.append(indent1 + "if (getClass() != obj.getClass()) {" + NL);\r
+        sb.append(indent2 + "return false;" + NL);\r
+        sb.append(indent1 + "}" + NL);\r
+\r
+        String typeStr = type.getPackageName() + "." + type.getName();\r
+        sb.append(indent1 + typeStr + " other = (" + typeStr + ") obj;" + NL);\r
+\r
+        for (Constant field : fields) {\r
+            String fieldName = field.getName();\r
+            sb.append(indent1 + "if (" + fieldName + " == null) {" + NL);\r
+            sb.append(indent2 + "if (other." + fieldName + " != null) {" + NL);\r
+            sb.append(indent3 + "return false;" + NL);\r
+            sb.append(indent2 + "}" + NL);\r
+            sb.append(indent1 + "} else if (!" + fieldName + ".equals(other."\r
+                    + fieldName + ")) {" + NL);\r
+            sb.append(indent2 + "return false;" + NL);\r
+            sb.append(indent1 + "}" + NL);\r
+        }\r
+\r
+        sb.append(indent1 + "return true;" + NL);\r
+\r
+        sb.append(indent + RCB + NL);\r
+        return sb.toString();\r
+    }\r
+\r
+    public static String createToString(Type type, List<Constant> fields,\r
+            String indent) {\r
+        StringBuilder sb = new StringBuilder();\r
+        String typeStr = type.getPackageName() + "." + type.getName();\r
+\r
+        sb.append(indent + "public String toString() {" + NL);\r
+        sb.append(indent + TAB + "return \"" + typeStr + "[");\r
+\r
+        boolean first = true;\r
+        for (Constant field : fields) {\r
+            String fieldName = field.getName();\r
+            String fieldType = field.getType().getPackageName() + "."\r
+                    + field.getType().getName();\r
+            if (first) {\r
+                if (fieldType.equals("java.lang.String")) {\r
+                    sb.append(fieldName + "=\\\""\r
+                            + parseStringValue((String) field.getValue())\r
+                            + "\\\"");\r
+                } else {\r
+                    sb.append(fieldName + "=" + field.getValue() + "");\r
+                }\r
+            } else {\r
+                if (fieldType.equals("java.lang.String")) {\r
+                    sb.append(", " + fieldName + "=\\\""\r
+                            + parseStringValue((String) field.getValue())\r
+                            + "\\\"");\r
+                } else {\r
+                    sb.append(", " + fieldName + "=" + field.getValue() + "");\r
+                }\r
+\r
+            }\r
+            first = false;\r
+        }\r
+        sb.append("]\"" + SC + NL);\r
+\r
+        sb.append(indent + RCB + NL);\r
+        return sb.toString();\r
+    }\r
+\r
+    /**\r
+     * Remove starting and ending quote sign\r
+     * \r
+     * @param o\r
+     * @return\r
+     */\r
+    private static String parseStringValue(String str) {\r
+        return str.substring(1, str.length() - 1);\r
+    }\r
+\r
+    public static String createEnum(Enumeration e, String indent) {\r
+        StringBuilder sb = new StringBuilder(indent + ENUM + GAP + e.getName()\r
+                + GAP + LCB + NL);\r
+\r
+        String separator = COMMA;\r
+        List<Pair> values = e.getValues();\r
+        sb.append(indent + TAB);\r
+        for (int i = 0; i < values.size(); i++) {\r
+            if (i + 1 == values.size()) {\r
+                separator = SC;\r
+            }\r
+            sb.append(values.get(i).getName() + separator);\r
+        }\r
+        sb.append(NL);\r
+        sb.append(indent + RCB);\r
+        return sb.toString();\r
+    }\r
+\r
+    private static String getExplicitType(Type type) {\r
+        String packageName = type.getPackageName();\r
+        if (packageName.endsWith(".")) {\r
+            packageName = packageName.substring(0, packageName.length() - 1);\r
+        }\r
+        StringBuilder sb = new StringBuilder(packageName + "." + type.getName());\r
+        if (type instanceof ParameterizedType) {\r
+            ParameterizedType pType = (ParameterizedType) type;\r
+            Type[] pTypes = pType.getActualTypeArguments();\r
+            sb.append("<");\r
+            sb.append(getParameters(pTypes));\r
+            sb.append(">");\r
+        }\r
+        if (sb.toString().equals("java.lang.Void")) {\r
+            return "void";\r
+        }\r
+        return sb.toString();\r
+    }\r
+\r
+    private static String getParameters(Type[] pTypes) {\r
+        StringBuilder sb = new StringBuilder();\r
+        for (int i = 0; i < pTypes.length; i++) {\r
+            Type t = pTypes[i];\r
+\r
+            String separator = COMMA;\r
+            if (i + 1 == pTypes.length) {\r
+                separator = "";\r
+            }\r
+            sb.append(getExplicitType(t) + separator);\r
+        }\r
+        return sb.toString();\r
+    }\r
+\r
+    private static void createComment(StringBuilder sb, String comment,\r
+            String indent) {\r
+        if (comment != null && comment.length() > 0) {\r
+            sb.append(indent + "/*" + NL);\r
+            sb.append(indent + comment + NL);\r
+            sb.append(indent + "*/" + NL);\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/InterfaceGenerator.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/InterfaceGenerator.java
new file mode 100644 (file)
index 0000000..8a0054b
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.java.api.generator;\r
+\r
+import static org.opendaylight.controller.sal.java.api.generator.Constants.*;\r
+\r
+import java.io.IOException;\r
+import java.io.StringWriter;\r
+import java.io.Writer;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.CodeGenerator;\r
+import org.opendaylight.controller.sal.binding.model.api.Constant;\r
+import org.opendaylight.controller.sal.binding.model.api.Enumeration;\r
+import org.opendaylight.controller.sal.binding.model.api.GeneratedType;\r
+import org.opendaylight.controller.sal.binding.model.api.MethodSignature;\r
+\r
+public class InterfaceGenerator implements CodeGenerator {\r
+\r
+    public Writer generate(GeneratedType type) throws IOException {\r
+        Writer writer = new StringWriter();\r
+        final List<Constant> constants = type.getConstantDefinitions();\r
+        final List<MethodSignature> methods = type.getMethodDefinitions();\r
+        final List<Enumeration> enums = type.getEnumDefintions();\r
+\r
+        writer.write(GeneratorUtil.createIfcDeclarationWithPkgName(\r
+                type.getPackageName(), type.getName(), ""));\r
+        writer.write(NL);\r
+\r
+        if (constants != null) {\r
+            for (Constant c : constants) {\r
+                writer.write(GeneratorUtil.createConstant(c, TAB) + NL);\r
+            }\r
+            writer.write(NL);\r
+        }\r
+\r
+        if (methods != null) {\r
+            for (MethodSignature m : methods) {\r
+                writer.write(GeneratorUtil.createMethodDeclaration(m, TAB) + NL);\r
+            }\r
+            writer.write(NL);\r
+        }\r
+\r
+        if (enums != null) {\r
+            for (Enumeration e : enums) {\r
+                writer.write(GeneratorUtil.createEnum(e, TAB) + NL);\r
+            }\r
+            writer.write(NL);\r
+        }\r
+\r
+        writer.write(RCB);\r
+\r
+        return writer;\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/package-info.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/package-info.java
new file mode 100644 (file)
index 0000000..c202f76
--- /dev/null
@@ -0,0 +1,8 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.java.api.generator;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/controller/sal/java/api/generator/test/GeneratorJavaFileTest.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/controller/sal/java/api/generator/test/GeneratorJavaFileTest.java
new file mode 100644 (file)
index 0000000..36d0fbc
--- /dev/null
@@ -0,0 +1,87 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.java.api.generator.test;\r
+\r
+import static org.junit.Assert.*;\r
+\r
+import java.io.File;\r
+import java.util.Arrays;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.junit.After;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.controller.sal.binding.generator.impl.GeneratedTypeBuilderImpl;\r
+import org.opendaylight.controller.sal.binding.model.api.GeneratedType;\r
+import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTypeBuilder;\r
+import org.opendaylight.controller.sal.java.api.generator.GeneratorJavaFile;\r
+import org.opendaylight.controller.sal.java.api.generator.InterfaceGenerator;\r
+\r
+public class GeneratorJavaFileTest {\r
+\r
+    private static final String FS = File.separator;\r
+    private static final String PATH = "test-dir";\r
+    private final File testDir = new File(PATH);\r
+\r
+    @Before\r
+    public void init() {\r
+        assertTrue(testDir.mkdir());\r
+    }\r
+\r
+    @After\r
+    public void cleanUp() {\r
+        deleteTestDir(testDir);\r
+    }\r
+\r
+    @Test\r
+    public void test() {\r
+        final Set<GeneratedType> types = new HashSet<GeneratedType>();\r
+        GeneratedType t1 = createGeneratedType(\r
+                "org.opendaylight.controller.gen", "Type1");\r
+        GeneratedType t2 = createGeneratedType(\r
+                "org.opendaylight.controller.gen", "Type2");\r
+        GeneratedType t3 = createGeneratedType(\r
+                "org.opendaylight.controller.gen", "Type3");\r
+        types.add(t1);\r
+        types.add(t2);\r
+        types.add(t3);\r
+        GeneratorJavaFile generator = new GeneratorJavaFile(\r
+                new InterfaceGenerator(), types);\r
+        generator.generateToFile(PATH);\r
+\r
+        // path: test-dir/com/cisco/yang\r
+        String[] files = new File(PATH + FS + "com" + FS + "cisco" + FS\r
+                + "yang").list();\r
+        List<String> filesList = Arrays.asList(files);\r
+\r
+        assertEquals(3, files.length);\r
+        assertTrue(filesList.contains("Type1.java"));\r
+        assertTrue(filesList.contains("Type2.java"));\r
+        assertTrue(filesList.contains("Type3.java"));\r
+    }\r
+\r
+    private GeneratedType createGeneratedType(String pkgName, String name) {\r
+        GeneratedTypeBuilder builder = new GeneratedTypeBuilderImpl(pkgName,\r
+                name);\r
+        return builder.toInstance();\r
+    }\r
+\r
+    private void deleteTestDir(File file) {\r
+        if (file.isDirectory()) {\r
+            for (File f : file.listFiles()) {\r
+                deleteTestDir(f);\r
+            }\r
+        }\r
+        if (!file.delete()) {\r
+            throw new RuntimeException("Failed to clean up after test");\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/controller/sal/java/api/generator/test/package-info.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/controller/sal/java/api/generator/test/package-info.java
new file mode 100644 (file)
index 0000000..82d6668
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.sal.java.api.generator.test;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/abstract-topology.yang b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/abstract-topology.yang
new file mode 100644 (file)
index 0000000..b0dff3c
--- /dev/null
@@ -0,0 +1,131 @@
+// vi: set smarttab sw=4 tabstop=4:
+module abstract-topology {
+       yang-version 1;
+    namespace "";
+    prefix "tp";
+
+       import ietf-inet-types { prefix "inet"; }
+    import abstract-prefixes { prefix "abs-pref"; }
+    
+       organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "
+               This module contains the definitions of elements that creates network 
+               topology i.e. definition of network nodes and links. This module is
+               not designed to be used solely for network representation. This module
+               SHOULD be used as base module in defining the network topology.
+       ";
+
+    revision "2013-02-08" {
+               reference " WILL BE DEFINED LATER";
+       }
+
+    revision "2013-03-08" {
+        reference " WILL BE DEFINED LATER";
+    }
+    
+    revision "2012-02-08" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    typedef topology-id-ref {
+       type leafref {
+               path "/tp:topology/tp:topology-id";
+       }
+       description "This type is used for leafs that reference topology identifier instance.";
+    }
+
+       typedef network-node-id-ref {
+               type leafref {
+                       path "/tp:topology/tp:network-nodes/tp:network-node/tp:node-id";
+               }
+               description "This type is used for leafs that reference network node instance.";
+       }
+
+       typedef link-id-ref {
+               type leafref {
+                       path "/tp:topology/tp:network-links/tp:network-link/tp:link-id";
+               }
+               description "This type is used for leafs that reference network link instance.";
+       }
+
+       container topology {
+        description "
+                       This is the model of abstract topology which contains only Network
+                       Nodes and Network Links. Each topology MUST be identified by
+                       unique topology-id for reason that the store could contain many
+                       topologies.
+               ";
+
+        leaf topology-id {
+            type inet:uri;
+            description "
+                               It is presumed that datastore will contain many topologies. To
+                               distinguish between topologies it is vital to have UNIQUE
+                               topology identifier.
+                       ";
+        }
+
+        container network-nodes {
+               list network-node {
+                   description "The list of network nodes defined for topology.";
+
+                       key "node-id";
+
+                       leaf node-id {
+                               type inet:uri;
+                               description "The Topology identifier of network-node.";
+                       }
+
+                   container attributes {
+                                       description "
+                                               Additional attributes that can Network Node contains.
+                                       ";
+                               }
+               }
+        }
+        
+        container network-links {
+               list network-link {
+                   description "
+                                       The Network Link which is defined by Local (Source) and
+                                       Remote (Destination) Network Nodes. Every link MUST be
+                                       defined either by identifier and his local and remote
+                                       Network Nodes (in real applications it is common that many
+                                       links are originated from one node and end up in same
+                                       remote node). To ensure that we would always know to
+                                       distinguish between links, every link SHOULD have
+                                       identifier.
+                               ";
+                       key "link-id";
+
+                       leaf link-id {
+                               type inet:uri;
+                               description "";
+                       }
+
+                   container source {
+                                       leaf node-id {
+                                               type node-id-ref;
+                                               description "Source node identifier.";
+                                       }
+                               }
+
+                               container destination {
+                                       leaf node-id {
+                                               type node-id-ref;
+                                               description "Destination node identifier.";
+                                       }
+                               }
+
+                               container attributes {
+                                       description "Aditional attributes that can Network Link contains.";
+                               }
+                   }
+        }
+    }
+
+    //TODO: add base operations
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/demo-topology.yang b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/demo-topology.yang
new file mode 100644 (file)
index 0000000..ba46b6f
--- /dev/null
@@ -0,0 +1,122 @@
+module demo-topology {
+       yang-version 1;
+    namespace "";
+    prefix "tp";
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "
+               This module contains the definitions of elements that creates network 
+               topology i.e. definition of network nodes and links. This module is
+               not designed to be used solely for network representation. This module
+               SHOULD be used as base module in defining the network topology.
+       ";
+
+    revision "2013-02-08"{
+               reference " WILL BE DEFINED LATER";
+       }
+
+       container topology {
+        description "
+                       This is the model of abstract topology which contains only Network
+                       Nodes and Network Links. Each topology MUST be identified by
+                       unique topology-id for reason that the store could contain many
+                       topologies.
+               ";
+
+        leaf topology-id {
+            type string;
+            description "
+                               It is presumed that datastore will contain many topologies. To
+                               distinguish between topologies it is vital to have UNIQUE
+                               topology identifier.
+                       ";
+        }
+
+        container network-nodes {
+               list network-node {
+                   description "The list of network nodes defined for topology.";
+
+                       key "node-id";
+
+                       leaf node-id {
+                               type string;
+                               description "The Topology identifier of network-node.";
+                       }
+                
+                list network-interface {
+                    key "interface-id";
+                    
+                    leaf interface-id {
+                        type uint8;
+                    }
+                    
+                    leaf interface-address {
+                        type string;
+                    }
+                }
+                
+                   container node-attributes {
+                                       description "
+                                               Additional attributes that can Network Node contains.
+                                       ";
+
+                                       leaf geo-latitude {
+                                               type decimal64 {
+                                                       fraction-digits 2;
+                                               }
+                                               config true;
+                                       }
+
+                                       leaf geo-longitude {
+                                               type decimal64 {
+                                                       fraction-digits 2;
+                                               }
+                                               config true;
+                                       }
+                               }
+               }
+        }
+        
+        container network-links {
+               list network-link {
+                   description "
+                                       The Network Link which is defined by Local (Source) and
+                                       Remote (Destination) Network Nodes. Every link MUST be
+                                       defined either by identifier and his local and remote
+                                       Network Nodes (in real applications it is common that many
+                                       links are originated from one node and end up in same
+                                       remote node). To ensure that we would always know to
+                                       distinguish between links, every link SHOULD have
+                                       identifier.
+                               ";
+                       key "link-id";
+
+                       leaf link-id {
+                               type string;
+                               description "";
+                       }
+
+                   container source {
+                                       leaf node-id {
+                                               type string;
+                                               description "Source node identifier.";
+                                       }
+                               }
+
+                               container destination {
+                                       leaf node-id {
+                                               type string;
+                                               description "Destination node identifier.";
+                                       }
+                               }
+
+                               container link-attributes {
+                                       description "Aditional attributes that can Network Link contains.";
+                               }
+                   }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/simple-container-demo.yang b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/simple-container-demo.yang
new file mode 100644 (file)
index 0000000..560c3ec
--- /dev/null
@@ -0,0 +1,46 @@
+module simple-container-demo {
+       yang-version 1;
+    namespace "urn:simple.container.demo";
+    prefix "scd";
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "
+        This module contains the definitions of elements that creates network 
+        topology i.e. definition of network nodes and links. This module is
+        not designed to be used solely for network representation. This module
+        SHOULD be used as base module in defining the network topology.
+    ";
+
+    revision "2012-02-08" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    revision "2010-02-08" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    container simple-container {
+
+       leaf foo {
+               type int32;
+       }
+
+       leaf bar {
+               type string;
+               config true;
+       }
+
+       container nested-container {
+               leaf foo {
+                       type uint8;
+               }
+
+               leaf bar {
+                       type string;
+               }
+       }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/simple-leaf-list-demo.yang b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/simple-leaf-list-demo.yang
new file mode 100644 (file)
index 0000000..78017bb
--- /dev/null
@@ -0,0 +1,47 @@
+module simple-leaf-list-demo {
+    yang-version 1;
+    namespace "urn:simple.leaf-list.demo";
+    prefix "scd";
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "
+        This module contains the definitions of elements that creates network 
+        topology i.e. definition of network nodes and links. This module is
+        not designed to be used solely for network representation. This module
+        SHOULD be used as base module in defining the network topology.
+    ";
+
+    revision "2012-02-08" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    revision "2010-02-08" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    container simple-container {
+
+        leaf-list foo {
+            type int32;
+        }
+
+        leaf bar {
+            type string;
+            config true;
+        }
+
+        container nested-container {
+            leaf foo {
+                type uint8;
+            }
+
+            leaf-list bar {
+                type string;
+                config true;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/simple-list-demo.yang b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/simple-list-demo.yang
new file mode 100644 (file)
index 0000000..059bc08
--- /dev/null
@@ -0,0 +1,50 @@
+module simple-list-demo {
+       yang-version 1;
+    namespace "urn:simple.container.demo";
+    prefix "scd";
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "
+        This module contains the definitions of elements that creates network 
+        topology i.e. definition of network nodes and links. This module is
+        not designed to be used solely for network representation. This module
+        SHOULD be used as base module in defining the network topology.
+    ";
+
+    revision "2013-02-27" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    container list-parent-container {
+
+       list simple-list {
+               key "list-key";
+
+               leaf list-key {
+                       type int8;
+               }
+            
+            container list-child-container {
+                leaf foo {
+                    type uint8;
+                }
+            }
+            
+               leaf foo {
+                       type int32;
+               }
+            
+            leaf-list simple-leaf-list {
+                type int32;
+            }
+            
+               leaf bar {
+                       type string;
+                       config true;
+               }       
+       }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/pom.xml b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/pom.xml
new file mode 100644 (file)
index 0000000..c9e60b6
--- /dev/null
@@ -0,0 +1,9 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>binding-generator</artifactId>\r
+    <version>1.0</version>\r
+  </parent>\r
+  <artifactId>binding-model-api</artifactId>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/AccessModifier.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/AccessModifier.java
new file mode 100644 (file)
index 0000000..5096dd8
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api;\r
+\r
+public enum AccessModifier {\r
+    PRIVATE, PUBLIC, PROTECTED\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/CodeGenerator.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/CodeGenerator.java
new file mode 100644 (file)
index 0000000..6e8d317
--- /dev/null
@@ -0,0 +1,17 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api;\r
+\r
+import java.io.IOException;\r
+import java.io.Writer;\r
+\r
+public interface CodeGenerator {\r
+\r
+    Writer generate(GeneratedType type) throws IOException;\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/ConcreteType.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/ConcreteType.java
new file mode 100644 (file)
index 0000000..ea11aba
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.binding.model.api;
+
+public interface ConcreteType extends Type {
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/Constant.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/Constant.java
new file mode 100644 (file)
index 0000000..cad3460
--- /dev/null
@@ -0,0 +1,21 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api;\r
+\r
+public interface Constant {\r
+\r
+    public Type getDefiningType();\r
+\r
+    public Type getType();\r
+\r
+    public String getName();\r
+\r
+    public Object getValue();\r
+\r
+    public String toFormattedString();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/Enumeration.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/Enumeration.java
new file mode 100644 (file)
index 0000000..bfce017
--- /dev/null
@@ -0,0 +1,26 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api;\r
+\r
+import java.util.List;\r
+\r
+public interface Enumeration extends Type {\r
+\r
+    public Type getDefiningType();\r
+\r
+    public List<Pair> getValues();\r
+\r
+    public String toFormattedString();\r
+\r
+    interface Pair {\r
+\r
+        public String getName();\r
+\r
+        public Integer getValue();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedProperty.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedProperty.java
new file mode 100644 (file)
index 0000000..462e1e1
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api;\r
+\r
+public interface GeneratedProperty extends MethodSignature {\r
+\r
+    public boolean isReadOnly();\r
+\r
+    public boolean isFinal();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedTransferObject.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedTransferObject.java
new file mode 100644 (file)
index 0000000..4bed98a
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.binding.model.api;
+
+import java.util.List;
+import java.util.Set;
+
+public interface GeneratedTransferObject extends Type {
+    
+    /**
+     * Returns Set of all Enumerator definitions associated with interface.
+     * 
+     * @return Set of all Enumerator definitions associated with interface.
+     */
+    public List<Enumeration> getEnumDefintions();
+    
+    public List<GeneratedProperty> getProperties();
+    
+    public List<GeneratedProperty> getEqualsIdentifiers();
+    
+    public List<GeneratedProperty> getHashCodeIdentifiers();
+    
+    public List<GeneratedProperty> getToStringIdentifiers();
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedType.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedType.java
new file mode 100644 (file)
index 0000000..5382311
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Every Java interface has to be specified with:\r
+ * <ul>\r
+ * <li><code>package</code> that belongs into</li>\r
+ * <li><code>interface</code> name (with commentary that <b>SHOULD</b> be\r
+ * present to proper define interface and base <i>contracts</i> specified for\r
+ * interface)</li>\r
+ * <li><code>enum</code> and <code>constant</code> definitions (i.e. each\r
+ * constant definition is by default defined as <code>public static final</code>\r
+ * + type (either primitive or object) and constant name</li>\r
+ * <li><code>method definitions</code> with specified input parameters (with\r
+ * types) and return values</li>\r
+ * </ul>\r
+ * \r
+ * By the definition of the interface constant, enum and method definitions MUST\r
+ * be public, so there is no need to specify the scope of visibility.\r
+ * \r
+ * \r
+ */\r
+public interface GeneratedType extends Type {\r
+\r
+    public Type getParentType();\r
+\r
+    /**\r
+     * Returns Set of all Enumerator definitions associated with interface.\r
+     * \r
+     * @return Set of all Enumerator definitions associated with interface.\r
+     */\r
+    public List<Enumeration> getEnumDefintions();\r
+\r
+    /**\r
+     * \r
+     * \r
+     * @return\r
+     */\r
+    public List<Constant> getConstantDefinitions();\r
+\r
+    /**\r
+     * \r
+     * \r
+     * @return\r
+     */\r
+    public List<MethodSignature> getMethodDefinitions();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/MethodSignature.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/MethodSignature.java
new file mode 100644 (file)
index 0000000..603ffdb
--- /dev/null
@@ -0,0 +1,31 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api;\r
+\r
+import java.util.List;\r
+\r
+public interface MethodSignature {\r
+\r
+    public String getName();\r
+\r
+    public String getComment();\r
+\r
+    public Type getDefiningType();\r
+\r
+    public Type getReturnType();\r
+\r
+    public List<Parameter> getParameters();\r
+\r
+    public AccessModifier getAccessModifier();\r
+\r
+    interface Parameter {\r
+        public String getName();\r
+\r
+        public Type getType();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/ParameterizedType.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/ParameterizedType.java
new file mode 100644 (file)
index 0000000..1e800ac
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api;\r
+\r
+/**\r
+ * Represents an instance of simple parametrized type such as List<String>.\r
+ */\r
+public interface ParameterizedType extends Type {\r
+\r
+    Type[] getActualTypeArguments();\r
+\r
+    Type getRawType();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/Type.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/Type.java
new file mode 100644 (file)
index 0000000..1ec3c9f
--- /dev/null
@@ -0,0 +1,24 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api;\r
+\r
+public interface Type {\r
+    /**\r
+     * Returns name of the package that interface belongs to.\r
+     * \r
+     * @return name of the package that interface belongs to\r
+     */\r
+    public String getPackageName();\r
+\r
+    /**\r
+     * Returns name of the interface.\r
+     * \r
+     * @return name of the interface.\r
+     */\r
+    public String getName();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/package-info.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/package-info.java
new file mode 100644 (file)
index 0000000..d969a6f
--- /dev/null
@@ -0,0 +1,8 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.binding.model.api;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/ConstantBuilder.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/ConstantBuilder.java
new file mode 100644 (file)
index 0000000..1a16f86
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api.type.builder;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.Constant;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+\r
+/**\r
+\r
+ *\r
+ */\r
+public interface ConstantBuilder {\r
+\r
+    public void assignValue(final Object value);\r
+\r
+    public Constant toInstance(Type definingType);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/EnumBuilder.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/EnumBuilder.java
new file mode 100644 (file)
index 0000000..e9c077e
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api.type.builder;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.Enumeration;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+\r
+/**\r
+\r
+ *\r
+ */\r
+public interface EnumBuilder {\r
+\r
+    public void addValue(final String name, final Integer value);\r
+\r
+    public Enumeration toInstance(final Type definingType);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/GeneratedPropertyBuilder.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/GeneratedPropertyBuilder.java
new file mode 100644 (file)
index 0000000..c01e740
--- /dev/null
@@ -0,0 +1,33 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.sal.binding.model.api.type.builder;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.AccessModifier;\r
+import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+\r
+/**\r
+\r
+ *\r
+ */\r
+public interface GeneratedPropertyBuilder {\r
+    \r
+    public String getName();\r
+    \r
+    public boolean addReturnType(final Type returnType);\r
+    \r
+    public void accessorModifier(final AccessModifier modifier);\r
+    \r
+    public void addComment(final String comment);\r
+    \r
+    public void setFinal(final boolean isFinal);\r
+    \r
+    public void setReadOnly(final boolean isReadOnly);\r
+    \r
+    public GeneratedProperty toInstance(final Type definingType);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/GeneratedTOBuilder.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/GeneratedTOBuilder.java
new file mode 100644 (file)
index 0000000..ff55fe5
--- /dev/null
@@ -0,0 +1,30 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api.type.builder;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+\r
+/**\r
+\r
+ *\r
+ */\r
+public interface GeneratedTOBuilder extends Type {\r
+\r
+    public EnumBuilder addEnumeration(final String name);\r
+\r
+    public GeneratedPropertyBuilder addProperty(final String name);\r
+\r
+    public boolean addEqualsIdentity(final GeneratedPropertyBuilder property);\r
+\r
+    public boolean addHashIdentity(final GeneratedPropertyBuilder property);\r
+\r
+    public boolean addToStringProperty(final GeneratedPropertyBuilder property);\r
+\r
+    public GeneratedTransferObject toInstance();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/GeneratedTypeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/GeneratedTypeBuilder.java
new file mode 100644 (file)
index 0000000..6b21250
--- /dev/null
@@ -0,0 +1,31 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api.type.builder;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.GeneratedType;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+\r
+/**\r
+\r
+ *\r
+ */\r
+public interface GeneratedTypeBuilder extends Type {\r
+\r
+    public Type getParentType();\r
+\r
+    public void addComment(final String comment);\r
+\r
+    public ConstantBuilder addConstant(final Type type, final String name,\r
+            final Object value);\r
+\r
+    public EnumBuilder addEnumeration(final String name);\r
+\r
+    public MethodSignatureBuilder addMethod(final String name);\r
+\r
+    public GeneratedType toInstance();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/MethodSignatureBuilder.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/MethodSignatureBuilder.java
new file mode 100644 (file)
index 0000000..349a342
--- /dev/null
@@ -0,0 +1,23 @@
+/**\r
+\r
+ *\r
+ * March 2013\r
+ *\r
+ * Copyright (c) 2013 by Cisco Systems, Inc.\r
+ * All rights reserved.\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api.type.builder;\r
+\r
+import org.opendaylight.controller.sal.binding.model.api.MethodSignature;\r
+import org.opendaylight.controller.sal.binding.model.api.Type;\r
+\r
+public interface MethodSignatureBuilder {\r
+\r
+    public void addReturnType(final Type returnType);\r
+\r
+    public void addParameter(final Type type, final String name);\r
+\r
+    public void addComment(final String comment);\r
+\r
+    public MethodSignature toInstance(final Type definingType);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/package-info.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/package-info.java
new file mode 100644 (file)
index 0000000..ff2c06e
--- /dev/null
@@ -0,0 +1,9 @@
+/**\r
+\r
+ *\r
+ * March 2013\r
+ *\r
+ * Copyright (c) 2013 by Cisco Systems, Inc.\r
+ * All rights reserved.\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api.type.builder;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/provider/package-info.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/provider/package-info.java
new file mode 100644 (file)
index 0000000..6fcb1a8
--- /dev/null
@@ -0,0 +1,9 @@
+/**\r
+\r
+ *\r
+ * March 2013\r
+ *\r
+ * Copyright (c) 2013 by Cisco Systems, Inc.\r
+ * All rights reserved.\r
+ */\r
+package org.opendaylight.controller.sal.binding.model.api.type.provider;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/pom.xml b/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/pom.xml
new file mode 100644 (file)
index 0000000..dfa23fa
--- /dev/null
@@ -0,0 +1,62 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>binding-generator</artifactId>\r
+    <version>1.0</version>\r
+  </parent>\r
+  <artifactId>code-generator-demo</artifactId>\r
+  \r
+  <dependencies>\r
+      <dependency>\r
+          <groupId>org.antlr</groupId>\r
+          <artifactId>antlr4</artifactId>\r
+          <version>4.0</version>\r
+      </dependency>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>binding-generator-impl</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>yang-model-parser-impl</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>binding-java-api-generator</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+  </dependencies>\r
+  \r
+  <build>\r
+               <plugins>\r
+                       <plugin>\r
+                               <artifactId>maven-assembly-plugin</artifactId>\r
+                               <version>2.4</version>\r
+                               <configuration>\r
+                                       <descriptorRefs>\r
+                                               <descriptorRef>jar-with-dependencies</descriptorRef>\r
+                                       </descriptorRefs>\r
+                                       <archive>\r
+                                               <manifest>\r
+                                                       <mainClass>org.opendaylight.controller.yang.Demo</mainClass>\r
+                                               </manifest>\r
+                                       </archive>\r
+                               </configuration>\r
+                               <executions>\r
+                                       <execution>\r
+                                               <id>make-assembly</id>\r
+                                               <phase>package</phase>\r
+                                               <goals>\r
+                                                       <goal>single</goal>\r
+                                               </goals>\r
+                                       </execution>\r
+                               </executions>\r
+                       </plugin>\r
+\r
+               </plugins>\r
+       </build>\r
+</project>\r
+\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/java/org/opendaylight/controller/Demo.java b/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/java/org/opendaylight/controller/Demo.java
new file mode 100644 (file)
index 0000000..bba11f5
--- /dev/null
@@ -0,0 +1,50 @@
+/**\r
+\r
+ *\r
+ * March 2013\r
+ *\r
+ * Copyright (c) 2013 by Cisco Systems, Inc.\r
+ * All rights reserved.\r
+ */\r
+package org.opendaylight.controller;\r
+\r
+import java.io.File;\r
+import java.util.Map;\r
+\r
+import org.opendaylight.controller.model.parser.builder.YangModelBuilder;\r
+\r
+\r
+\r
+public class Demo {\r
+\r
+       public static void main(String[] args) throws Exception {\r
+\r
+               String yangFilesDir;\r
+               if(args.length > 0) {\r
+                       yangFilesDir = args[0];\r
+               } else {\r
+                       yangFilesDir = "src/main/resources";\r
+               }\r
+\r
+               File resourceDir = new File(yangFilesDir);\r
+               if(!resourceDir.exists()) {\r
+                       throw new IllegalArgumentException("Specified resource directory does not exists: "+ resourceDir.getAbsolutePath());\r
+               }\r
+\r
+               String[] dirList = resourceDir.list();\r
+               String[] absFiles = new String[dirList.length];\r
+\r
+               int i = 0;\r
+               for(String fileName : dirList) {\r
+                       File f = new File(fileName);\r
+                       absFiles[i] = f.getAbsolutePath();\r
+                       i++;\r
+               }\r
+\r
+        YangModelBuilder builder = new YangModelBuilder(absFiles);\r
+        Map<String, org.opendaylight.controller.yang.model.api.Module> builtModules = builder.build();\r
+\r
+        System.out.println("Modules built: "+ builtModules.size());\r
+       }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo-topology.yang b/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo-topology.yang
new file mode 100644 (file)
index 0000000..23552bb
--- /dev/null
@@ -0,0 +1,224 @@
+module demo-topology {
+    yang-version 1;
+    namespace "urn:demo.simple-topology";
+    prefix "tp";
+    import simple-list-demo { prefix "simple"; revision-date 2008-01-01; }
+    import controller-network {prefix "cn";}
+       import mount  {prefix "mnt";}
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "
+        This module contains the definitions of elements that creates network 
+        topology i.e. definition of network nodes and links. This module is
+        not designed to be used solely for network representation. This module
+        SHOULD be used as base module in defining the network topology.
+    ";
+
+    revision "2013-02-08"{
+        reference " WILL BE DEFINED LATER";
+    }
+    
+    
+    
+    
+    
+    deviation /base:system/base:user/base:type {
+         deviate add {
+             default "admin"; // new users are 'admin' by default
+         }
+     }
+     
+    deviation /base:system/base:name-server {
+         deviate replace {
+             max-elements 3;
+         }
+     }
+     
+     deviation "/base:system" {
+         deviate delete {
+             must "daytime or time";
+         }
+     }
+     
+     
+     
+     
+     
+    
+    grouping target {
+       status "current";
+         leaf address {
+             type inet:ip-address;
+             description "Target IP address";
+         }
+         leaf port {
+             type inet:port-number;
+             description "Target port number";
+         }
+     }
+     
+     augment "/cn:network/cn:topologies/cn:topology" {
+        container prefixes {
+            container "prefix" {
+                leaf id {
+                    type string;
+
+                    description "";
+                }
+
+                leaf-list advertising-node-id {
+                    type cn:node-ref;
+
+                    description "";
+                }
+            }
+        }
+        mnt:mountpoint point  {
+               mnt:target-ref target;
+           
+            } 
+    }
+
+     container peer {
+         container destination {
+             uses target;
+         }
+     }
+
+    container topology {
+    
+       leaf ifType {
+             type enumeration {
+                 enum ethernet;
+                 enum atm;
+             }
+         }
+         leaf ifMTU {
+             type uint32;
+         }
+         must "ifType != 'ethernet' or " +
+              "(ifType = 'ethernet' and ifMTU = 1500)" {
+             error-message "An ethernet MTU must be 1500";
+         }
+    
+       presence "test-presence";
+    
+        description "
+            This is the model of abstract topology which contains only Network
+            Nodes and Network Links. Each topology MUST be identified by
+            unique topology-id for reason that the store could contain many
+            topologies.
+        ";
+
+        leaf topology-id {
+            type string;
+            description "
+                It is presumed that datastore will contain many topologies. To
+                distinguish between topologies it is vital to have UNIQUE
+                topology identifier.
+            ";
+        }
+
+        container network-nodes {
+            list network-node {
+               ordered-by system;
+                description "The list of network nodes defined for topology.";
+
+                key "node-id";
+
+                leaf node-id {
+                    type string;
+                    description "The Topology identifier of network-node.";
+                }
+                
+                list network-interface {
+                    key "interface-id";
+                    
+                    leaf interface-id {
+                        type uint8;
+                    }
+                    
+                    leaf interface-address {
+                        type string;
+                    }
+                }
+                
+                container node-attributes {
+                    description "
+                        Additional attributes that can Network Node contains.
+                    ";
+
+                    leaf geo-latitude {
+                        type decimal64 {
+                            fraction-digits 2;
+                        }
+                        config true;
+                    }
+
+                    leaf geo-longitude {
+                        type decimal64 {
+                            fraction-digits 2;
+                        }
+                        config true;
+                    }
+                }
+            }
+        }
+        
+        container network-links {
+            list network-link {
+                description "
+                    The Network Link which is defined by Local (Source) and
+                    Remote (Destination) Network Nodes. Every link MUST be
+                    defined either by identifier and his local and remote
+                    Network Nodes (in real applications it is common that many
+                    links are originated from one node and end up in same
+                    remote node). To ensure that we would always know to
+                    distinguish between links, every link SHOULD have
+                    identifier.
+                ";
+                key "link-id";
+
+                leaf link-id {
+                    type string;
+                    description "";
+                }
+
+                container source {
+                    leaf node-id {
+                        type string;
+                        description "Source node identifier.";
+                    }
+                }
+
+                container destination {
+                    leaf node-id {
+                        type string;
+                        description "Destination node identifier.";
+                    }
+                }
+
+                container link-attributes {
+                    description "Aditional attributes that can Network Link contains.";
+                }
+            }
+        }
+    }
+    
+    rpc activate-software-image {
+         input {
+             leaf image-name {
+                 type string;
+             }
+         }
+         output {
+             leaf status {
+                 type string;
+             }
+         }
+     }
+     
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types1.yang b/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types1.yang
new file mode 100644 (file)
index 0000000..1025298
--- /dev/null
@@ -0,0 +1,80 @@
+module types1 {
+       yang-version 1;
+    namespace "urn:simple.container.demo";
+    prefix "t1";
+    
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+    
+    
+    leaf mybits {
+         type bits {
+             bit disable-nagle {
+                 position 0;
+             }
+             bit auto-sense-speed {
+                 position 1;
+             }
+             bit 10-Mb-only {
+                 position 2;
+             }
+         }
+         default "auto-sense-speed";
+     }
+    
+    container interfaces {
+         list ifEntry {
+             key "ifIndex";
+
+             leaf ifIndex {
+                 type uint32;
+             }
+             leaf ifDescr {
+                 type string;
+             }
+             leaf ifType {
+                 type uint8;
+             }
+             leaf ifMtu {
+                 type int32;
+             }
+         }
+     }
+    
+    
+       container topology {
+               leaf name {
+                       type string;
+               }
+       }
+       
+       
+       
+       
+       
+       
+       
+//     typedef my-string {
+//             type string {
+//                     length "0..4";
+//             pattern "[0-9a-fA-F]*";
+//             }
+//     }
+
+
+//     leaf completed {
+//             type types2:percent;
+//  }
+
+//     leaf testleaf {
+//             type data:my-base-int32-type;
+//     }
+
+//     leaf-list domain-search {
+//             type string;
+//             description "List of domain names to search";
+//     }
+       
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types2.yang b/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types2.yang
new file mode 100644 (file)
index 0000000..a056bdb
--- /dev/null
@@ -0,0 +1,35 @@
+module types2 {
+       yang-version 1;
+    namespace "urn:simple.types.data.demo";
+    prefix "t2";
+    
+    import types1 {
+         prefix "t1";
+     }
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "This is types-data test description";
+
+    revision "2013-02-27" {
+        reference " WILL BE DEFINED LATER";
+    }
+    
+    
+     augment "/t1:interfaces/t1:ifEntry" {
+         when "t1:ifType='ds0'";
+         leaf ds0ChannelNumber {
+             type string;
+         }
+     }
+     
+     typedef my-leaf-ref {
+               type leafref {
+                       path "/t1:topology/t1:name";
+               }
+               description "This type is used for leafs that reference network node instance.";
+       }
+     
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types3.yang b/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types3.yang
new file mode 100644 (file)
index 0000000..0d09259
--- /dev/null
@@ -0,0 +1,35 @@
+module types3 {
+       yang-version 1;
+    namespace "urn:simple.types3.data.demo";
+    prefix "scd";
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "This is types-data test description";
+
+    revision "2013-02-27" {
+        reference " WILL BE DEFINED LATER";
+    }
+    
+    typedef my-decimal {
+         type decimal64 {
+               fraction-digits 2;
+         }
+    }
+
+       typedef my-base-int32-type {
+         type int32 {
+               range "0..32";
+         }
+    }
+    
+    typedef percent {
+         type uint8 {
+             range "0 .. 100";
+         }
+         description "Percentage";
+       }
+       
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/test-topology.yang b/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/test-topology.yang
new file mode 100644 (file)
index 0000000..76582c7
--- /dev/null
@@ -0,0 +1,123 @@
+// vi: set smarttab sw=4 tabstop=4:
+module abstract-topology {
+       yang-version 1;
+    namespace "pre:simple.test.demo";
+    prefix "tp";
+
+       import ietf-inet-types { prefix "inet"; }
+    import abstract-prefixes { prefix "abs-pref"; }
+    
+       organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "
+               This module contains the definitions of elements that creates network 
+               topology i.e. definition of network nodes and links. This module is
+               not designed to be used solely for network representation. This module
+               SHOULD be used as base module in defining the network topology.
+       ";
+    
+    revision "2012-02-08" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    typedef topology-id-ref {
+       type leafref {
+               path "/tp:topology/tp:topology-id";
+       }
+       description "This type is used for leafs that reference topology identifier instance.";
+    }
+
+       typedef network-node-id-ref {
+               type leafref {
+                       path "/tp:topology/tp:network-nodes/tp:network-node/tp:node-id";
+               }
+               description "This type is used for leafs that reference network node instance.";
+       }
+
+       typedef link-id-ref {
+               type leafref {
+                       path "/tp:topology/tp:network-links/tp:network-link/tp:link-id";
+               }
+               description "This type is used for leafs that reference network link instance.";
+       }
+
+       container topology {
+        description "
+                       This is the model of abstract topology which contains only Network
+                       Nodes and Network Links. Each topology MUST be identified by
+                       unique topology-id for reason that the store could contain many
+                       topologies.
+               ";
+
+        leaf topology-id {
+            type inet:uri;
+            description "
+                               It is presumed that datastore will contain many topologies. To
+                               distinguish between topologies it is vital to have UNIQUE
+                               topology identifier.
+                       ";
+        }
+
+        container network-nodes {
+               list network-node {
+                   description "The list of network nodes defined for topology.";
+
+                       key "node-id";
+
+                       leaf node-id {
+                               type inet:uri;
+                               description "The Topology identifier of network-node.";
+                       }
+
+                   container attributes {
+                                       description "
+                                               Additional attributes that can Network Node contains.
+                                       ";
+                               }
+               }
+        }
+        
+        container network-links {
+               list network-link {
+                   description "
+                                       The Network Link which is defined by Local (Source) and
+                                       Remote (Destination) Network Nodes. Every link MUST be
+                                       defined either by identifier and his local and remote
+                                       Network Nodes (in real applications it is common that many
+                                       links are originated from one node and end up in same
+                                       remote node). To ensure that we would always know to
+                                       distinguish between links, every link SHOULD have
+                                       identifier.
+                               ";
+                       key "link-id";
+
+                       leaf link-id {
+                               type inet:uri;
+                               description "";
+                       }
+
+                   container source {
+                                       leaf node-id {
+                                               type node-id-ref;
+                                               description "Source node identifier.";
+                                       }
+                               }
+
+                               container destination {
+                                       leaf node-id {
+                                               type node-id-ref;
+                                               description "Destination node identifier.";
+                                       }
+                               }
+
+                               container attributes {
+                                       description "Aditional attributes that can Network Link contains.";
+                               }
+                   }
+        }
+    }
+
+    //TODO: add base operations
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/pom.xml b/opendaylight/sal/yang-prototype/code-generator/pom.xml
new file mode 100644 (file)
index 0000000..add2241
--- /dev/null
@@ -0,0 +1,96 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>binding-generator</artifactId>\r
+    <version>1.0</version>\r
+    <packaging>pom</packaging>\r
+    <name>binding-generator</name>\r
+    \r
+    <properties>\r
+               <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\r
+       </properties>\r
+  \r
+    <modules>\r
+       <module>../yang</module>\r
+       <module>../sal/sal-schema-repository-api</module>\r
+        <module>code-generator-demo</module>\r
+        <module>yang-model-parser-api</module>\r
+        <module>yang-model-parser-impl</module>\r
+        <module>binding-model-api</module>\r
+        <module>binding-generator-api</module>\r
+        <module>binding-generator-spi</module>\r
+        <module>binding-generator-util</module>\r
+        <module>binding-generator-impl</module>\r
+        <module>binding-java-api-generator</module>\r
+    </modules>\r
+    <dependencies>\r
+\r
+        <dependency>\r
+            <groupId>junit</groupId>\r
+            <artifactId>junit</artifactId>\r
+            <version>4.10</version>\r
+            <scope>test</scope>\r
+            <optional>true</optional>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.slf4j</groupId>\r
+            <artifactId>slf4j-api</artifactId>\r
+            <version>1.7.2</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.slf4j</groupId>\r
+            <artifactId>slf4j-simple</artifactId>\r
+            <version>1.7.2</version>\r
+        </dependency>\r
+    </dependencies>\r
+    <build>\r
+        <plugins>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-compiler-plugin</artifactId>\r
+                <version>2.0</version>\r
+                <inherited>true</inherited>\r
+                <configuration>\r
+                    <source>1.6</source>\r
+                    <target>1.6</target>\r
+                </configuration>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-javadoc-plugin</artifactId>\r
+                <version>2.8.1</version>\r
+                <configuration>\r
+                    <stylesheet>maven</stylesheet>\r
+                </configuration>\r
+                <executions>\r
+                    <execution>\r
+                        <goals>\r
+                            <goal>aggregate</goal>\r
+                        </goals>\r
+                        <phase>site</phase>\r
+                    </execution>\r
+                </executions>\r
+            </plugin>\r
+        </plugins>\r
+    </build>\r
+    <reporting>\r
+        <plugins>\r
+            <plugin>\r
+                <groupId>org.codehaus.mojo</groupId>\r
+                <artifactId>findbugs-maven-plugin</artifactId>\r
+                <version>2.4.0</version>\r
+                <configuration>\r
+                    <effort>Max</effort>\r
+                    <threshold>Low</threshold>\r
+                    <goal>site</goal>\r
+                </configuration>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.codehaus.mojo</groupId>\r
+                <artifactId>jdepend-maven-plugin</artifactId>\r
+                <version>2.0-beta-2</version>\r
+            </plugin>\r
+        </plugins>\r
+    </reporting>\r
+</project>\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/pom.xml b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/pom.xml
new file mode 100644 (file)
index 0000000..184abf0
--- /dev/null
@@ -0,0 +1,54 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>binding-generator</artifactId>\r
+    <version>1.0</version>\r
+  </parent>\r
+  <artifactId>yang-model-parser-impl</artifactId>\r
+  \r
+  <dependencies>\r
+         <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>yang-common</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+         <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>yang-model-api</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>yang-model-util</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>binding-model-api</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+      \r
+      <dependency>\r
+          <groupId>org.antlr</groupId>\r
+          <artifactId>antlr4</artifactId>\r
+          <version>4.0</version>\r
+      </dependency>\r
+      <dependency>\r
+          <groupId>org.slf4j</groupId>\r
+          <artifactId>slf4j-api</artifactId>\r
+          <version>1.7.2</version>\r
+      </dependency>\r
+      <dependency>\r
+          <groupId>org.slf4j</groupId>\r
+          <artifactId>slf4j-simple</artifactId>\r
+          <version>1.7.2</version>\r
+      </dependency>\r
+      <dependency>\r
+          <groupId>org.mockito</groupId>\r
+          <artifactId>mockito-all</artifactId>\r
+          <version>1.8.4</version>\r
+      </dependency>\r
+  </dependencies>\r
+  \r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangLexer.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangLexer.java
new file mode 100644 (file)
index 0000000..0fbfc1c
--- /dev/null
@@ -0,0 +1,1379 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.antlrv4.code.gen;\r
+\r
+import org.antlr.v4.runtime.CharStream;\r
+import org.antlr.v4.runtime.Lexer;\r
+import org.antlr.v4.runtime.RuleContext;\r
+import org.antlr.v4.runtime.atn.ATN;\r
+import org.antlr.v4.runtime.atn.ATNSimulator;\r
+import org.antlr.v4.runtime.atn.LexerATNSimulator;\r
+import org.antlr.v4.runtime.atn.PredictionContextCache;\r
+import org.antlr.v4.runtime.dfa.DFA;\r
+\r
+@SuppressWarnings({ "all", "warnings", "unchecked", "unused", "cast" })\r
+public class YangLexer extends Lexer {\r
+    protected static final DFA[] _decisionToDFA;\r
+    protected static final PredictionContextCache _sharedContextCache = new PredictionContextCache();\r
+    public static final int SEMICOLON = 1, LEFT_BRACE = 2, RIGHT_BRACE = 3,\r
+            PLUS = 4, WS = 5, LINE_COMMENT = 6, BLOCK_COMMENT = 7,\r
+            YIN_ELEMENT_KEYWORD = 8, YANG_VERSION_KEYWORD = 9,\r
+            WHEN_KEYWORD = 10, VALUE_KEYWORD = 11, USES_KEYWORD = 12,\r
+            UNITS_KEYWORD = 13, UNIQUE_KEYWORD = 14, TYPEDEF_KEYWORD = 15,\r
+            TYPE_KEYWORD = 16, SUBMODULE_KEYWORD = 17, STATUS_KEYWORD = 18,\r
+            RPC_KEYWORD = 19, REVISION_DATE_KEYWORD = 20,\r
+            REVISION_KEYWORD = 21, REQUIRE_INSTANCE_KEYWORD = 22,\r
+            REFINE_KEYWORD = 23, REFERENCE_KEYWORD = 24, RANGE_KEYWORD = 25,\r
+            PRESENCE_KEYWORD = 26, PREFIX_KEYWORD = 27, POSITION_KEYWORD = 28,\r
+            PATTERN_KEYWORD = 29, PATH_KEYWORD = 30, OUTPUT_KEYWORD = 31,\r
+            ORGANIZATION_KEYWORD = 32, ORDERED_BY_KEYWORD = 33,\r
+            NOTIFICATION_KEYWORD = 34, NAMESPACE_KEYWORD = 35,\r
+            MUST_KEYWORD = 36, MODULE_KEYWORD = 37, MIN_ELEMENTS_KEYWORD = 38,\r
+            MAX_ELEMENTS_KEYWORD = 39, MANDATORY_KEYWORD = 40,\r
+            LIST_KEYWORD = 41, LENGTH_KEYWORD = 42, LEAF_LIST_KEYWORD = 43,\r
+            LEAF_KEYWORD = 44, KEY_KEYWORD = 45, INPUT_KEYWORD = 46,\r
+            INCLUDE_KEYWORD = 47, IMPORT_KEYWORD = 48, IF_FEATURE_KEYWORD = 49,\r
+            IDENTITY_KEYWORD = 50, GROUPING_KEYWORD = 51,\r
+            FRACTION_DIGITS_KEYWORD = 52, FEATURE_KEYWORD = 53,\r
+            DEVIATE_KEYWORD = 54, DEVIATION_KEYWORD = 55,\r
+            EXTENSION_KEYWORD = 56, ERROR_MESSAGE_KEYWORD = 57,\r
+            ERROR_APP_TAG_KEYWORD = 58, ENUM_KEYWORD = 59,\r
+            DESCRIPTION_KEYWORD = 60, DEFAULT_KEYWORD = 61,\r
+            CONTAINER_KEYWORD = 62, CONTACT_KEYWORD = 63, CONFIG_KEYWORD = 64,\r
+            CHOICE_KEYWORD = 65, CASE_KEYWORD = 66, BIT_KEYWORD = 67,\r
+            BELONGS_TO_KEYWORD = 68, BASE_KEYWORD = 69, AUGMENT_KEYWORD = 70,\r
+            ARGUMENT_KEYWORD = 71, ANYXML_KEYWORD = 72, IDENTIFIER = 73,\r
+            STRING = 74, S = 75;\r
+    public static final int VALUE_MODE = 1;\r
+    public static String[] modeNames = { "DEFAULT_MODE", "VALUE_MODE" };\r
+\r
+    public static final String[] tokenNames = { "<INVALID>", "SEMICOLON",\r
+            "LEFT_BRACE", "'}'", "'+'", "WS", "LINE_COMMENT", "BLOCK_COMMENT",\r
+            "'yin-element'", "'yang-version'", "'when'", "'value'", "'uses'",\r
+            "'units'", "'unique'", "'typedef'", "'type'", "'submodule'",\r
+            "'status'", "'rpc'", "'revision-date'", "'revision'",\r
+            "'require-instance'", "'refine'", "'reference'", "'range'",\r
+            "'presence'", "'prefix'", "'position'", "'pattern'", "'path'",\r
+            "'output'", "'organization'", "'ordered-by'", "'notification'",\r
+            "'namespace'", "'must'", "'module'", "'min-elements'",\r
+            "'max-elements'", "'mandatory'", "'list'", "'length'",\r
+            "'leaf-list'", "'leaf'", "'key'", "'input'", "'include'",\r
+            "'import'", "'if-feature'", "'identity'", "'grouping'",\r
+            "'fraction-digits'", "'feature'", "'deviate'", "'deviation'",\r
+            "'extension'", "'error-message'", "'error-app-tag'", "'enum'",\r
+            "'description'", "'default'", "'container'", "'contact'",\r
+            "'config'", "'choice'", "'case'", "'bit'", "'belongs-to'",\r
+            "'base'", "'augment'", "'argument'", "'anyxml'", "IDENTIFIER",\r
+            "STRING", "S" };\r
+    public static final String[] ruleNames = { "PLUS", "WS", "LINE_COMMENT",\r
+            "BLOCK_COMMENT", "SEMICOLON", "LEFT_BRACE", "RIGHT_BRACE",\r
+            "YIN_ELEMENT_KEYWORD", "YANG_VERSION_KEYWORD", "WHEN_KEYWORD",\r
+            "VALUE_KEYWORD", "USES_KEYWORD", "UNITS_KEYWORD", "UNIQUE_KEYWORD",\r
+            "TYPEDEF_KEYWORD", "TYPE_KEYWORD", "SUBMODULE_KEYWORD",\r
+            "STATUS_KEYWORD", "RPC_KEYWORD", "REVISION_DATE_KEYWORD",\r
+            "REVISION_KEYWORD", "REQUIRE_INSTANCE_KEYWORD", "REFINE_KEYWORD",\r
+            "REFERENCE_KEYWORD", "RANGE_KEYWORD", "PRESENCE_KEYWORD",\r
+            "PREFIX_KEYWORD", "POSITION_KEYWORD", "PATTERN_KEYWORD",\r
+            "PATH_KEYWORD", "OUTPUT_KEYWORD", "ORGANIZATION_KEYWORD",\r
+            "ORDERED_BY_KEYWORD", "NOTIFICATION_KEYWORD", "NAMESPACE_KEYWORD",\r
+            "MUST_KEYWORD", "MODULE_KEYWORD", "MIN_ELEMENTS_KEYWORD",\r
+            "MAX_ELEMENTS_KEYWORD", "MANDATORY_KEYWORD", "LIST_KEYWORD",\r
+            "LENGTH_KEYWORD", "LEAF_LIST_KEYWORD", "LEAF_KEYWORD",\r
+            "KEY_KEYWORD", "INPUT_KEYWORD", "INCLUDE_KEYWORD",\r
+            "IMPORT_KEYWORD", "IF_FEATURE_KEYWORD", "IDENTITY_KEYWORD",\r
+            "GROUPING_KEYWORD", "FRACTION_DIGITS_KEYWORD", "FEATURE_KEYWORD",\r
+            "DEVIATE_KEYWORD", "DEVIATION_KEYWORD", "EXTENSION_KEYWORD",\r
+            "ERROR_MESSAGE_KEYWORD", "ERROR_APP_TAG_KEYWORD", "ENUM_KEYWORD",\r
+            "DESCRIPTION_KEYWORD", "DEFAULT_KEYWORD", "CONTAINER_KEYWORD",\r
+            "CONTACT_KEYWORD", "CONFIG_KEYWORD", "CHOICE_KEYWORD",\r
+            "CASE_KEYWORD", "BIT_KEYWORD", "BELONGS_TO_KEYWORD",\r
+            "BASE_KEYWORD", "AUGMENT_KEYWORD", "ARGUMENT_KEYWORD",\r
+            "ANYXML_KEYWORD", "IDENTIFIER", "ESC", "UNICODE", "HEX",\r
+            "END_IDENTIFIER_SEMICOLON", "END_IDENTIFIER_LEFT_BRACE",\r
+            "SUB_STRING", "STRING", "S" };\r
+\r
+    public YangLexer(CharStream input) {\r
+        super(input);\r
+        _interp = new LexerATNSimulator(this, _ATN, _decisionToDFA,\r
+                _sharedContextCache);\r
+    }\r
+\r
+    @Override\r
+    public String getGrammarFileName() {\r
+        return "yangLexer.g4";\r
+    }\r
+\r
+    @Override\r
+    public String[] getTokenNames() {\r
+        return tokenNames;\r
+    }\r
+\r
+    @Override\r
+    public String[] getRuleNames() {\r
+        return ruleNames;\r
+    }\r
+\r
+    @Override\r
+    public String[] getModeNames() {\r
+        return modeNames;\r
+    }\r
+\r
+    @Override\r
+    public ATN getATN() {\r
+        return _ATN;\r
+    }\r
+\r
+    @Override\r
+    public void action(RuleContext _localctx, int ruleIndex, int actionIndex) {\r
+        switch (ruleIndex) {\r
+        case 0:\r
+            PLUS_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 1:\r
+            WS_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 2:\r
+            LINE_COMMENT_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 3:\r
+            BLOCK_COMMENT_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 4:\r
+            SEMICOLON_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 5:\r
+            LEFT_BRACE_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 6:\r
+            RIGHT_BRACE_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 7:\r
+            YIN_ELEMENT_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 8:\r
+            YANG_VERSION_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 9:\r
+            WHEN_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 10:\r
+            VALUE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 11:\r
+            USES_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 12:\r
+            UNITS_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 13:\r
+            UNIQUE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 14:\r
+            TYPEDEF_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 15:\r
+            TYPE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 16:\r
+            SUBMODULE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 17:\r
+            STATUS_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 18:\r
+            RPC_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 19:\r
+            REVISION_DATE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 20:\r
+            REVISION_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 21:\r
+            REQUIRE_INSTANCE_KEYWORD_action((RuleContext) _localctx,\r
+                    actionIndex);\r
+            break;\r
+\r
+        case 22:\r
+            REFINE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 23:\r
+            REFERENCE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 24:\r
+            RANGE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 25:\r
+            PRESENCE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 26:\r
+            PREFIX_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 27:\r
+            POSITION_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 28:\r
+            PATTERN_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 29:\r
+            PATH_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 31:\r
+            ORGANIZATION_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 32:\r
+            ORDERED_BY_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 33:\r
+            NOTIFICATION_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 34:\r
+            NAMESPACE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 35:\r
+            MUST_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 36:\r
+            MODULE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 37:\r
+            MIN_ELEMENTS_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 38:\r
+            MAX_ELEMENTS_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 39:\r
+            MANDATORY_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 40:\r
+            LIST_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 41:\r
+            LENGTH_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 42:\r
+            LEAF_LIST_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 43:\r
+            LEAF_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 44:\r
+            KEY_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 46:\r
+            INCLUDE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 47:\r
+            IMPORT_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 48:\r
+            IF_FEATURE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 49:\r
+            IDENTITY_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 50:\r
+            GROUPING_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 51:\r
+            FRACTION_DIGITS_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 52:\r
+            FEATURE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 53:\r
+            DEVIATE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 54:\r
+            DEVIATION_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 55:\r
+            EXTENSION_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 56:\r
+            ERROR_MESSAGE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 57:\r
+            ERROR_APP_TAG_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 58:\r
+            ENUM_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 59:\r
+            DESCRIPTION_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 60:\r
+            DEFAULT_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 61:\r
+            CONTAINER_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 62:\r
+            CONTACT_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 63:\r
+            CONFIG_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 64:\r
+            CHOICE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 65:\r
+            CASE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 66:\r
+            BIT_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 67:\r
+            BELONGS_TO_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 68:\r
+            BASE_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 69:\r
+            AUGMENT_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 70:\r
+            ARGUMENT_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 71:\r
+            ANYXML_KEYWORD_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 72:\r
+            IDENTIFIER_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 76:\r
+            END_IDENTIFIER_SEMICOLON_action((RuleContext) _localctx,\r
+                    actionIndex);\r
+            break;\r
+\r
+        case 77:\r
+            END_IDENTIFIER_LEFT_BRACE_action((RuleContext) _localctx,\r
+                    actionIndex);\r
+            break;\r
+\r
+        case 79:\r
+            STRING_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+\r
+        case 80:\r
+            S_action((RuleContext) _localctx, actionIndex);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void CHOICE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 62:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void YIN_ELEMENT_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 7:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void WHEN_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 9:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void REVISION_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 20:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void DESCRIPTION_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 57:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void NAMESPACE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 33:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void MODULE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 35:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void REFERENCE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 23:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void CONTACT_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 60:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void LEAF_LIST_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 41:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void REVISION_DATE_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 19:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void BELONGS_TO_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 65:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void LEAF_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 42:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void PREFIX_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 26:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void DEFAULT_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 58:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void PRESENCE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 25:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void ARGUMENT_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 68:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void NOTIFICATION_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 32:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void RPC_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 18:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void CONTAINER_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 59:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void DEVIATION_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 52:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void STATUS_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 17:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void IDENTITY_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 47:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void IDENTIFIER_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 70:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void REFINE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 22:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void USES_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 11:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void VALUE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 10:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void IMPORT_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 45:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void BLOCK_COMMENT_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 3:\r
+            skip();\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void PLUS_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 0:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void PATTERN_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 28:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void IF_FEATURE_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 46:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void LENGTH_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 40:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void FEATURE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 50:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void REQUIRE_INSTANCE_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 21:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void ORGANIZATION_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 30:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void UNIQUE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 13:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void SUBMODULE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 16:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void TYPE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 15:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void RIGHT_BRACE_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 6:\r
+            _type = RIGHT_BRACE;\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void ERROR_MESSAGE_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 54:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void LINE_COMMENT_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 2:\r
+            skip();\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void END_IDENTIFIER_LEFT_BRACE_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 72:\r
+            _type = LEFT_BRACE;\r
+            popMode();\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void MIN_ELEMENTS_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 36:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void MUST_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 34:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void SEMICOLON_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 4:\r
+            _type = SEMICOLON;\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void POSITION_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 27:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void PATH_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 29:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void S_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 74:\r
+            skip();\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void KEY_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 43:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void EXTENSION_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 53:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void WS_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 1:\r
+            skip();\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void MANDATORY_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 38:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void ORDERED_BY_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 31:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void ERROR_APP_TAG_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 55:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void INCLUDE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 44:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void END_IDENTIFIER_SEMICOLON_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 71:\r
+            _type = SEMICOLON;\r
+            popMode();\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void ANYXML_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 69:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void AUGMENT_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 67:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void DEVIATE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 51:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void LEFT_BRACE_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 5:\r
+            _type = LEFT_BRACE;\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void YANG_VERSION_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 8:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void LIST_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 39:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void TYPEDEF_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 14:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void MAX_ELEMENTS_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 37:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void ENUM_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 56:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void CASE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 63:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void UNITS_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 12:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void GROUPING_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 48:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void BASE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 66:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void RANGE_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 24:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void FRACTION_DIGITS_KEYWORD_action(RuleContext _localctx,\r
+            int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 49:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void CONFIG_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 61:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void BIT_KEYWORD_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 64:\r
+            pushMode(VALUE_MODE);\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void STRING_action(RuleContext _localctx, int actionIndex) {\r
+        switch (actionIndex) {\r
+        case 73:\r
+            popMode();\r
+            break;\r
+        }\r
+    }\r
+\r
+    public static final String _serializedATN = "\2\4M\u03bf\b\1\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4"\r
+            + "\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4"\r
+            + "\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4"\r
+            + "\27\t\27\4\30\t\30\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4"\r
+            + "\36\t\36\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'"\r
+            + "\4(\t(\4)\t)\4*\t*\4+\t+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4"\r
+            + "\62\t\62\4\63\t\63\4\64\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t"\r
+            + "9\4:\t:\4;\t;\4<\t<\4=\t=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4"\r
+            + "E\tE\4F\tF\4G\tG\4H\tH\4I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\t"\r
+            + "P\4Q\tQ\4R\tR\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\7\4\u00b3"\r
+            + "\n\4\f\4\16\4\u00b6\13\4\3\4\3\4\3\5\3\5\3\5\3\5\7\5\u00be\n\5\f\5\16"\r
+            + "\5\u00c1\13\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\b"\r
+            + "\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3"\r
+            + "\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3"\r
+            + "\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3"\r
+            + "\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17"\r
+            + "\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20"\r
+            + "\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22"\r
+            + "\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23"\r
+            + "\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\25"\r
+            + "\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26"\r
+            + "\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\27"\r
+            + "\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30"\r
+            + "\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31"\r
+            + "\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\33"\r
+            + "\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34"\r
+            + "\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35"\r
+            + "\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\37\3\37"\r
+            + "\3\37\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3 \3 \3 \3!\3!\3!\3!\3!\3!\3!\3"\r
+            + "!\3!\3!\3!\3!\3!\3!\3!\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\""\r
+            + "\3\"\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3$\3$\3$\3$\3$\3$\3"\r
+            + "$\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3&\3&\3&\3&\3\'\3"\r
+            + "\'\3\'\3\'\3\'\3\'\3\'\3\'\3\'\3\'\3\'\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3("\r
+            + "\3(\3(\3(\3(\3(\3(\3(\3(\3(\3(\3)\3)\3)\3)\3)\3)\3)\3)\3)\3)\3)\3)\3*"\r
+            + "\3*\3*\3*\3*\3*\3*\3+\3+\3+\3+\3+\3+\3+\3+\3+\3,\3,\3,\3,\3,\3,\3,\3,"\r
+            + "\3,\3,\3,\3,\3-\3-\3-\3-\3-\3-\3-\3.\3.\3.\3.\3.\3.\3/\3/\3/\3/\3/\3/"\r
+            + "\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\61\3\61\3\61\3\61"\r
+            + "\3\61\3\61\3\61\3\61\3\61\3\62\3\62\3\62\3\62\3\62\3\62\3\62\3\62\3\62"\r
+            + "\3\62\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3\63\3\63\3\63\3\63\3\63\3\63"\r
+            + "\3\63\3\64\3\64\3\64\3\64\3\64\3\64\3\64\3\64\3\64\3\64\3\64\3\65\3\65"\r
+            + "\3\65\3\65\3\65\3\65\3\65\3\65\3\65\3\65\3\65\3\65\3\65\3\65\3\65\3\65"\r
+            + "\3\65\3\65\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\67\3\67"\r
+            + "\3\67\3\67\3\67\3\67\3\67\3\67\3\67\3\67\38\38\38\38\38\38\38\38\38\3"\r
+            + "8\38\38\39\39\39\39\39\39\39\39\39\39\39\39\3:\3:\3:\3:\3:\3:\3:\3:\3"\r
+            + ":\3:\3:\3:\3:\3:\3:\3:\3;\3;\3;\3;\3;\3;\3;\3;\3;\3;\3;\3;\3;\3;\3;\3"\r
+            + ";\3<\3<\3<\3<\3<\3<\3<\3=\3=\3=\3=\3=\3=\3=\3=\3=\3=\3=\3=\3=\3=\3>\3"\r
+            + ">\3>\3>\3>\3>\3>\3>\3>\3>\3?\3?\3?\3?\3?\3?\3?\3?\3?\3?\3?\3?\3@\3@\3"\r
+            + "@\3@\3@\3@\3@\3@\3@\3@\3A\3A\3A\3A\3A\3A\3A\3A\3A\3B\3B\3B\3B\3B\3B\3"\r
+            + "B\3B\3B\3C\3C\3C\3C\3C\3C\3C\3D\3D\3D\3D\3D\3D\3E\3E\3E\3E\3E\3E\3E\3"\r
+            + "E\3E\3E\3E\3E\3E\3F\3F\3F\3F\3F\3F\3F\3G\3G\3G\3G\3G\3G\3G\3G\3G\3G\3"\r
+            + "H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3I\3I\3I\3I\3J\3J\7J\u0382"\r
+            + "\nJ\fJ\16J\u0385\13J\3J\3J\3K\3K\3K\5K\u038c\nK\3L\3L\3L\3L\3L\3L\3M\3"\r
+            + "M\3N\3N\3N\3N\3O\3O\3O\3O\3P\3P\3P\7P\u03a1\nP\fP\16P\u03a4\13P\3P\3P"\r
+            + "\3P\3P\7P\u03aa\nP\fP\16P\u03ad\13P\3P\5P\u03b0\nP\3Q\3Q\6Q\u03b4\nQ\r"\r
+            + "Q\16Q\u03b5\5Q\u03b8\nQ\3Q\3Q\3R\3R\3R\3R\2S\4\6\2\6\7\3\b\b\4\n\t\5\f"\r
+            + "\3\6\16\4\7\20\5\b\22\n\t\24\13\n\26\f\13\30\r\f\32\16\r\34\17\16\36\20"\r
+            + "\17 \21\20\"\22\21$\23\22&\24\23(\25\24*\26\25,\27\26.\30\27\60\31\30"\r
+            + "\62\32\31\64\33\32\66\34\338\35\34:\36\35<\37\36> \37@!\1B\" D#!F$\"H"\r
+            + "%#J&$L\'%N(&P)\'R*(T+)V,*X-+Z.,\\/-^\60\1`\61.b\62/d\63\60f\64\61h\65"\r
+            + "\62j\66\63l\67\64n8\65p9\66r:\67t;8v<9x=:z>;|?<~@=\u0080A>\u0082B?\u0084"\r
+            + "C@\u0086DA\u0088EB\u008aFC\u008cGD\u008eHE\u0090IF\u0092JG\u0094KH\u0096"\r
+            + "\2\1\u0098\2\1\u009a\2\1\u009c\2I\u009e\2J\u00a0\2\1\u00a2LK\u00a4ML\4"\r
+            + "\2\3\r\5\13\f\17\17\"\"\4\f\f\17\17\2\6/;C\\aac|\7/\60\62<C\\aac|\n$$"\r
+            + "\61\61^^ddhhppttvv\5\62;CHch\3$$\3))\7\f\f\17\17\"\"==}}\5\13\f\17\17"\r
+            + "\"\"\u03c4\2\4\3\2\2\2\2\6\3\2\2\2\2\b\3\2\2\2\2\n\3\2\2\2\2\f\3\2\2\2"\r
+            + "\2\16\3\2\2\2\2\20\3\2\2\2\2\22\3\2\2\2\2\24\3\2\2\2\2\26\3\2\2\2\2\30"\r
+            + "\3\2\2\2\2\32\3\2\2\2\2\34\3\2\2\2\2\36\3\2\2\2\2 \3\2\2\2\2\"\3\2\2\2"\r
+            + "\2$\3\2\2\2\2&\3\2\2\2\2(\3\2\2\2\2*\3\2\2\2\2,\3\2\2\2\2.\3\2\2\2\2\60"\r
+            + "\3\2\2\2\2\62\3\2\2\2\2\64\3\2\2\2\2\66\3\2\2\2\28\3\2\2\2\2:\3\2\2\2"\r
+            + "\2<\3\2\2\2\2>\3\2\2\2\2@\3\2\2\2\2B\3\2\2\2\2D\3\2\2\2\2F\3\2\2\2\2H"\r
+            + "\3\2\2\2\2J\3\2\2\2\2L\3\2\2\2\2N\3\2\2\2\2P\3\2\2\2\2R\3\2\2\2\2T\3\2"\r
+            + "\2\2\2V\3\2\2\2\2X\3\2\2\2\2Z\3\2\2\2\2\\\3\2\2\2\2^\3\2\2\2\2`\3\2\2"\r
+            + "\2\2b\3\2\2\2\2d\3\2\2\2\2f\3\2\2\2\2h\3\2\2\2\2j\3\2\2\2\2l\3\2\2\2\2"\r
+            + "n\3\2\2\2\2p\3\2\2\2\2r\3\2\2\2\2t\3\2\2\2\2v\3\2\2\2\2x\3\2\2\2\2z\3"\r
+            + "\2\2\2\2|\3\2\2\2\2~\3\2\2\2\2\u0080\3\2\2\2\2\u0082\3\2\2\2\2\u0084\3"\r
+            + "\2\2\2\2\u0086\3\2\2\2\2\u0088\3\2\2\2\2\u008a\3\2\2\2\2\u008c\3\2\2\2"\r
+            + "\2\u008e\3\2\2\2\2\u0090\3\2\2\2\2\u0092\3\2\2\2\2\u0094\3\2\2\2\3\u009c"\r
+            + "\3\2\2\2\3\u009e\3\2\2\2\3\u00a2\3\2\2\2\3\u00a4\3\2\2\2\4\u00a6\3\2\2"\r
+            + "\2\6\u00aa\3\2\2\2\b\u00ae\3\2\2\2\n\u00b9\3\2\2\2\f\u00c7\3\2\2\2\16"\r
+            + "\u00cb\3\2\2\2\20\u00cf\3\2\2\2\22\u00d3\3\2\2\2\24\u00e1\3\2\2\2\26\u00f0"\r
+            + "\3\2\2\2\30\u00f7\3\2\2\2\32\u00ff\3\2\2\2\34\u0106\3\2\2\2\36\u010e\3"\r
+            + "\2\2\2 \u0117\3\2\2\2\"\u0121\3\2\2\2$\u0128\3\2\2\2&\u0134\3\2\2\2(\u013d"\r
+            + "\3\2\2\2*\u0143\3\2\2\2,\u0153\3\2\2\2.\u015e\3\2\2\2\60\u0171\3\2\2\2"\r
+            + "\62\u017a\3\2\2\2\64\u0186\3\2\2\2\66\u018e\3\2\2\28\u0199\3\2\2\2:\u01a2"\r
+            + "\3\2\2\2<\u01ad\3\2\2\2>\u01b7\3\2\2\2@\u01be\3\2\2\2B\u01c5\3\2\2\2D"\r
+            + "\u01d4\3\2\2\2F\u01e1\3\2\2\2H\u01f0\3\2\2\2J\u01fc\3\2\2\2L\u0203\3\2"\r
+            + "\2\2N\u020c\3\2\2\2P\u021b\3\2\2\2R\u022a\3\2\2\2T\u0236\3\2\2\2V\u023d"\r
+            + "\3\2\2\2X\u0246\3\2\2\2Z\u0252\3\2\2\2\\\u0259\3\2\2\2^\u025f\3\2\2\2"\r
+            + "`\u0265\3\2\2\2b\u026f\3\2\2\2d\u0278\3\2\2\2f\u0285\3\2\2\2h\u0290\3"\r
+            + "\2\2\2j\u029b\3\2\2\2l\u02ad\3\2\2\2n\u02b7\3\2\2\2p\u02c1\3\2\2\2r\u02cd"\r
+            + "\3\2\2\2t\u02d9\3\2\2\2v\u02e9\3\2\2\2x\u02f9\3\2\2\2z\u0300\3\2\2\2|"\r
+            + "\u030e\3\2\2\2~\u0318\3\2\2\2\u0080\u0324\3\2\2\2\u0082\u032e\3\2\2\2"\r
+            + "\u0084\u0337\3\2\2\2\u0086\u0340\3\2\2\2\u0088\u0347\3\2\2\2\u008a\u034d"\r
+            + "\3\2\2\2\u008c\u035a\3\2\2\2\u008e\u0361\3\2\2\2\u0090\u036b\3\2\2\2\u0092"\r
+            + "\u0376\3\2\2\2\u0094\u037f\3\2\2\2\u0096\u0388\3\2\2\2\u0098\u038d\3\2"\r
+            + "\2\2\u009a\u0393\3\2\2\2\u009c\u0395\3\2\2\2\u009e\u0399\3\2\2\2\u00a0"\r
+            + "\u03af\3\2\2\2\u00a2\u03b7\3\2\2\2\u00a4\u03bb\3\2\2\2\u00a6\u00a7\7-"\r
+            + "\2\2\u00a7\u00a8\3\2\2\2\u00a8\u00a9\b\2\2\2\u00a9\5\3\2\2\2\u00aa\u00ab"\r
+            + "\t\2\2\2\u00ab\u00ac\3\2\2\2\u00ac\u00ad\b\3\3\2\u00ad\7\3\2\2\2\u00ae"\r
+            + "\u00af\7\61\2\2\u00af\u00b0\7\61\2\2\u00b0\u00b4\3\2\2\2\u00b1\u00b3\n"\r
+            + "\3\2\2\u00b2\u00b1\3\2\2\2\u00b3\u00b6\3\2\2\2\u00b4\u00b2\3\2\2\2\u00b4"\r
+            + "\u00b5\3\2\2\2\u00b5\u00b7\3\2\2\2\u00b6\u00b4\3\2\2\2\u00b7\u00b8\b\4"\r
+            + "\4\2\u00b8\t\3\2\2\2\u00b9\u00ba\7\61\2\2\u00ba\u00bb\7,\2\2\u00bb\u00bf"\r
+            + "\3\2\2\2\u00bc\u00be\n\4\2\2\u00bd\u00bc\3\2\2\2\u00be\u00c1\3\2\2\2\u00bf"\r
+            + "\u00bd\3\2\2\2\u00bf\u00c0\3\2\2\2\u00c0\u00c2\3\2\2\2\u00c1\u00bf\3\2"\r
+            + "\2\2\u00c2\u00c3\7,\2\2\u00c3\u00c4\7\61\2\2\u00c4\u00c5\3\2\2\2\u00c5"\r
+            + "\u00c6\b\5\5\2\u00c6\13\3\2\2\2\u00c7\u00c8\7=\2\2\u00c8\u00c9\3\2\2\2"\r
+            + "\u00c9\u00ca\b\6\6\2\u00ca\r\3\2\2\2\u00cb\u00cc\7}\2\2\u00cc\u00cd\3"\r
+            + "\2\2\2\u00cd\u00ce\b\7\7\2\u00ce\17\3\2\2\2\u00cf\u00d0\7\177\2\2\u00d0"\r
+            + "\u00d1\3\2\2\2\u00d1\u00d2\b\b\b\2\u00d2\21\3\2\2\2\u00d3\u00d4\7{\2\2"\r
+            + "\u00d4\u00d5\7k\2\2\u00d5\u00d6\7p\2\2\u00d6\u00d7\7/\2\2\u00d7\u00d8"\r
+            + "\7g\2\2\u00d8\u00d9\7n\2\2\u00d9\u00da\7g\2\2\u00da\u00db\7o\2\2\u00db"\r
+            + "\u00dc\7g\2\2\u00dc\u00dd\7p\2\2\u00dd\u00de\7v\2\2\u00de\u00df\3\2\2"\r
+            + "\2\u00df\u00e0\b\t\t\2\u00e0\23\3\2\2\2\u00e1\u00e2\7{\2\2\u00e2\u00e3"\r
+            + "\7c\2\2\u00e3\u00e4\7p\2\2\u00e4\u00e5\7i\2\2\u00e5\u00e6\7/\2\2\u00e6"\r
+            + "\u00e7\7x\2\2\u00e7\u00e8\7g\2\2\u00e8\u00e9\7t\2\2\u00e9\u00ea\7u\2\2"\r
+            + "\u00ea\u00eb\7k\2\2\u00eb\u00ec\7q\2\2\u00ec\u00ed\7p\2\2\u00ed\u00ee"\r
+            + "\3\2\2\2\u00ee\u00ef\b\n\n\2\u00ef\25\3\2\2\2\u00f0\u00f1\7y\2\2\u00f1"\r
+            + "\u00f2\7j\2\2\u00f2\u00f3\7g\2\2\u00f3\u00f4\7p\2\2\u00f4\u00f5\3\2\2"\r
+            + "\2\u00f5\u00f6\b\13\13\2\u00f6\27\3\2\2\2\u00f7\u00f8\7x\2\2\u00f8\u00f9"\r
+            + "\7c\2\2\u00f9\u00fa\7n\2\2\u00fa\u00fb\7w\2\2\u00fb\u00fc\7g\2\2\u00fc"\r
+            + "\u00fd\3\2\2\2\u00fd\u00fe\b\f\f\2\u00fe\31\3\2\2\2\u00ff\u0100\7w\2\2"\r
+            + "\u0100\u0101\7u\2\2\u0101\u0102\7g\2\2\u0102\u0103\7u\2\2\u0103\u0104"\r
+            + "\3\2\2\2\u0104\u0105\b\r\r\2\u0105\33\3\2\2\2\u0106\u0107\7w\2\2\u0107"\r
+            + "\u0108\7p\2\2\u0108\u0109\7k\2\2\u0109\u010a\7v\2\2\u010a\u010b\7u\2\2"\r
+            + "\u010b\u010c\3\2\2\2\u010c\u010d\b\16\16\2\u010d\35\3\2\2\2\u010e\u010f"\r
+            + "\7w\2\2\u010f\u0110\7p\2\2\u0110\u0111\7k\2\2\u0111\u0112\7s\2\2\u0112"\r
+            + "\u0113\7w\2\2\u0113\u0114\7g\2\2\u0114\u0115\3\2\2\2\u0115\u0116\b\17"\r
+            + "\17\2\u0116\37\3\2\2\2\u0117\u0118\7v\2\2\u0118\u0119\7{\2\2\u0119\u011a"\r
+            + "\7r\2\2\u011a\u011b\7g\2\2\u011b\u011c\7f\2\2\u011c\u011d\7g\2\2\u011d"\r
+            + "\u011e\7h\2\2\u011e\u011f\3\2\2\2\u011f\u0120\b\20\20\2\u0120!\3\2\2\2"\r
+            + "\u0121\u0122\7v\2\2\u0122\u0123\7{\2\2\u0123\u0124\7r\2\2\u0124\u0125"\r
+            + "\7g\2\2\u0125\u0126\3\2\2\2\u0126\u0127\b\21\21\2\u0127#\3\2\2\2\u0128"\r
+            + "\u0129\7u\2\2\u0129\u012a\7w\2\2\u012a\u012b\7d\2\2\u012b\u012c\7o\2\2"\r
+            + "\u012c\u012d\7q\2\2\u012d\u012e\7f\2\2\u012e\u012f\7w\2\2\u012f\u0130"\r
+            + "\7n\2\2\u0130\u0131\7g\2\2\u0131\u0132\3\2\2\2\u0132\u0133\b\22\22\2\u0133"\r
+            + "%\3\2\2\2\u0134\u0135\7u\2\2\u0135\u0136\7v\2\2\u0136\u0137\7c\2\2\u0137"\r
+            + "\u0138\7v\2\2\u0138\u0139\7w\2\2\u0139\u013a\7u\2\2\u013a\u013b\3\2\2"\r
+            + "\2\u013b\u013c\b\23\23\2\u013c\'\3\2\2\2\u013d\u013e\7t\2\2\u013e\u013f"\r
+            + "\7r\2\2\u013f\u0140\7e\2\2\u0140\u0141\3\2\2\2\u0141\u0142\b\24\24\2\u0142"\r
+            + ")\3\2\2\2\u0143\u0144\7t\2\2\u0144\u0145\7g\2\2\u0145\u0146\7x\2\2\u0146"\r
+            + "\u0147\7k\2\2\u0147\u0148\7u\2\2\u0148\u0149\7k\2\2\u0149\u014a\7q\2\2"\r
+            + "\u014a\u014b\7p\2\2\u014b\u014c\7/\2\2\u014c\u014d\7f\2\2\u014d\u014e"\r
+            + "\7c\2\2\u014e\u014f\7v\2\2\u014f\u0150\7g\2\2\u0150\u0151\3\2\2\2\u0151"\r
+            + "\u0152\b\25\25\2\u0152+\3\2\2\2\u0153\u0154\7t\2\2\u0154\u0155\7g\2\2"\r
+            + "\u0155\u0156\7x\2\2\u0156\u0157\7k\2\2\u0157\u0158\7u\2\2\u0158\u0159"\r
+            + "\7k\2\2\u0159\u015a\7q\2\2\u015a\u015b\7p\2\2\u015b\u015c\3\2\2\2\u015c"\r
+            + "\u015d\b\26\26\2\u015d-\3\2\2\2\u015e\u015f\7t\2\2\u015f\u0160\7g\2\2"\r
+            + "\u0160\u0161\7s\2\2\u0161\u0162\7w\2\2\u0162\u0163\7k\2\2\u0163\u0164"\r
+            + "\7t\2\2\u0164\u0165\7g\2\2\u0165\u0166\7/\2\2\u0166\u0167\7k\2\2\u0167"\r
+            + "\u0168\7p\2\2\u0168\u0169\7u\2\2\u0169\u016a\7v\2\2\u016a\u016b\7c\2\2"\r
+            + "\u016b\u016c\7p\2\2\u016c\u016d\7e\2\2\u016d\u016e\7g\2\2\u016e\u016f"\r
+            + "\3\2\2\2\u016f\u0170\b\27\27\2\u0170/\3\2\2\2\u0171\u0172\7t\2\2\u0172"\r
+            + "\u0173\7g\2\2\u0173\u0174\7h\2\2\u0174\u0175\7k\2\2\u0175\u0176\7p\2\2"\r
+            + "\u0176\u0177\7g\2\2\u0177\u0178\3\2\2\2\u0178\u0179\b\30\30\2\u0179\61"\r
+            + "\3\2\2\2\u017a\u017b\7t\2\2\u017b\u017c\7g\2\2\u017c\u017d\7h\2\2\u017d"\r
+            + "\u017e\7g\2\2\u017e\u017f\7t\2\2\u017f\u0180\7g\2\2\u0180\u0181\7p\2\2"\r
+            + "\u0181\u0182\7e\2\2\u0182\u0183\7g\2\2\u0183\u0184\3\2\2\2\u0184\u0185"\r
+            + "\b\31\31\2\u0185\63\3\2\2\2\u0186\u0187\7t\2\2\u0187\u0188\7c\2\2\u0188"\r
+            + "\u0189\7p\2\2\u0189\u018a\7i\2\2\u018a\u018b\7g\2\2\u018b\u018c\3\2\2"\r
+            + "\2\u018c\u018d\b\32\32\2\u018d\65\3\2\2\2\u018e\u018f\7r\2\2\u018f\u0190"\r
+            + "\7t\2\2\u0190\u0191\7g\2\2\u0191\u0192\7u\2\2\u0192\u0193\7g\2\2\u0193"\r
+            + "\u0194\7p\2\2\u0194\u0195\7e\2\2\u0195\u0196\7g\2\2\u0196\u0197\3\2\2"\r
+            + "\2\u0197\u0198\b\33\33\2\u0198\67\3\2\2\2\u0199\u019a\7r\2\2\u019a\u019b"\r
+            + "\7t\2\2\u019b\u019c\7g\2\2\u019c\u019d\7h\2\2\u019d\u019e\7k\2\2\u019e"\r
+            + "\u019f\7z\2\2\u019f\u01a0\3\2\2\2\u01a0\u01a1\b\34\34\2\u01a19\3\2\2\2"\r
+            + "\u01a2\u01a3\7r\2\2\u01a3\u01a4\7q\2\2\u01a4\u01a5\7u\2\2\u01a5\u01a6"\r
+            + "\7k\2\2\u01a6\u01a7\7v\2\2\u01a7\u01a8\7k\2\2\u01a8\u01a9\7q\2\2\u01a9"\r
+            + "\u01aa\7p\2\2\u01aa\u01ab\3\2\2\2\u01ab\u01ac\b\35\35\2\u01ac;\3\2\2\2"\r
+            + "\u01ad\u01ae\7r\2\2\u01ae\u01af\7c\2\2\u01af\u01b0\7v\2\2\u01b0\u01b1"\r
+            + "\7v\2\2\u01b1\u01b2\7g\2\2\u01b2\u01b3\7t\2\2\u01b3\u01b4\7p\2\2\u01b4"\r
+            + "\u01b5\3\2\2\2\u01b5\u01b6\b\36\36\2\u01b6=\3\2\2\2\u01b7\u01b8\7r\2\2"\r
+            + "\u01b8\u01b9\7c\2\2\u01b9\u01ba\7v\2\2\u01ba\u01bb\7j\2\2\u01bb\u01bc"\r
+            + "\3\2\2\2\u01bc\u01bd\b\37\37\2\u01bd?\3\2\2\2\u01be\u01bf\7q\2\2\u01bf"\r
+            + "\u01c0\7w\2\2\u01c0\u01c1\7v\2\2\u01c1\u01c2\7r\2\2\u01c2\u01c3\7w\2\2"\r
+            + "\u01c3\u01c4\7v\2\2\u01c4A\3\2\2\2\u01c5\u01c6\7q\2\2\u01c6\u01c7\7t\2"\r
+            + "\2\u01c7\u01c8\7i\2\2\u01c8\u01c9\7c\2\2\u01c9\u01ca\7p\2\2\u01ca\u01cb"\r
+            + "\7k\2\2\u01cb\u01cc\7|\2\2\u01cc\u01cd\7c\2\2\u01cd\u01ce\7v\2\2\u01ce"\r
+            + "\u01cf\7k\2\2\u01cf\u01d0\7q\2\2\u01d0\u01d1\7p\2\2\u01d1\u01d2\3\2\2"\r
+            + "\2\u01d2\u01d3\b! \2\u01d3C\3\2\2\2\u01d4\u01d5\7q\2\2\u01d5\u01d6\7t"\r
+            + "\2\2\u01d6\u01d7\7f\2\2\u01d7\u01d8\7g\2\2\u01d8\u01d9\7t\2\2\u01d9\u01da"\r
+            + "\7g\2\2\u01da\u01db\7f\2\2\u01db\u01dc\7/\2\2\u01dc\u01dd\7d\2\2\u01dd"\r
+            + "\u01de\7{\2\2\u01de\u01df\3\2\2\2\u01df\u01e0\b\"!\2\u01e0E\3\2\2\2\u01e1"\r
+            + "\u01e2\7p\2\2\u01e2\u01e3\7q\2\2\u01e3\u01e4\7v\2\2\u01e4\u01e5\7k\2\2"\r
+            + "\u01e5\u01e6\7h\2\2\u01e6\u01e7\7k\2\2\u01e7\u01e8\7e\2\2\u01e8\u01e9"\r
+            + "\7c\2\2\u01e9\u01ea\7v\2\2\u01ea\u01eb\7k\2\2\u01eb\u01ec\7q\2\2\u01ec"\r
+            + "\u01ed\7p\2\2\u01ed\u01ee\3\2\2\2\u01ee\u01ef\b#\"\2\u01efG\3\2\2\2\u01f0"\r
+            + "\u01f1\7p\2\2\u01f1\u01f2\7c\2\2\u01f2\u01f3\7o\2\2\u01f3\u01f4\7g\2\2"\r
+            + "\u01f4\u01f5\7u\2\2\u01f5\u01f6\7r\2\2\u01f6\u01f7\7c\2\2\u01f7\u01f8"\r
+            + "\7e\2\2\u01f8\u01f9\7g\2\2\u01f9\u01fa\3\2\2\2\u01fa\u01fb\b$#\2\u01fb"\r
+            + "I\3\2\2\2\u01fc\u01fd\7o\2\2\u01fd\u01fe\7w\2\2\u01fe\u01ff\7u\2\2\u01ff"\r
+            + "\u0200\7v\2\2\u0200\u0201\3\2\2\2\u0201\u0202\b%$\2\u0202K\3\2\2\2\u0203"\r
+            + "\u0204\7o\2\2\u0204\u0205\7q\2\2\u0205\u0206\7f\2\2\u0206\u0207\7w\2\2"\r
+            + "\u0207\u0208\7n\2\2\u0208\u0209\7g\2\2\u0209\u020a\3\2\2\2\u020a\u020b"\r
+            + "\b&%\2\u020bM\3\2\2\2\u020c\u020d\7o\2\2\u020d\u020e\7k\2\2\u020e\u020f"\r
+            + "\7p\2\2\u020f\u0210\7/\2\2\u0210\u0211\7g\2\2\u0211\u0212\7n\2\2\u0212"\r
+            + "\u0213\7g\2\2\u0213\u0214\7o\2\2\u0214\u0215\7g\2\2\u0215\u0216\7p\2\2"\r
+            + "\u0216\u0217\7v\2\2\u0217\u0218\7u\2\2\u0218\u0219\3\2\2\2\u0219\u021a"\r
+            + "\b\'&\2\u021aO\3\2\2\2\u021b\u021c\7o\2\2\u021c\u021d\7c\2\2\u021d\u021e"\r
+            + "\7z\2\2\u021e\u021f\7/\2\2\u021f\u0220\7g\2\2\u0220\u0221\7n\2\2\u0221"\r
+            + "\u0222\7g\2\2\u0222\u0223\7o\2\2\u0223\u0224\7g\2\2\u0224\u0225\7p\2\2"\r
+            + "\u0225\u0226\7v\2\2\u0226\u0227\7u\2\2\u0227\u0228\3\2\2\2\u0228\u0229"\r
+            + "\b(\'\2\u0229Q\3\2\2\2\u022a\u022b\7o\2\2\u022b\u022c\7c\2\2\u022c\u022d"\r
+            + "\7p\2\2\u022d\u022e\7f\2\2\u022e\u022f\7c\2\2\u022f\u0230\7v\2\2\u0230"\r
+            + "\u0231\7q\2\2\u0231\u0232\7t\2\2\u0232\u0233\7{\2\2\u0233\u0234\3\2\2"\r
+            + "\2\u0234\u0235\b)(\2\u0235S\3\2\2\2\u0236\u0237\7n\2\2\u0237\u0238\7k"\r
+            + "\2\2\u0238\u0239\7u\2\2\u0239\u023a\7v\2\2\u023a\u023b\3\2\2\2\u023b\u023c"\r
+            + "\b*)\2\u023cU\3\2\2\2\u023d\u023e\7n\2\2\u023e\u023f\7g\2\2\u023f\u0240"\r
+            + "\7p\2\2\u0240\u0241\7i\2\2\u0241\u0242\7v\2\2\u0242\u0243\7j\2\2\u0243"\r
+            + "\u0244\3\2\2\2\u0244\u0245\b+*\2\u0245W\3\2\2\2\u0246\u0247\7n\2\2\u0247"\r
+            + "\u0248\7g\2\2\u0248\u0249\7c\2\2\u0249\u024a\7h\2\2\u024a\u024b\7/\2\2"\r
+            + "\u024b\u024c\7n\2\2\u024c\u024d\7k\2\2\u024d\u024e\7u\2\2\u024e\u024f"\r
+            + "\7v\2\2\u024f\u0250\3\2\2\2\u0250\u0251\b,+\2\u0251Y\3\2\2\2\u0252\u0253"\r
+            + "\7n\2\2\u0253\u0254\7g\2\2\u0254\u0255\7c\2\2\u0255\u0256\7h\2\2\u0256"\r
+            + "\u0257\3\2\2\2\u0257\u0258\b-,\2\u0258[\3\2\2\2\u0259\u025a\7m\2\2\u025a"\r
+            + "\u025b\7g\2\2\u025b\u025c\7{\2\2\u025c\u025d\3\2\2\2\u025d\u025e\b.-\2"\r
+            + "\u025e]\3\2\2\2\u025f\u0260\7k\2\2\u0260\u0261\7p\2\2\u0261\u0262\7r\2"\r
+            + "\2\u0262\u0263\7w\2\2\u0263\u0264\7v\2\2\u0264_\3\2\2\2\u0265\u0266\7"\r
+            + "k\2\2\u0266\u0267\7p\2\2\u0267\u0268\7e\2\2\u0268\u0269\7n\2\2\u0269\u026a"\r
+            + "\7w\2\2\u026a\u026b\7f\2\2\u026b\u026c\7g\2\2\u026c\u026d\3\2\2\2\u026d"\r
+            + "\u026e\b\60.\2\u026ea\3\2\2\2\u026f\u0270\7k\2\2\u0270\u0271\7o\2\2\u0271"\r
+            + "\u0272\7r\2\2\u0272\u0273\7q\2\2\u0273\u0274\7t\2\2\u0274\u0275\7v\2\2"\r
+            + "\u0275\u0276\3\2\2\2\u0276\u0277\b\61/\2\u0277c\3\2\2\2\u0278\u0279\7"\r
+            + "k\2\2\u0279\u027a\7h\2\2\u027a\u027b\7/\2\2\u027b\u027c\7h\2\2\u027c\u027d"\r
+            + "\7g\2\2\u027d\u027e\7c\2\2\u027e\u027f\7v\2\2\u027f\u0280\7w\2\2\u0280"\r
+            + "\u0281\7t\2\2\u0281\u0282\7g\2\2\u0282\u0283\3\2\2\2\u0283\u0284\b\62"\r
+            + "\60\2\u0284e\3\2\2\2\u0285\u0286\7k\2\2\u0286\u0287\7f\2\2\u0287\u0288"\r
+            + "\7g\2\2\u0288\u0289\7p\2\2\u0289\u028a\7v\2\2\u028a\u028b\7k\2\2\u028b"\r
+            + "\u028c\7v\2\2\u028c\u028d\7{\2\2\u028d\u028e\3\2\2\2\u028e\u028f\b\63"\r
+            + "\61\2\u028fg\3\2\2\2\u0290\u0291\7i\2\2\u0291\u0292\7t\2\2\u0292\u0293"\r
+            + "\7q\2\2\u0293\u0294\7w\2\2\u0294\u0295\7r\2\2\u0295\u0296\7k\2\2\u0296"\r
+            + "\u0297\7p\2\2\u0297\u0298\7i\2\2\u0298\u0299\3\2\2\2\u0299\u029a\b\64"\r
+            + "\62\2\u029ai\3\2\2\2\u029b\u029c\7h\2\2\u029c\u029d\7t\2\2\u029d\u029e"\r
+            + "\7c\2\2\u029e\u029f\7e\2\2\u029f\u02a0\7v\2\2\u02a0\u02a1\7k\2\2\u02a1"\r
+            + "\u02a2\7q\2\2\u02a2\u02a3\7p\2\2\u02a3\u02a4\7/\2\2\u02a4\u02a5\7f\2\2"\r
+            + "\u02a5\u02a6\7k\2\2\u02a6\u02a7\7i\2\2\u02a7\u02a8\7k\2\2\u02a8\u02a9"\r
+            + "\7v\2\2\u02a9\u02aa\7u\2\2\u02aa\u02ab\3\2\2\2\u02ab\u02ac\b\65\63\2\u02ac"\r
+            + "k\3\2\2\2\u02ad\u02ae\7h\2\2\u02ae\u02af\7g\2\2\u02af\u02b0\7c\2\2\u02b0"\r
+            + "\u02b1\7v\2\2\u02b1\u02b2\7w\2\2\u02b2\u02b3\7t\2\2\u02b3\u02b4\7g\2\2"\r
+            + "\u02b4\u02b5\3\2\2\2\u02b5\u02b6\b\66\64\2\u02b6m\3\2\2\2\u02b7\u02b8"\r
+            + "\7f\2\2\u02b8\u02b9\7g\2\2\u02b9\u02ba\7x\2\2\u02ba\u02bb\7k\2\2\u02bb"\r
+            + "\u02bc\7c\2\2\u02bc\u02bd\7v\2\2\u02bd\u02be\7g\2\2\u02be\u02bf\3\2\2"\r
+            + "\2\u02bf\u02c0\b\67\65\2\u02c0o\3\2\2\2\u02c1\u02c2\7f\2\2\u02c2\u02c3"\r
+            + "\7g\2\2\u02c3\u02c4\7x\2\2\u02c4\u02c5\7k\2\2\u02c5\u02c6\7c\2\2\u02c6"\r
+            + "\u02c7\7v\2\2\u02c7\u02c8\7k\2\2\u02c8\u02c9\7q\2\2\u02c9\u02ca\7p\2\2"\r
+            + "\u02ca\u02cb\3\2\2\2\u02cb\u02cc\b8\66\2\u02ccq\3\2\2\2\u02cd\u02ce\7"\r
+            + "g\2\2\u02ce\u02cf\7z\2\2\u02cf\u02d0\7v\2\2\u02d0\u02d1\7g\2\2\u02d1\u02d2"\r
+            + "\7p\2\2\u02d2\u02d3\7u\2\2\u02d3\u02d4\7k\2\2\u02d4\u02d5\7q\2\2\u02d5"\r
+            + "\u02d6\7p\2\2\u02d6\u02d7\3\2\2\2\u02d7\u02d8\b9\67\2\u02d8s\3\2\2\2\u02d9"\r
+            + "\u02da\7g\2\2\u02da\u02db\7t\2\2\u02db\u02dc\7t\2\2\u02dc\u02dd\7q\2\2"\r
+            + "\u02dd\u02de\7t\2\2\u02de\u02df\7/\2\2\u02df\u02e0\7o\2\2\u02e0\u02e1"\r
+            + "\7g\2\2\u02e1\u02e2\7u\2\2\u02e2\u02e3\7u\2\2\u02e3\u02e4\7c\2\2\u02e4"\r
+            + "\u02e5\7i\2\2\u02e5\u02e6\7g\2\2\u02e6\u02e7\3\2\2\2\u02e7\u02e8\b:8\2"\r
+            + "\u02e8u\3\2\2\2\u02e9\u02ea\7g\2\2\u02ea\u02eb\7t\2\2\u02eb\u02ec\7t\2"\r
+            + "\2\u02ec\u02ed\7q\2\2\u02ed\u02ee\7t\2\2\u02ee\u02ef\7/\2\2\u02ef\u02f0"\r
+            + "\7c\2\2\u02f0\u02f1\7r\2\2\u02f1\u02f2\7r\2\2\u02f2\u02f3\7/\2\2\u02f3"\r
+            + "\u02f4\7v\2\2\u02f4\u02f5\7c\2\2\u02f5\u02f6\7i\2\2\u02f6\u02f7\3\2\2"\r
+            + "\2\u02f7\u02f8\b;9\2\u02f8w\3\2\2\2\u02f9\u02fa\7g\2\2\u02fa\u02fb\7p"\r
+            + "\2\2\u02fb\u02fc\7w\2\2\u02fc\u02fd\7o\2\2\u02fd\u02fe\3\2\2\2\u02fe\u02ff"\r
+            + "\b<:\2\u02ffy\3\2\2\2\u0300\u0301\7f\2\2\u0301\u0302\7g\2\2\u0302\u0303"\r
+            + "\7u\2\2\u0303\u0304\7e\2\2\u0304\u0305\7t\2\2\u0305\u0306\7k\2\2\u0306"\r
+            + "\u0307\7r\2\2\u0307\u0308\7v\2\2\u0308\u0309\7k\2\2\u0309\u030a\7q\2\2"\r
+            + "\u030a\u030b\7p\2\2\u030b\u030c\3\2\2\2\u030c\u030d\b=;\2\u030d{\3\2\2"\r
+            + "\2\u030e\u030f\7f\2\2\u030f\u0310\7g\2\2\u0310\u0311\7h\2\2\u0311\u0312"\r
+            + "\7c\2\2\u0312\u0313\7w\2\2\u0313\u0314\7n\2\2\u0314\u0315\7v\2\2\u0315"\r
+            + "\u0316\3\2\2\2\u0316\u0317\b><\2\u0317}\3\2\2\2\u0318\u0319\7e\2\2\u0319"\r
+            + "\u031a\7q\2\2\u031a\u031b\7p\2\2\u031b\u031c\7v\2\2\u031c\u031d\7c\2\2"\r
+            + "\u031d\u031e\7k\2\2\u031e\u031f\7p\2\2\u031f\u0320\7g\2\2\u0320\u0321"\r
+            + "\7t\2\2\u0321\u0322\3\2\2\2\u0322\u0323\b?=\2\u0323\177\3\2\2\2\u0324"\r
+            + "\u0325\7e\2\2\u0325\u0326\7q\2\2\u0326\u0327\7p\2\2\u0327\u0328\7v\2\2"\r
+            + "\u0328\u0329\7c\2\2\u0329\u032a\7e\2\2\u032a\u032b\7v\2\2\u032b\u032c"\r
+            + "\3\2\2\2\u032c\u032d\b@>\2\u032d\u0081\3\2\2\2\u032e\u032f\7e\2\2\u032f"\r
+            + "\u0330\7q\2\2\u0330\u0331\7p\2\2\u0331\u0332\7h\2\2\u0332\u0333\7k\2\2"\r
+            + "\u0333\u0334\7i\2\2\u0334\u0335\3\2\2\2\u0335\u0336\bA?\2\u0336\u0083"\r
+            + "\3\2\2\2\u0337\u0338\7e\2\2\u0338\u0339\7j\2\2\u0339\u033a\7q\2\2\u033a"\r
+            + "\u033b\7k\2\2\u033b\u033c\7e\2\2\u033c\u033d\7g\2\2\u033d\u033e\3\2\2"\r
+            + "\2\u033e\u033f\bB@\2\u033f\u0085\3\2\2\2\u0340\u0341\7e\2\2\u0341\u0342"\r
+            + "\7c\2\2\u0342\u0343\7u\2\2\u0343\u0344\7g\2\2\u0344\u0345\3\2\2\2\u0345"\r
+            + "\u0346\bCA\2\u0346\u0087\3\2\2\2\u0347\u0348\7d\2\2\u0348\u0349\7k\2\2"\r
+            + "\u0349\u034a\7v\2\2\u034a\u034b\3\2\2\2\u034b\u034c\bDB\2\u034c\u0089"\r
+            + "\3\2\2\2\u034d\u034e\7d\2\2\u034e\u034f\7g\2\2\u034f\u0350\7n\2\2\u0350"\r
+            + "\u0351\7q\2\2\u0351\u0352\7p\2\2\u0352\u0353\7i\2\2\u0353\u0354\7u\2\2"\r
+            + "\u0354\u0355\7/\2\2\u0355\u0356\7v\2\2\u0356\u0357\7q\2\2\u0357\u0358"\r
+            + "\3\2\2\2\u0358\u0359\bEC\2\u0359\u008b\3\2\2\2\u035a\u035b\7d\2\2\u035b"\r
+            + "\u035c\7c\2\2\u035c\u035d\7u\2\2\u035d\u035e\7g\2\2\u035e\u035f\3\2\2"\r
+            + "\2\u035f\u0360\bFD\2\u0360\u008d\3\2\2\2\u0361\u0362\7c\2\2\u0362\u0363"\r
+            + "\7w\2\2\u0363\u0364\7i\2\2\u0364\u0365\7o\2\2\u0365\u0366\7g\2\2\u0366"\r
+            + "\u0367\7p\2\2\u0367\u0368\7v\2\2\u0368\u0369\3\2\2\2\u0369\u036a\bGE\2"\r
+            + "\u036a\u008f\3\2\2\2\u036b\u036c\7c\2\2\u036c\u036d\7t\2\2\u036d\u036e"\r
+            + "\7i\2\2\u036e\u036f\7w\2\2\u036f\u0370\7o\2\2\u0370\u0371\7g\2\2\u0371"\r
+            + "\u0372\7p\2\2\u0372\u0373\7v\2\2\u0373\u0374\3\2\2\2\u0374\u0375\bHF\2"\r
+            + "\u0375\u0091\3\2\2\2\u0376\u0377\7c\2\2\u0377\u0378\7p\2\2\u0378\u0379"\r
+            + "\7{\2\2\u0379\u037a\7z\2\2\u037a\u037b\7o\2\2\u037b\u037c\7n\2\2\u037c"\r
+            + "\u037d\3\2\2\2\u037d\u037e\bIG\2\u037e\u0093\3\2\2\2\u037f\u0383\t\5\2"\r
+            + "\2\u0380\u0382\t\6\2\2\u0381\u0380\3\2\2\2\u0382\u0385\3\2\2\2\u0383\u0381"\r
+            + "\3\2\2\2\u0383\u0384\3\2\2\2\u0384\u0386\3\2\2\2\u0385\u0383\3\2\2\2\u0386"\r
+            + "\u0387\bJH\2\u0387\u0095\3\2\2\2\u0388\u038b\7^\2\2\u0389\u038c\t\7\2"\r
+            + "\2\u038a\u038c\5\u0098L\2\u038b\u0389\3\2\2\2\u038b\u038a\3\2\2\2\u038c"\r
+            + "\u0097\3\2\2\2\u038d\u038e\7w\2\2\u038e\u038f\5\u009aM\2\u038f\u0390\5"\r
+            + "\u009aM\2\u0390\u0391\5\u009aM\2\u0391\u0392\5\u009aM\2\u0392\u0099\3"\r
+            + "\2\2\2\u0393\u0394\t\b\2\2\u0394\u009b\3\2\2\2\u0395\u0396\7=\2\2\u0396"\r
+            + "\u0397\3\2\2\2\u0397\u0398\bNI\2\u0398\u009d\3\2\2\2\u0399\u039a\7}\2"\r
+            + "\2\u039a\u039b\3\2\2\2\u039b\u039c\bOJ\2\u039c\u009f\3\2\2\2\u039d\u03a2"\r
+            + "\7$\2\2\u039e\u03a1\5\u0096K\2\u039f\u03a1\n\t\2\2\u03a0\u039e\3\2\2\2"\r
+            + "\u03a0\u039f\3\2\2\2\u03a1\u03a4\3\2\2\2\u03a2\u03a0\3\2\2\2\u03a2\u03a3"\r
+            + "\3\2\2\2\u03a3\u03a5\3\2\2\2\u03a4\u03a2\3\2\2\2\u03a5\u03b0\7$\2\2\u03a6"\r
+            + "\u03ab\7)\2\2\u03a7\u03aa\5\u0096K\2\u03a8\u03aa\n\n\2\2\u03a9\u03a7\3"\r
+            + "\2\2\2\u03a9\u03a8\3\2\2\2\u03aa\u03ad\3\2\2\2\u03ab\u03a9\3\2\2\2\u03ab"\r
+            + "\u03ac\3\2\2\2\u03ac\u03ae\3\2\2\2\u03ad\u03ab\3\2\2\2\u03ae\u03b0\7)"\r
+            + "\2\2\u03af\u039d\3\2\2\2\u03af\u03a6\3\2\2\2\u03b0\u00a1\3\2\2\2\u03b1"\r
+            + "\u03b8\5\u00a0P\2\u03b2\u03b4\n\13\2\2\u03b3\u03b2\3\2\2\2\u03b4\u03b5"\r
+            + "\3\2\2\2\u03b5\u03b3\3\2\2\2\u03b5\u03b6\3\2\2\2\u03b6\u03b8\3\2\2\2\u03b7"\r
+            + "\u03b1\3\2\2\2\u03b7\u03b3\3\2\2\2\u03b8\u03b9\3\2\2\2\u03b9\u03ba\bQ"\r
+            + "K\2\u03ba\u00a3\3\2\2\2\u03bb\u03bc\t\f\2\2\u03bc\u03bd\3\2\2\2\u03bd"\r
+            + "\u03be\bRL\2\u03be\u00a5\3\2\2\2\17\2\3\u00b4\u00bf\u0383\u038b\u03a0"\r
+            + "\u03a2\u03a9\u03ab\u03af\u03b5\u03b7";\r
+    public static final ATN _ATN = ATNSimulator.deserialize(_serializedATN\r
+            .toCharArray());\r
+    static {\r
+        _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];\r
+    }\r
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParser.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParser.java
new file mode 100644 (file)
index 0000000..2b22fc7
--- /dev/null
@@ -0,0 +1,13367 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.antlrv4.code.gen;\r
+\r
+import java.util.List;\r
+\r
+import org.antlr.v4.runtime.NoViableAltException;\r
+import org.antlr.v4.runtime.Parser;\r
+import org.antlr.v4.runtime.ParserRuleContext;\r
+import org.antlr.v4.runtime.RecognitionException;\r
+import org.antlr.v4.runtime.TokenStream;\r
+import org.antlr.v4.runtime.atn.ATN;\r
+import org.antlr.v4.runtime.atn.ATNSimulator;\r
+import org.antlr.v4.runtime.atn.ParserATNSimulator;\r
+import org.antlr.v4.runtime.atn.PredictionContextCache;\r
+import org.antlr.v4.runtime.dfa.DFA;\r
+import org.antlr.v4.runtime.tree.ParseTreeListener;\r
+import org.antlr.v4.runtime.tree.ParseTreeVisitor;\r
+import org.antlr.v4.runtime.tree.TerminalNode;\r
+\r
+@SuppressWarnings({ "all", "warnings", "unchecked", "unused", "cast" })\r
+public class YangParser extends Parser {\r
+    protected static final DFA[] _decisionToDFA;\r
+    protected static final PredictionContextCache _sharedContextCache = new PredictionContextCache();\r
+    public static final int CHOICE_KEYWORD = 65, YIN_ELEMENT_KEYWORD = 8,\r
+            WHEN_KEYWORD = 10, REVISION_KEYWORD = 21, DESCRIPTION_KEYWORD = 60,\r
+            NAMESPACE_KEYWORD = 35, MODULE_KEYWORD = 37,\r
+            REFERENCE_KEYWORD = 24, CONTACT_KEYWORD = 63,\r
+            LEAF_LIST_KEYWORD = 43, REVISION_DATE_KEYWORD = 20,\r
+            BELONGS_TO_KEYWORD = 68, LEAF_KEYWORD = 44, PREFIX_KEYWORD = 27,\r
+            DEFAULT_KEYWORD = 61, PRESENCE_KEYWORD = 26, ARGUMENT_KEYWORD = 71,\r
+            NOTIFICATION_KEYWORD = 34, RPC_KEYWORD = 19,\r
+            CONTAINER_KEYWORD = 62, DEVIATION_KEYWORD = 55,\r
+            STATUS_KEYWORD = 18, IDENTITY_KEYWORD = 50, IDENTIFIER = 73,\r
+            REFINE_KEYWORD = 23, USES_KEYWORD = 12, VALUE_KEYWORD = 11,\r
+            IMPORT_KEYWORD = 48, BLOCK_COMMENT = 7, INPUT_KEYWORD = 46,\r
+            IF_FEATURE_KEYWORD = 49, PLUS = 4, PATTERN_KEYWORD = 29,\r
+            LENGTH_KEYWORD = 42, FEATURE_KEYWORD = 53,\r
+            REQUIRE_INSTANCE_KEYWORD = 22, ORGANIZATION_KEYWORD = 32,\r
+            UNIQUE_KEYWORD = 14, SUBMODULE_KEYWORD = 17, TYPE_KEYWORD = 16,\r
+            RIGHT_BRACE = 3, ERROR_MESSAGE_KEYWORD = 57, LINE_COMMENT = 6,\r
+            OUTPUT_KEYWORD = 31, MIN_ELEMENTS_KEYWORD = 38, MUST_KEYWORD = 36,\r
+            SEMICOLON = 1, POSITION_KEYWORD = 28, PATH_KEYWORD = 30, S = 75,\r
+            KEY_KEYWORD = 45, EXTENSION_KEYWORD = 56, WS = 5,\r
+            MANDATORY_KEYWORD = 40, ORDERED_BY_KEYWORD = 33,\r
+            ERROR_APP_TAG_KEYWORD = 58, INCLUDE_KEYWORD = 47,\r
+            ANYXML_KEYWORD = 72, AUGMENT_KEYWORD = 70, DEVIATE_KEYWORD = 54,\r
+            LEFT_BRACE = 2, YANG_VERSION_KEYWORD = 9, LIST_KEYWORD = 41,\r
+            TYPEDEF_KEYWORD = 15, MAX_ELEMENTS_KEYWORD = 39, ENUM_KEYWORD = 59,\r
+            CASE_KEYWORD = 66, UNITS_KEYWORD = 13, GROUPING_KEYWORD = 51,\r
+            BASE_KEYWORD = 69, RANGE_KEYWORD = 25,\r
+            FRACTION_DIGITS_KEYWORD = 52, CONFIG_KEYWORD = 64,\r
+            BIT_KEYWORD = 67, STRING = 74;\r
+    public static final String[] tokenNames = { "<INVALID>", "SEMICOLON",\r
+            "LEFT_BRACE", "'}'", "'+'", "WS", "LINE_COMMENT", "BLOCK_COMMENT",\r
+            "'yin-element'", "'yang-version'", "'when'", "'value'", "'uses'",\r
+            "'units'", "'unique'", "'typedef'", "'type'", "'submodule'",\r
+            "'status'", "'rpc'", "'revision-date'", "'revision'",\r
+            "'require-instance'", "'refine'", "'reference'", "'range'",\r
+            "'presence'", "'prefix'", "'position'", "'pattern'", "'path'",\r
+            "'output'", "'organization'", "'ordered-by'", "'notification'",\r
+            "'namespace'", "'must'", "'module'", "'min-elements'",\r
+            "'max-elements'", "'mandatory'", "'list'", "'length'",\r
+            "'leaf-list'", "'leaf'", "'key'", "'input'", "'include'",\r
+            "'import'", "'if-feature'", "'identity'", "'grouping'",\r
+            "'fraction-digits'", "'feature'", "'deviate'", "'deviation'",\r
+            "'extension'", "'error-message'", "'error-app-tag'", "'enum'",\r
+            "'description'", "'default'", "'container'", "'contact'",\r
+            "'config'", "'choice'", "'case'", "'bit'", "'belongs-to'",\r
+            "'base'", "'augment'", "'argument'", "'anyxml'", "IDENTIFIER",\r
+            "STRING", "S" };\r
+    public static final int RULE_yang = 0, RULE_string = 1,\r
+            RULE_identifier_stmt = 2, RULE_stmtend = 3,\r
+            RULE_deviate_replace_stmt = 4, RULE_deviate_delete_stmt = 5,\r
+            RULE_deviate_add_stmt = 6, RULE_deviate_not_supported_stmt = 7,\r
+            RULE_deviation_stmt = 8, RULE_notification_stmt = 9,\r
+            RULE_output_stmt = 10, RULE_input_stmt = 11, RULE_rpc_stmt = 12,\r
+            RULE_when_stmt = 13, RULE_augment_stmt = 14,\r
+            RULE_uses_augment_stmt = 15, RULE_refine_anyxml_stmts = 16,\r
+            RULE_refine_case_stmts = 17, RULE_refine_choice_stmts = 18,\r
+            RULE_refine_list_stmts = 19, RULE_refine_leaf_list_stmts = 20,\r
+            RULE_refine_leaf_stmts = 21, RULE_refine_container_stmts = 22,\r
+            RULE_refune_pom = 23, RULE_refine_stmt = 24, RULE_uses_stmt = 25,\r
+            RULE_anyxml_stmt = 26, RULE_case_stmt = 27,\r
+            RULE_short_case_stmt = 28, RULE_choice_stmt = 29,\r
+            RULE_unique_stmt = 30, RULE_key_stmt = 31, RULE_list_stmt = 32,\r
+            RULE_leaf_list_stmt = 33, RULE_leaf_stmt = 34,\r
+            RULE_container_stmt = 35, RULE_grouping_stmt = 36,\r
+            RULE_value_stmt = 37, RULE_max_value_arg = 38,\r
+            RULE_max_elements_stmt = 39, RULE_min_elements_stmt = 40,\r
+            RULE_error_app_tag_stmt = 41, RULE_error_message_stmt = 42,\r
+            RULE_must_stmt = 43, RULE_ordered_by_arg = 44,\r
+            RULE_ordered_by_stmt = 45, RULE_presence_stmt = 46,\r
+            RULE_mandatory_arg = 47, RULE_mandatory_stmt = 48,\r
+            RULE_config_arg = 49, RULE_config_stmt = 50, RULE_status_arg = 51,\r
+            RULE_status_stmt = 52, RULE_position_stmt = 53, RULE_bit_stmt = 54,\r
+            RULE_bits_specification = 55, RULE_union_specification = 56,\r
+            RULE_identityref_specification = 57,\r
+            RULE_instance_identifier_specification = 58,\r
+            RULE_require_instance_arg = 59, RULE_require_instance_stmt = 60,\r
+            RULE_path_stmt = 61, RULE_leafref_specification = 62,\r
+            RULE_enum_stmt = 63, RULE_enum_specification = 64,\r
+            RULE_default_stmt = 65, RULE_pattern_stmt = 66,\r
+            RULE_length_stmt = 67, RULE_string_restrictions = 68,\r
+            RULE_fraction_digits_stmt = 69, RULE_decimal64_specification = 70,\r
+            RULE_range_stmt = 71, RULE_numerical_restrictions = 72,\r
+            RULE_type_body_stmts = 73, RULE_type_stmt = 74,\r
+            RULE_typedef_stmt = 75, RULE_if_feature_stmt = 76,\r
+            RULE_feature_stmt = 77, RULE_base_stmt = 78,\r
+            RULE_identity_stmt = 79, RULE_yin_element_arg = 80,\r
+            RULE_yin_element_stmt = 81, RULE_argument_stmt = 82,\r
+            RULE_extension_stmt = 83, RULE_revision_date_stmt = 84,\r
+            RULE_revision_stmt = 85, RULE_units_stmt = 86,\r
+            RULE_reference_stmt = 87, RULE_description_stmt = 88,\r
+            RULE_contact_stmt = 89, RULE_organization_stmt = 90,\r
+            RULE_belongs_to_stmt = 91, RULE_prefix_stmt = 92,\r
+            RULE_namespace_stmt = 93, RULE_include_stmt = 94,\r
+            RULE_import_stmt = 95, RULE_yang_version_stmt = 96,\r
+            RULE_data_def_stmt = 97, RULE_body_stmts = 98,\r
+            RULE_revision_stmts = 99, RULE_linkage_stmts = 100,\r
+            RULE_meta_stmts = 101, RULE_submodule_header_stmts = 102,\r
+            RULE_module_header_stmts = 103, RULE_submodule_stmt = 104,\r
+            RULE_module_stmt = 105;\r
+    public static final String[] ruleNames = { "yang", "string",\r
+            "identifier_stmt", "stmtend", "deviate_replace_stmt",\r
+            "deviate_delete_stmt", "deviate_add_stmt",\r
+            "deviate_not_supported_stmt", "deviation_stmt",\r
+            "notification_stmt", "output_stmt", "input_stmt", "rpc_stmt",\r
+            "when_stmt", "augment_stmt", "uses_augment_stmt",\r
+            "refine_anyxml_stmts", "refine_case_stmts", "refine_choice_stmts",\r
+            "refine_list_stmts", "refine_leaf_list_stmts", "refine_leaf_stmts",\r
+            "refine_container_stmts", "refune_pom", "refine_stmt", "uses_stmt",\r
+            "anyxml_stmt", "case_stmt", "short_case_stmt", "choice_stmt",\r
+            "unique_stmt", "key_stmt", "list_stmt", "leaf_list_stmt",\r
+            "leaf_stmt", "container_stmt", "grouping_stmt", "value_stmt",\r
+            "max_value_arg", "max_elements_stmt", "min_elements_stmt",\r
+            "error_app_tag_stmt", "error_message_stmt", "must_stmt",\r
+            "ordered_by_arg", "ordered_by_stmt", "presence_stmt",\r
+            "mandatory_arg", "mandatory_stmt", "config_arg", "config_stmt",\r
+            "status_arg", "status_stmt", "position_stmt", "bit_stmt",\r
+            "bits_specification", "union_specification",\r
+            "identityref_specification", "instance_identifier_specification",\r
+            "require_instance_arg", "require_instance_stmt", "path_stmt",\r
+            "leafref_specification", "enum_stmt", "enum_specification",\r
+            "default_stmt", "pattern_stmt", "length_stmt",\r
+            "string_restrictions", "fraction_digits_stmt",\r
+            "decimal64_specification", "range_stmt", "numerical_restrictions",\r
+            "type_body_stmts", "type_stmt", "typedef_stmt", "if_feature_stmt",\r
+            "feature_stmt", "base_stmt", "identity_stmt", "yin_element_arg",\r
+            "yin_element_stmt", "argument_stmt", "extension_stmt",\r
+            "revision_date_stmt", "revision_stmt", "units_stmt",\r
+            "reference_stmt", "description_stmt", "contact_stmt",\r
+            "organization_stmt", "belongs_to_stmt", "prefix_stmt",\r
+            "namespace_stmt", "include_stmt", "import_stmt",\r
+            "yang_version_stmt", "data_def_stmt", "body_stmts",\r
+            "revision_stmts", "linkage_stmts", "meta_stmts",\r
+            "submodule_header_stmts", "module_header_stmts", "submodule_stmt",\r
+            "module_stmt" };\r
+\r
+    @Override\r
+    public String getGrammarFileName() {\r
+        return "yangParser.g4";\r
+    }\r
+\r
+    @Override\r
+    public String[] getTokenNames() {\r
+        return tokenNames;\r
+    }\r
+\r
+    @Override\r
+    public String[] getRuleNames() {\r
+        return ruleNames;\r
+    }\r
+\r
+    @Override\r
+    public ATN getATN() {\r
+        return _ATN;\r
+    }\r
+\r
+    public YangParser(TokenStream input) {\r
+        super(input);\r
+        _interp = new ParserATNSimulator(this, _ATN, _decisionToDFA,\r
+                _sharedContextCache);\r
+    }\r
+\r
+    public static class YangContext extends ParserRuleContext {\r
+        public Submodule_stmtContext submodule_stmt() {\r
+            return getRuleContext(Submodule_stmtContext.class, 0);\r
+        }\r
+\r
+        public Module_stmtContext module_stmt() {\r
+            return getRuleContext(Module_stmtContext.class, 0);\r
+        }\r
+\r
+        public YangContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_yang;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterYang(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitYang(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitYang(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final YangContext yang() throws RecognitionException {\r
+        YangContext _localctx = new YangContext(_ctx, getState());\r
+        enterRule(_localctx, 0, RULE_yang);\r
+        try {\r
+            setState(214);\r
+            switch (_input.LA(1)) {\r
+            case MODULE_KEYWORD:\r
+                enterOuterAlt(_localctx, 1);\r
+                {\r
+                    setState(212);\r
+                    module_stmt();\r
+                }\r
+                break;\r
+            case SUBMODULE_KEYWORD:\r
+                enterOuterAlt(_localctx, 2);\r
+                {\r
+                    setState(213);\r
+                    submodule_stmt();\r
+                }\r
+                break;\r
+            default:\r
+                throw new NoViableAltException(this);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class StringContext extends ParserRuleContext {\r
+        public List<TerminalNode> PLUS() {\r
+            return getTokens(YangParser.PLUS);\r
+        }\r
+\r
+        public TerminalNode STRING(int i) {\r
+            return getToken(YangParser.STRING, i);\r
+        }\r
+\r
+        public TerminalNode PLUS(int i) {\r
+            return getToken(YangParser.PLUS, i);\r
+        }\r
+\r
+        public List<TerminalNode> STRING() {\r
+            return getTokens(YangParser.STRING);\r
+        }\r
+\r
+        public StringContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_string;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterString(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitString(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitString(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final StringContext string() throws RecognitionException {\r
+        StringContext _localctx = new StringContext(_ctx, getState());\r
+        enterRule(_localctx, 2, RULE_string);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(216);\r
+                match(STRING);\r
+                setState(221);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                while (_la == PLUS) {\r
+                    {\r
+                        {\r
+                            setState(217);\r
+                            match(PLUS);\r
+                            setState(218);\r
+                            match(STRING);\r
+                        }\r
+                    }\r
+                    setState(223);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Identifier_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode IDENTIFIER() {\r
+            return getToken(YangParser.IDENTIFIER, 0);\r
+        }\r
+\r
+        public Identifier_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_identifier_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterIdentifier_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitIdentifier_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitIdentifier_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Identifier_stmtContext identifier_stmt()\r
+            throws RecognitionException {\r
+        Identifier_stmtContext _localctx = new Identifier_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 4, RULE_identifier_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(224);\r
+                match(IDENTIFIER);\r
+                setState(226);\r
+                _la = _input.LA(1);\r
+                if (_la == STRING) {\r
+                    {\r
+                        setState(225);\r
+                        string();\r
+                    }\r
+                }\r
+\r
+                setState(228);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class StmtendContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt() {\r
+            return getRuleContext(Identifier_stmtContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public StmtendContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_stmtend;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterStmtend(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitStmtend(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitStmtend(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final StmtendContext stmtend() throws RecognitionException {\r
+        StmtendContext _localctx = new StmtendContext(_ctx, getState());\r
+        enterRule(_localctx, 6, RULE_stmtend);\r
+        int _la;\r
+        try {\r
+            setState(239);\r
+            switch (_input.LA(1)) {\r
+            case SEMICOLON:\r
+                enterOuterAlt(_localctx, 1);\r
+                {\r
+                    {\r
+                        setState(230);\r
+                        match(SEMICOLON);\r
+                        setState(232);\r
+                        switch (getInterpreter().adaptivePredict(_input, 3,\r
+                                _ctx)) {\r
+                        case 1: {\r
+                            setState(231);\r
+                            identifier_stmt();\r
+                        }\r
+                            break;\r
+                        }\r
+                    }\r
+                }\r
+                break;\r
+            case LEFT_BRACE:\r
+                enterOuterAlt(_localctx, 2);\r
+                {\r
+                    {\r
+                        setState(234);\r
+                        match(LEFT_BRACE);\r
+                        setState(236);\r
+                        _la = _input.LA(1);\r
+                        if (_la == IDENTIFIER) {\r
+                            {\r
+                                setState(235);\r
+                                identifier_stmt();\r
+                            }\r
+                        }\r
+\r
+                        setState(238);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                break;\r
+            default:\r
+                throw new NoViableAltException(this);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Deviate_replace_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public Units_stmtContext units_stmt(int i) {\r
+            return getRuleContext(Units_stmtContext.class, i);\r
+        }\r
+\r
+        public Default_stmtContext default_stmt(int i) {\r
+            return getRuleContext(Default_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Units_stmtContext> units_stmt() {\r
+            return getRuleContexts(Units_stmtContext.class);\r
+        }\r
+\r
+        public List<Max_elements_stmtContext> max_elements_stmt() {\r
+            return getRuleContexts(Max_elements_stmtContext.class);\r
+        }\r
+\r
+        public Type_stmtContext type_stmt(int i) {\r
+            return getRuleContext(Type_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode DEVIATE_KEYWORD() {\r
+            return getToken(YangParser.DEVIATE_KEYWORD, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public List<Mandatory_stmtContext> mandatory_stmt() {\r
+            return getRuleContexts(Mandatory_stmtContext.class);\r
+        }\r
+\r
+        public List<Type_stmtContext> type_stmt() {\r
+            return getRuleContexts(Type_stmtContext.class);\r
+        }\r
+\r
+        public Min_elements_stmtContext min_elements_stmt(int i) {\r
+            return getRuleContext(Min_elements_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Default_stmtContext> default_stmt() {\r
+            return getRuleContexts(Default_stmtContext.class);\r
+        }\r
+\r
+        public Mandatory_stmtContext mandatory_stmt(int i) {\r
+            return getRuleContext(Mandatory_stmtContext.class, i);\r
+        }\r
+\r
+        public Config_stmtContext config_stmt(int i) {\r
+            return getRuleContext(Config_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public List<Min_elements_stmtContext> min_elements_stmt() {\r
+            return getRuleContexts(Min_elements_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Config_stmtContext> config_stmt() {\r
+            return getRuleContexts(Config_stmtContext.class);\r
+        }\r
+\r
+        public Max_elements_stmtContext max_elements_stmt(int i) {\r
+            return getRuleContext(Max_elements_stmtContext.class, i);\r
+        }\r
+\r
+        public Deviate_replace_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_deviate_replace_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterDeviate_replace_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitDeviate_replace_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitDeviate_replace_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Deviate_replace_stmtContext deviate_replace_stmt()\r
+            throws RecognitionException {\r
+        Deviate_replace_stmtContext _localctx = new Deviate_replace_stmtContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 8, RULE_deviate_replace_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(241);\r
+                match(DEVIATE_KEYWORD);\r
+                setState(242);\r
+                string();\r
+                setState(258);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(243);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(244);\r
+                        match(LEFT_BRACE);\r
+                        setState(254);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 13)) & ~0x3f) == 0 && ((1L << (_la - 13)) & ((1L << (UNITS_KEYWORD - 13))\r
+                                | (1L << (TYPE_KEYWORD - 13))\r
+                                | (1L << (MIN_ELEMENTS_KEYWORD - 13))\r
+                                | (1L << (MAX_ELEMENTS_KEYWORD - 13))\r
+                                | (1L << (MANDATORY_KEYWORD - 13))\r
+                                | (1L << (DEFAULT_KEYWORD - 13)) | (1L << (CONFIG_KEYWORD - 13)))) != 0)) {\r
+                            {\r
+                                setState(252);\r
+                                switch (_input.LA(1)) {\r
+                                case TYPE_KEYWORD: {\r
+                                    setState(245);\r
+                                    type_stmt();\r
+                                }\r
+                                    break;\r
+                                case UNITS_KEYWORD: {\r
+                                    setState(246);\r
+                                    units_stmt();\r
+                                }\r
+                                    break;\r
+                                case DEFAULT_KEYWORD: {\r
+                                    setState(247);\r
+                                    default_stmt();\r
+                                }\r
+                                    break;\r
+                                case CONFIG_KEYWORD: {\r
+                                    setState(248);\r
+                                    config_stmt();\r
+                                }\r
+                                    break;\r
+                                case MANDATORY_KEYWORD: {\r
+                                    setState(249);\r
+                                    mandatory_stmt();\r
+                                }\r
+                                    break;\r
+                                case MIN_ELEMENTS_KEYWORD: {\r
+                                    setState(250);\r
+                                    min_elements_stmt();\r
+                                }\r
+                                    break;\r
+                                case MAX_ELEMENTS_KEYWORD: {\r
+                                    setState(251);\r
+                                    max_elements_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(256);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(257);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Deviate_delete_stmtContext extends ParserRuleContext {\r
+        public Units_stmtContext units_stmt(int i) {\r
+            return getRuleContext(Units_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Default_stmtContext> default_stmt() {\r
+            return getRuleContexts(Default_stmtContext.class);\r
+        }\r
+\r
+        public Default_stmtContext default_stmt(int i) {\r
+            return getRuleContext(Default_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Units_stmtContext> units_stmt() {\r
+            return getRuleContexts(Units_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public List<Must_stmtContext> must_stmt() {\r
+            return getRuleContexts(Must_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Unique_stmtContext> unique_stmt() {\r
+            return getRuleContexts(Unique_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode DEVIATE_KEYWORD() {\r
+            return getToken(YangParser.DEVIATE_KEYWORD, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Must_stmtContext must_stmt(int i) {\r
+            return getRuleContext(Must_stmtContext.class, i);\r
+        }\r
+\r
+        public Unique_stmtContext unique_stmt(int i) {\r
+            return getRuleContext(Unique_stmtContext.class, i);\r
+        }\r
+\r
+        public Deviate_delete_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_deviate_delete_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterDeviate_delete_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitDeviate_delete_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitDeviate_delete_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Deviate_delete_stmtContext deviate_delete_stmt()\r
+            throws RecognitionException {\r
+        Deviate_delete_stmtContext _localctx = new Deviate_delete_stmtContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 10, RULE_deviate_delete_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(260);\r
+                match(DEVIATE_KEYWORD);\r
+                setState(261);\r
+                string();\r
+                setState(274);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(262);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(263);\r
+                        match(LEFT_BRACE);\r
+                        setState(270);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << UNITS_KEYWORD)\r
+                                | (1L << UNIQUE_KEYWORD) | (1L << MUST_KEYWORD) | (1L << DEFAULT_KEYWORD))) != 0)) {\r
+                            {\r
+                                setState(268);\r
+                                switch (_input.LA(1)) {\r
+                                case UNITS_KEYWORD: {\r
+                                    setState(264);\r
+                                    units_stmt();\r
+                                }\r
+                                    break;\r
+                                case MUST_KEYWORD: {\r
+                                    setState(265);\r
+                                    must_stmt();\r
+                                }\r
+                                    break;\r
+                                case UNIQUE_KEYWORD: {\r
+                                    setState(266);\r
+                                    unique_stmt();\r
+                                }\r
+                                    break;\r
+                                case DEFAULT_KEYWORD: {\r
+                                    setState(267);\r
+                                    default_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(272);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(273);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Deviate_add_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public Units_stmtContext units_stmt(int i) {\r
+            return getRuleContext(Units_stmtContext.class, i);\r
+        }\r
+\r
+        public Default_stmtContext default_stmt(int i) {\r
+            return getRuleContext(Default_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Units_stmtContext> units_stmt() {\r
+            return getRuleContexts(Units_stmtContext.class);\r
+        }\r
+\r
+        public List<Max_elements_stmtContext> max_elements_stmt() {\r
+            return getRuleContexts(Max_elements_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode DEVIATE_KEYWORD() {\r
+            return getToken(YangParser.DEVIATE_KEYWORD, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public List<Mandatory_stmtContext> mandatory_stmt() {\r
+            return getRuleContexts(Mandatory_stmtContext.class);\r
+        }\r
+\r
+        public Must_stmtContext must_stmt(int i) {\r
+            return getRuleContext(Must_stmtContext.class, i);\r
+        }\r
+\r
+        public Min_elements_stmtContext min_elements_stmt(int i) {\r
+            return getRuleContext(Min_elements_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Default_stmtContext> default_stmt() {\r
+            return getRuleContexts(Default_stmtContext.class);\r
+        }\r
+\r
+        public Mandatory_stmtContext mandatory_stmt(int i) {\r
+            return getRuleContext(Mandatory_stmtContext.class, i);\r
+        }\r
+\r
+        public Config_stmtContext config_stmt(int i) {\r
+            return getRuleContext(Config_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public List<Min_elements_stmtContext> min_elements_stmt() {\r
+            return getRuleContexts(Min_elements_stmtContext.class);\r
+        }\r
+\r
+        public List<Config_stmtContext> config_stmt() {\r
+            return getRuleContexts(Config_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Must_stmtContext> must_stmt() {\r
+            return getRuleContexts(Must_stmtContext.class);\r
+        }\r
+\r
+        public List<Unique_stmtContext> unique_stmt() {\r
+            return getRuleContexts(Unique_stmtContext.class);\r
+        }\r
+\r
+        public Max_elements_stmtContext max_elements_stmt(int i) {\r
+            return getRuleContext(Max_elements_stmtContext.class, i);\r
+        }\r
+\r
+        public Unique_stmtContext unique_stmt(int i) {\r
+            return getRuleContext(Unique_stmtContext.class, i);\r
+        }\r
+\r
+        public Deviate_add_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_deviate_add_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterDeviate_add_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitDeviate_add_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitDeviate_add_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Deviate_add_stmtContext deviate_add_stmt()\r
+            throws RecognitionException {\r
+        Deviate_add_stmtContext _localctx = new Deviate_add_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 12, RULE_deviate_add_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(276);\r
+                match(DEVIATE_KEYWORD);\r
+                setState(277);\r
+                string();\r
+                setState(294);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(278);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(279);\r
+                        match(LEFT_BRACE);\r
+                        setState(290);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 13)) & ~0x3f) == 0 && ((1L << (_la - 13)) & ((1L << (UNITS_KEYWORD - 13))\r
+                                | (1L << (UNIQUE_KEYWORD - 13))\r
+                                | (1L << (MUST_KEYWORD - 13))\r
+                                | (1L << (MIN_ELEMENTS_KEYWORD - 13))\r
+                                | (1L << (MAX_ELEMENTS_KEYWORD - 13))\r
+                                | (1L << (MANDATORY_KEYWORD - 13))\r
+                                | (1L << (DEFAULT_KEYWORD - 13)) | (1L << (CONFIG_KEYWORD - 13)))) != 0)) {\r
+                            {\r
+                                setState(288);\r
+                                switch (_input.LA(1)) {\r
+                                case UNITS_KEYWORD: {\r
+                                    setState(280);\r
+                                    units_stmt();\r
+                                }\r
+                                    break;\r
+                                case MUST_KEYWORD: {\r
+                                    setState(281);\r
+                                    must_stmt();\r
+                                }\r
+                                    break;\r
+                                case UNIQUE_KEYWORD: {\r
+                                    setState(282);\r
+                                    unique_stmt();\r
+                                }\r
+                                    break;\r
+                                case DEFAULT_KEYWORD: {\r
+                                    setState(283);\r
+                                    default_stmt();\r
+                                }\r
+                                    break;\r
+                                case CONFIG_KEYWORD: {\r
+                                    setState(284);\r
+                                    config_stmt();\r
+                                }\r
+                                    break;\r
+                                case MANDATORY_KEYWORD: {\r
+                                    setState(285);\r
+                                    mandatory_stmt();\r
+                                }\r
+                                    break;\r
+                                case MIN_ELEMENTS_KEYWORD: {\r
+                                    setState(286);\r
+                                    min_elements_stmt();\r
+                                }\r
+                                    break;\r
+                                case MAX_ELEMENTS_KEYWORD: {\r
+                                    setState(287);\r
+                                    max_elements_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(292);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(293);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Deviate_not_supported_stmtContext extends\r
+            ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt() {\r
+            return getRuleContext(Identifier_stmtContext.class, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode DEVIATE_KEYWORD() {\r
+            return getToken(YangParser.DEVIATE_KEYWORD, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Deviate_not_supported_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_deviate_not_supported_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .enterDeviate_not_supported_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .exitDeviate_not_supported_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitDeviate_not_supported_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Deviate_not_supported_stmtContext deviate_not_supported_stmt()\r
+            throws RecognitionException {\r
+        Deviate_not_supported_stmtContext _localctx = new Deviate_not_supported_stmtContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 14, RULE_deviate_not_supported_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(296);\r
+                match(DEVIATE_KEYWORD);\r
+                setState(297);\r
+                string();\r
+                setState(304);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(298);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(299);\r
+                        match(LEFT_BRACE);\r
+                        setState(301);\r
+                        _la = _input.LA(1);\r
+                        if (_la == IDENTIFIER) {\r
+                            {\r
+                                setState(300);\r
+                                identifier_stmt();\r
+                            }\r
+                        }\r
+\r
+                        setState(303);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Deviation_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode DEVIATION_KEYWORD() {\r
+            return getToken(YangParser.DEVIATION_KEYWORD, 0);\r
+        }\r
+\r
+        public Deviate_replace_stmtContext deviate_replace_stmt(int i) {\r
+            return getRuleContext(Deviate_replace_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Deviate_delete_stmtContext deviate_delete_stmt(int i) {\r
+            return getRuleContext(Deviate_delete_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Deviate_delete_stmtContext> deviate_delete_stmt() {\r
+            return getRuleContexts(Deviate_delete_stmtContext.class);\r
+        }\r
+\r
+        public Deviate_add_stmtContext deviate_add_stmt(int i) {\r
+            return getRuleContext(Deviate_add_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Deviate_add_stmtContext> deviate_add_stmt() {\r
+            return getRuleContexts(Deviate_add_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Deviate_replace_stmtContext> deviate_replace_stmt() {\r
+            return getRuleContexts(Deviate_replace_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public List<Deviate_not_supported_stmtContext> deviate_not_supported_stmt() {\r
+            return getRuleContexts(Deviate_not_supported_stmtContext.class);\r
+        }\r
+\r
+        public Deviate_not_supported_stmtContext deviate_not_supported_stmt(\r
+                int i) {\r
+            return getRuleContext(Deviate_not_supported_stmtContext.class, i);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Deviation_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_deviation_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterDeviation_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitDeviation_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitDeviation_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Deviation_stmtContext deviation_stmt()\r
+            throws RecognitionException {\r
+        Deviation_stmtContext _localctx = new Deviation_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 16, RULE_deviation_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(306);\r
+                match(DEVIATION_KEYWORD);\r
+                setState(307);\r
+                string();\r
+                setState(308);\r
+                match(LEFT_BRACE);\r
+                setState(315);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                do {\r
+                    {\r
+                        setState(315);\r
+                        switch (getInterpreter().adaptivePredict(_input, 17,\r
+                                _ctx)) {\r
+                        case 1: {\r
+                            setState(309);\r
+                            description_stmt();\r
+                        }\r
+                            break;\r
+\r
+                        case 2: {\r
+                            setState(310);\r
+                            reference_stmt();\r
+                        }\r
+                            break;\r
+\r
+                        case 3: {\r
+                            setState(311);\r
+                            deviate_not_supported_stmt();\r
+                        }\r
+                            break;\r
+\r
+                        case 4: {\r
+                            setState(312);\r
+                            deviate_add_stmt();\r
+                        }\r
+                            break;\r
+\r
+                        case 5: {\r
+                            setState(313);\r
+                            deviate_replace_stmt();\r
+                        }\r
+                            break;\r
+\r
+                        case 6: {\r
+                            setState(314);\r
+                            deviate_delete_stmt();\r
+                        }\r
+                            break;\r
+                        }\r
+                    }\r
+                    setState(317);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                } while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << REFERENCE_KEYWORD)\r
+                        | (1L << DEVIATE_KEYWORD) | (1L << DESCRIPTION_KEYWORD))) != 0));\r
+                setState(319);\r
+                match(RIGHT_BRACE);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Notification_stmtContext extends ParserRuleContext {\r
+        public List<Grouping_stmtContext> grouping_stmt() {\r
+            return getRuleContexts(Grouping_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Typedef_stmtContext typedef_stmt(int i) {\r
+            return getRuleContext(Typedef_stmtContext.class, i);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Grouping_stmtContext grouping_stmt(int i) {\r
+            return getRuleContext(Grouping_stmtContext.class, i);\r
+        }\r
+\r
+        public If_feature_stmtContext if_feature_stmt(int i) {\r
+            return getRuleContext(If_feature_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Data_def_stmtContext data_def_stmt(int i) {\r
+            return getRuleContext(Data_def_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Typedef_stmtContext> typedef_stmt() {\r
+            return getRuleContexts(Typedef_stmtContext.class);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public List<If_feature_stmtContext> if_feature_stmt() {\r
+            return getRuleContexts(If_feature_stmtContext.class);\r
+        }\r
+\r
+        public List<Data_def_stmtContext> data_def_stmt() {\r
+            return getRuleContexts(Data_def_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode NOTIFICATION_KEYWORD() {\r
+            return getToken(YangParser.NOTIFICATION_KEYWORD, 0);\r
+        }\r
+\r
+        public Notification_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_notification_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterNotification_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitNotification_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitNotification_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Notification_stmtContext notification_stmt()\r
+            throws RecognitionException {\r
+        Notification_stmtContext _localctx = new Notification_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 18, RULE_notification_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(321);\r
+                match(NOTIFICATION_KEYWORD);\r
+                setState(322);\r
+                string();\r
+                setState(338);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(323);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(324);\r
+                        match(LEFT_BRACE);\r
+                        setState(334);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 12)) & ~0x3f) == 0 && ((1L << (_la - 12)) & ((1L << (USES_KEYWORD - 12))\r
+                                | (1L << (TYPEDEF_KEYWORD - 12))\r
+                                | (1L << (STATUS_KEYWORD - 12))\r
+                                | (1L << (REFERENCE_KEYWORD - 12))\r
+                                | (1L << (LIST_KEYWORD - 12))\r
+                                | (1L << (LEAF_LIST_KEYWORD - 12))\r
+                                | (1L << (LEAF_KEYWORD - 12))\r
+                                | (1L << (IF_FEATURE_KEYWORD - 12))\r
+                                | (1L << (GROUPING_KEYWORD - 12))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 12))\r
+                                | (1L << (CONTAINER_KEYWORD - 12))\r
+                                | (1L << (CHOICE_KEYWORD - 12)) | (1L << (ANYXML_KEYWORD - 12)))) != 0)) {\r
+                            {\r
+                                setState(332);\r
+                                switch (_input.LA(1)) {\r
+                                case IF_FEATURE_KEYWORD: {\r
+                                    setState(325);\r
+                                    if_feature_stmt();\r
+                                }\r
+                                    break;\r
+                                case STATUS_KEYWORD: {\r
+                                    setState(326);\r
+                                    status_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(327);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(328);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                case TYPEDEF_KEYWORD: {\r
+                                    setState(329);\r
+                                    typedef_stmt();\r
+                                }\r
+                                    break;\r
+                                case GROUPING_KEYWORD: {\r
+                                    setState(330);\r
+                                    grouping_stmt();\r
+                                }\r
+                                    break;\r
+                                case USES_KEYWORD:\r
+                                case LIST_KEYWORD:\r
+                                case LEAF_LIST_KEYWORD:\r
+                                case LEAF_KEYWORD:\r
+                                case CONTAINER_KEYWORD:\r
+                                case CHOICE_KEYWORD:\r
+                                case ANYXML_KEYWORD: {\r
+                                    setState(331);\r
+                                    data_def_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(336);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(337);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Output_stmtContext extends ParserRuleContext {\r
+        public List<Grouping_stmtContext> grouping_stmt() {\r
+            return getRuleContexts(Grouping_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public Typedef_stmtContext typedef_stmt(int i) {\r
+            return getRuleContext(Typedef_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Data_def_stmtContext> data_def_stmt() {\r
+            return getRuleContexts(Data_def_stmtContext.class);\r
+        }\r
+\r
+        public Grouping_stmtContext grouping_stmt(int i) {\r
+            return getRuleContext(Grouping_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode OUTPUT_KEYWORD() {\r
+            return getToken(YangParser.OUTPUT_KEYWORD, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Data_def_stmtContext data_def_stmt(int i) {\r
+            return getRuleContext(Data_def_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Typedef_stmtContext> typedef_stmt() {\r
+            return getRuleContexts(Typedef_stmtContext.class);\r
+        }\r
+\r
+        public Output_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_output_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterOutput_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitOutput_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitOutput_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Output_stmtContext output_stmt() throws RecognitionException {\r
+        Output_stmtContext _localctx = new Output_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 20, RULE_output_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(340);\r
+                match(OUTPUT_KEYWORD);\r
+                setState(341);\r
+                match(LEFT_BRACE);\r
+                setState(345);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                do {\r
+                    {\r
+                        setState(345);\r
+                        switch (_input.LA(1)) {\r
+                        case TYPEDEF_KEYWORD: {\r
+                            setState(342);\r
+                            typedef_stmt();\r
+                        }\r
+                            break;\r
+                        case GROUPING_KEYWORD: {\r
+                            setState(343);\r
+                            grouping_stmt();\r
+                        }\r
+                            break;\r
+                        case USES_KEYWORD:\r
+                        case LIST_KEYWORD:\r
+                        case LEAF_LIST_KEYWORD:\r
+                        case LEAF_KEYWORD:\r
+                        case CONTAINER_KEYWORD:\r
+                        case CHOICE_KEYWORD:\r
+                        case ANYXML_KEYWORD: {\r
+                            setState(344);\r
+                            data_def_stmt();\r
+                        }\r
+                            break;\r
+                        default:\r
+                            throw new NoViableAltException(this);\r
+                        }\r
+                    }\r
+                    setState(347);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                } while (((((_la - 12)) & ~0x3f) == 0 && ((1L << (_la - 12)) & ((1L << (USES_KEYWORD - 12))\r
+                        | (1L << (TYPEDEF_KEYWORD - 12))\r
+                        | (1L << (LIST_KEYWORD - 12))\r
+                        | (1L << (LEAF_LIST_KEYWORD - 12))\r
+                        | (1L << (LEAF_KEYWORD - 12))\r
+                        | (1L << (GROUPING_KEYWORD - 12))\r
+                        | (1L << (CONTAINER_KEYWORD - 12))\r
+                        | (1L << (CHOICE_KEYWORD - 12)) | (1L << (ANYXML_KEYWORD - 12)))) != 0));\r
+                setState(349);\r
+                match(RIGHT_BRACE);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Input_stmtContext extends ParserRuleContext {\r
+        public List<Grouping_stmtContext> grouping_stmt() {\r
+            return getRuleContexts(Grouping_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public Typedef_stmtContext typedef_stmt(int i) {\r
+            return getRuleContext(Typedef_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode INPUT_KEYWORD() {\r
+            return getToken(YangParser.INPUT_KEYWORD, 0);\r
+        }\r
+\r
+        public List<Data_def_stmtContext> data_def_stmt() {\r
+            return getRuleContexts(Data_def_stmtContext.class);\r
+        }\r
+\r
+        public Grouping_stmtContext grouping_stmt(int i) {\r
+            return getRuleContext(Grouping_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Data_def_stmtContext data_def_stmt(int i) {\r
+            return getRuleContext(Data_def_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Typedef_stmtContext> typedef_stmt() {\r
+            return getRuleContexts(Typedef_stmtContext.class);\r
+        }\r
+\r
+        public Input_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_input_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterInput_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitInput_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitInput_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Input_stmtContext input_stmt() throws RecognitionException {\r
+        Input_stmtContext _localctx = new Input_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 22, RULE_input_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(351);\r
+                match(INPUT_KEYWORD);\r
+                setState(352);\r
+                match(LEFT_BRACE);\r
+                setState(356);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                do {\r
+                    {\r
+                        setState(356);\r
+                        switch (_input.LA(1)) {\r
+                        case TYPEDEF_KEYWORD: {\r
+                            setState(353);\r
+                            typedef_stmt();\r
+                        }\r
+                            break;\r
+                        case GROUPING_KEYWORD: {\r
+                            setState(354);\r
+                            grouping_stmt();\r
+                        }\r
+                            break;\r
+                        case USES_KEYWORD:\r
+                        case LIST_KEYWORD:\r
+                        case LEAF_LIST_KEYWORD:\r
+                        case LEAF_KEYWORD:\r
+                        case CONTAINER_KEYWORD:\r
+                        case CHOICE_KEYWORD:\r
+                        case ANYXML_KEYWORD: {\r
+                            setState(355);\r
+                            data_def_stmt();\r
+                        }\r
+                            break;\r
+                        default:\r
+                            throw new NoViableAltException(this);\r
+                        }\r
+                    }\r
+                    setState(358);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                } while (((((_la - 12)) & ~0x3f) == 0 && ((1L << (_la - 12)) & ((1L << (USES_KEYWORD - 12))\r
+                        | (1L << (TYPEDEF_KEYWORD - 12))\r
+                        | (1L << (LIST_KEYWORD - 12))\r
+                        | (1L << (LEAF_LIST_KEYWORD - 12))\r
+                        | (1L << (LEAF_KEYWORD - 12))\r
+                        | (1L << (GROUPING_KEYWORD - 12))\r
+                        | (1L << (CONTAINER_KEYWORD - 12))\r
+                        | (1L << (CHOICE_KEYWORD - 12)) | (1L << (ANYXML_KEYWORD - 12)))) != 0));\r
+                setState(360);\r
+                match(RIGHT_BRACE);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Rpc_stmtContext extends ParserRuleContext {\r
+        public List<Grouping_stmtContext> grouping_stmt() {\r
+            return getRuleContexts(Grouping_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public Output_stmtContext output_stmt(int i) {\r
+            return getRuleContext(Output_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Typedef_stmtContext typedef_stmt(int i) {\r
+            return getRuleContext(Typedef_stmtContext.class, i);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Grouping_stmtContext grouping_stmt(int i) {\r
+            return getRuleContext(Grouping_stmtContext.class, i);\r
+        }\r
+\r
+        public Input_stmtContext input_stmt(int i) {\r
+            return getRuleContext(Input_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Input_stmtContext> input_stmt() {\r
+            return getRuleContexts(Input_stmtContext.class);\r
+        }\r
+\r
+        public If_feature_stmtContext if_feature_stmt(int i) {\r
+            return getRuleContext(If_feature_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public List<Typedef_stmtContext> typedef_stmt() {\r
+            return getRuleContexts(Typedef_stmtContext.class);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public List<If_feature_stmtContext> if_feature_stmt() {\r
+            return getRuleContexts(If_feature_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Output_stmtContext> output_stmt() {\r
+            return getRuleContexts(Output_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode RPC_KEYWORD() {\r
+            return getToken(YangParser.RPC_KEYWORD, 0);\r
+        }\r
+\r
+        public Rpc_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_rpc_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterRpc_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitRpc_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRpc_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Rpc_stmtContext rpc_stmt() throws RecognitionException {\r
+        Rpc_stmtContext _localctx = new Rpc_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 24, RULE_rpc_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(362);\r
+                match(RPC_KEYWORD);\r
+                setState(363);\r
+                string();\r
+                setState(380);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(364);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(365);\r
+                        match(LEFT_BRACE);\r
+                        setState(376);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEF_KEYWORD)\r
+                                | (1L << STATUS_KEYWORD)\r
+                                | (1L << REFERENCE_KEYWORD)\r
+                                | (1L << OUTPUT_KEYWORD)\r
+                                | (1L << INPUT_KEYWORD)\r
+                                | (1L << IF_FEATURE_KEYWORD)\r
+                                | (1L << GROUPING_KEYWORD) | (1L << DESCRIPTION_KEYWORD))) != 0)) {\r
+                            {\r
+                                setState(374);\r
+                                switch (_input.LA(1)) {\r
+                                case IF_FEATURE_KEYWORD: {\r
+                                    setState(366);\r
+                                    if_feature_stmt();\r
+                                }\r
+                                    break;\r
+                                case STATUS_KEYWORD: {\r
+                                    setState(367);\r
+                                    status_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(368);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(369);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                case TYPEDEF_KEYWORD: {\r
+                                    setState(370);\r
+                                    typedef_stmt();\r
+                                }\r
+                                    break;\r
+                                case GROUPING_KEYWORD: {\r
+                                    setState(371);\r
+                                    grouping_stmt();\r
+                                }\r
+                                    break;\r
+                                case INPUT_KEYWORD: {\r
+                                    setState(372);\r
+                                    input_stmt();\r
+                                }\r
+                                    break;\r
+                                case OUTPUT_KEYWORD: {\r
+                                    setState(373);\r
+                                    output_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(378);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(379);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class When_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode WHEN_KEYWORD() {\r
+            return getToken(YangParser.WHEN_KEYWORD, 0);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public When_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_when_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterWhen_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitWhen_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitWhen_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final When_stmtContext when_stmt() throws RecognitionException {\r
+        When_stmtContext _localctx = new When_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 26, RULE_when_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(382);\r
+                match(WHEN_KEYWORD);\r
+                setState(383);\r
+                string();\r
+                setState(394);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(384);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(385);\r
+                        match(LEFT_BRACE);\r
+                        setState(390);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (_la == REFERENCE_KEYWORD\r
+                                || _la == DESCRIPTION_KEYWORD) {\r
+                            {\r
+                                setState(388);\r
+                                switch (_input.LA(1)) {\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(386);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(387);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(392);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(393);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Augment_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public List<When_stmtContext> when_stmt() {\r
+            return getRuleContexts(When_stmtContext.class);\r
+        }\r
+\r
+        public List<Case_stmtContext> case_stmt() {\r
+            return getRuleContexts(Case_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode AUGMENT_KEYWORD() {\r
+            return getToken(YangParser.AUGMENT_KEYWORD, 0);\r
+        }\r
+\r
+        public If_feature_stmtContext if_feature_stmt(int i) {\r
+            return getRuleContext(If_feature_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Data_def_stmtContext data_def_stmt(int i) {\r
+            return getRuleContext(Data_def_stmtContext.class, i);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public List<If_feature_stmtContext> if_feature_stmt() {\r
+            return getRuleContexts(If_feature_stmtContext.class);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Data_def_stmtContext> data_def_stmt() {\r
+            return getRuleContexts(Data_def_stmtContext.class);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public When_stmtContext when_stmt(int i) {\r
+            return getRuleContext(When_stmtContext.class, i);\r
+        }\r
+\r
+        public Case_stmtContext case_stmt(int i) {\r
+            return getRuleContext(Case_stmtContext.class, i);\r
+        }\r
+\r
+        public Augment_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_augment_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterAugment_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitAugment_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitAugment_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Augment_stmtContext augment_stmt() throws RecognitionException {\r
+        Augment_stmtContext _localctx = new Augment_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 28, RULE_augment_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(396);\r
+                match(AUGMENT_KEYWORD);\r
+                setState(397);\r
+                string();\r
+                setState(398);\r
+                match(LEFT_BRACE);\r
+                setState(407);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                do {\r
+                    {\r
+                        setState(407);\r
+                        switch (_input.LA(1)) {\r
+                        case IDENTIFIER: {\r
+                            setState(399);\r
+                            identifier_stmt();\r
+                        }\r
+                            break;\r
+                        case WHEN_KEYWORD: {\r
+                            setState(400);\r
+                            when_stmt();\r
+                        }\r
+                            break;\r
+                        case IF_FEATURE_KEYWORD: {\r
+                            setState(401);\r
+                            if_feature_stmt();\r
+                        }\r
+                            break;\r
+                        case STATUS_KEYWORD: {\r
+                            setState(402);\r
+                            status_stmt();\r
+                        }\r
+                            break;\r
+                        case DESCRIPTION_KEYWORD: {\r
+                            setState(403);\r
+                            description_stmt();\r
+                        }\r
+                            break;\r
+                        case REFERENCE_KEYWORD: {\r
+                            setState(404);\r
+                            reference_stmt();\r
+                        }\r
+                            break;\r
+                        case USES_KEYWORD:\r
+                        case LIST_KEYWORD:\r
+                        case LEAF_LIST_KEYWORD:\r
+                        case LEAF_KEYWORD:\r
+                        case CONTAINER_KEYWORD:\r
+                        case CHOICE_KEYWORD:\r
+                        case ANYXML_KEYWORD: {\r
+                            setState(405);\r
+                            data_def_stmt();\r
+                        }\r
+                            break;\r
+                        case CASE_KEYWORD: {\r
+                            setState(406);\r
+                            case_stmt();\r
+                        }\r
+                            break;\r
+                        default:\r
+                            throw new NoViableAltException(this);\r
+                        }\r
+                    }\r
+                    setState(409);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                } while (((((_la - 10)) & ~0x3f) == 0 && ((1L << (_la - 10)) & ((1L << (WHEN_KEYWORD - 10))\r
+                        | (1L << (USES_KEYWORD - 10))\r
+                        | (1L << (STATUS_KEYWORD - 10))\r
+                        | (1L << (REFERENCE_KEYWORD - 10))\r
+                        | (1L << (LIST_KEYWORD - 10))\r
+                        | (1L << (LEAF_LIST_KEYWORD - 10))\r
+                        | (1L << (LEAF_KEYWORD - 10))\r
+                        | (1L << (IF_FEATURE_KEYWORD - 10))\r
+                        | (1L << (DESCRIPTION_KEYWORD - 10))\r
+                        | (1L << (CONTAINER_KEYWORD - 10))\r
+                        | (1L << (CHOICE_KEYWORD - 10))\r
+                        | (1L << (CASE_KEYWORD - 10))\r
+                        | (1L << (ANYXML_KEYWORD - 10)) | (1L << (IDENTIFIER - 10)))) != 0));\r
+                setState(411);\r
+                match(RIGHT_BRACE);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Uses_augment_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public List<When_stmtContext> when_stmt() {\r
+            return getRuleContexts(When_stmtContext.class);\r
+        }\r
+\r
+        public List<Case_stmtContext> case_stmt() {\r
+            return getRuleContexts(Case_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode AUGMENT_KEYWORD() {\r
+            return getToken(YangParser.AUGMENT_KEYWORD, 0);\r
+        }\r
+\r
+        public If_feature_stmtContext if_feature_stmt(int i) {\r
+            return getRuleContext(If_feature_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Data_def_stmtContext data_def_stmt(int i) {\r
+            return getRuleContext(Data_def_stmtContext.class, i);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public List<If_feature_stmtContext> if_feature_stmt() {\r
+            return getRuleContexts(If_feature_stmtContext.class);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Data_def_stmtContext> data_def_stmt() {\r
+            return getRuleContexts(Data_def_stmtContext.class);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public When_stmtContext when_stmt(int i) {\r
+            return getRuleContext(When_stmtContext.class, i);\r
+        }\r
+\r
+        public Case_stmtContext case_stmt(int i) {\r
+            return getRuleContext(Case_stmtContext.class, i);\r
+        }\r
+\r
+        public Uses_augment_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_uses_augment_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterUses_augment_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitUses_augment_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitUses_augment_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Uses_augment_stmtContext uses_augment_stmt()\r
+            throws RecognitionException {\r
+        Uses_augment_stmtContext _localctx = new Uses_augment_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 30, RULE_uses_augment_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(413);\r
+                match(AUGMENT_KEYWORD);\r
+                setState(414);\r
+                string();\r
+                setState(415);\r
+                match(LEFT_BRACE);\r
+                setState(424);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                do {\r
+                    {\r
+                        setState(424);\r
+                        switch (_input.LA(1)) {\r
+                        case IDENTIFIER: {\r
+                            setState(416);\r
+                            identifier_stmt();\r
+                        }\r
+                            break;\r
+                        case WHEN_KEYWORD: {\r
+                            setState(417);\r
+                            when_stmt();\r
+                        }\r
+                            break;\r
+                        case IF_FEATURE_KEYWORD: {\r
+                            setState(418);\r
+                            if_feature_stmt();\r
+                        }\r
+                            break;\r
+                        case STATUS_KEYWORD: {\r
+                            setState(419);\r
+                            status_stmt();\r
+                        }\r
+                            break;\r
+                        case DESCRIPTION_KEYWORD: {\r
+                            setState(420);\r
+                            description_stmt();\r
+                        }\r
+                            break;\r
+                        case REFERENCE_KEYWORD: {\r
+                            setState(421);\r
+                            reference_stmt();\r
+                        }\r
+                            break;\r
+                        case USES_KEYWORD:\r
+                        case LIST_KEYWORD:\r
+                        case LEAF_LIST_KEYWORD:\r
+                        case LEAF_KEYWORD:\r
+                        case CONTAINER_KEYWORD:\r
+                        case CHOICE_KEYWORD:\r
+                        case ANYXML_KEYWORD: {\r
+                            setState(422);\r
+                            data_def_stmt();\r
+                        }\r
+                            break;\r
+                        case CASE_KEYWORD: {\r
+                            setState(423);\r
+                            case_stmt();\r
+                        }\r
+                            break;\r
+                        default:\r
+                            throw new NoViableAltException(this);\r
+                        }\r
+                    }\r
+                    setState(426);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                } while (((((_la - 10)) & ~0x3f) == 0 && ((1L << (_la - 10)) & ((1L << (WHEN_KEYWORD - 10))\r
+                        | (1L << (USES_KEYWORD - 10))\r
+                        | (1L << (STATUS_KEYWORD - 10))\r
+                        | (1L << (REFERENCE_KEYWORD - 10))\r
+                        | (1L << (LIST_KEYWORD - 10))\r
+                        | (1L << (LEAF_LIST_KEYWORD - 10))\r
+                        | (1L << (LEAF_KEYWORD - 10))\r
+                        | (1L << (IF_FEATURE_KEYWORD - 10))\r
+                        | (1L << (DESCRIPTION_KEYWORD - 10))\r
+                        | (1L << (CONTAINER_KEYWORD - 10))\r
+                        | (1L << (CHOICE_KEYWORD - 10))\r
+                        | (1L << (CASE_KEYWORD - 10))\r
+                        | (1L << (ANYXML_KEYWORD - 10)) | (1L << (IDENTIFIER - 10)))) != 0));\r
+                setState(428);\r
+                match(RIGHT_BRACE);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Refine_anyxml_stmtsContext extends ParserRuleContext {\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Mandatory_stmtContext mandatory_stmt(int i) {\r
+            return getRuleContext(Mandatory_stmtContext.class, i);\r
+        }\r
+\r
+        public Config_stmtContext config_stmt(int i) {\r
+            return getRuleContext(Config_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Config_stmtContext> config_stmt() {\r
+            return getRuleContexts(Config_stmtContext.class);\r
+        }\r
+\r
+        public List<Must_stmtContext> must_stmt() {\r
+            return getRuleContexts(Must_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Mandatory_stmtContext> mandatory_stmt() {\r
+            return getRuleContexts(Mandatory_stmtContext.class);\r
+        }\r
+\r
+        public Must_stmtContext must_stmt(int i) {\r
+            return getRuleContext(Must_stmtContext.class, i);\r
+        }\r
+\r
+        public Refine_anyxml_stmtsContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_refine_anyxml_stmts;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterRefine_anyxml_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitRefine_anyxml_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRefine_anyxml_stmts(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Refine_anyxml_stmtsContext refine_anyxml_stmts()\r
+            throws RecognitionException {\r
+        Refine_anyxml_stmtsContext _localctx = new Refine_anyxml_stmtsContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 32, RULE_refine_anyxml_stmts);\r
+        try {\r
+            int _alt;\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(437);\r
+                _errHandler.sync(this);\r
+                _alt = getInterpreter().adaptivePredict(_input, 37, _ctx);\r
+                while (_alt != 2 && _alt != -1) {\r
+                    if (_alt == 1) {\r
+                        {\r
+                            setState(435);\r
+                            switch (_input.LA(1)) {\r
+                            case MUST_KEYWORD: {\r
+                                setState(430);\r
+                                must_stmt();\r
+                            }\r
+                                break;\r
+                            case CONFIG_KEYWORD: {\r
+                                setState(431);\r
+                                config_stmt();\r
+                            }\r
+                                break;\r
+                            case MANDATORY_KEYWORD: {\r
+                                setState(432);\r
+                                mandatory_stmt();\r
+                            }\r
+                                break;\r
+                            case DESCRIPTION_KEYWORD: {\r
+                                setState(433);\r
+                                description_stmt();\r
+                            }\r
+                                break;\r
+                            case REFERENCE_KEYWORD: {\r
+                                setState(434);\r
+                                reference_stmt();\r
+                            }\r
+                                break;\r
+                            default:\r
+                                throw new NoViableAltException(this);\r
+                            }\r
+                        }\r
+                    }\r
+                    setState(439);\r
+                    _errHandler.sync(this);\r
+                    _alt = getInterpreter().adaptivePredict(_input, 37, _ctx);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Refine_case_stmtsContext extends ParserRuleContext {\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Refine_case_stmtsContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_refine_case_stmts;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterRefine_case_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitRefine_case_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRefine_case_stmts(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Refine_case_stmtsContext refine_case_stmts()\r
+            throws RecognitionException {\r
+        Refine_case_stmtsContext _localctx = new Refine_case_stmtsContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 34, RULE_refine_case_stmts);\r
+        try {\r
+            int _alt;\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(444);\r
+                _errHandler.sync(this);\r
+                _alt = getInterpreter().adaptivePredict(_input, 39, _ctx);\r
+                while (_alt != 2 && _alt != -1) {\r
+                    if (_alt == 1) {\r
+                        {\r
+                            setState(442);\r
+                            switch (_input.LA(1)) {\r
+                            case DESCRIPTION_KEYWORD: {\r
+                                setState(440);\r
+                                description_stmt();\r
+                            }\r
+                                break;\r
+                            case REFERENCE_KEYWORD: {\r
+                                setState(441);\r
+                                reference_stmt();\r
+                            }\r
+                                break;\r
+                            default:\r
+                                throw new NoViableAltException(this);\r
+                            }\r
+                        }\r
+                    }\r
+                    setState(446);\r
+                    _errHandler.sync(this);\r
+                    _alt = getInterpreter().adaptivePredict(_input, 39, _ctx);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Refine_choice_stmtsContext extends ParserRuleContext {\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public List<Default_stmtContext> default_stmt() {\r
+            return getRuleContexts(Default_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Default_stmtContext default_stmt(int i) {\r
+            return getRuleContext(Default_stmtContext.class, i);\r
+        }\r
+\r
+        public Mandatory_stmtContext mandatory_stmt(int i) {\r
+            return getRuleContext(Mandatory_stmtContext.class, i);\r
+        }\r
+\r
+        public Config_stmtContext config_stmt(int i) {\r
+            return getRuleContext(Config_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Config_stmtContext> config_stmt() {\r
+            return getRuleContexts(Config_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Mandatory_stmtContext> mandatory_stmt() {\r
+            return getRuleContexts(Mandatory_stmtContext.class);\r
+        }\r
+\r
+        public Refine_choice_stmtsContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_refine_choice_stmts;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterRefine_choice_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitRefine_choice_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRefine_choice_stmts(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Refine_choice_stmtsContext refine_choice_stmts()\r
+            throws RecognitionException {\r
+        Refine_choice_stmtsContext _localctx = new Refine_choice_stmtsContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 36, RULE_refine_choice_stmts);\r
+        try {\r
+            int _alt;\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(454);\r
+                _errHandler.sync(this);\r
+                _alt = getInterpreter().adaptivePredict(_input, 41, _ctx);\r
+                while (_alt != 2 && _alt != -1) {\r
+                    if (_alt == 1) {\r
+                        {\r
+                            setState(452);\r
+                            switch (_input.LA(1)) {\r
+                            case DEFAULT_KEYWORD: {\r
+                                setState(447);\r
+                                default_stmt();\r
+                            }\r
+                                break;\r
+                            case CONFIG_KEYWORD: {\r
+                                setState(448);\r
+                                config_stmt();\r
+                            }\r
+                                break;\r
+                            case MANDATORY_KEYWORD: {\r
+                                setState(449);\r
+                                mandatory_stmt();\r
+                            }\r
+                                break;\r
+                            case DESCRIPTION_KEYWORD: {\r
+                                setState(450);\r
+                                description_stmt();\r
+                            }\r
+                                break;\r
+                            case REFERENCE_KEYWORD: {\r
+                                setState(451);\r
+                                reference_stmt();\r
+                            }\r
+                                break;\r
+                            default:\r
+                                throw new NoViableAltException(this);\r
+                            }\r
+                        }\r
+                    }\r
+                    setState(456);\r
+                    _errHandler.sync(this);\r
+                    _alt = getInterpreter().adaptivePredict(_input, 41, _ctx);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Refine_list_stmtsContext extends ParserRuleContext {\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Config_stmtContext config_stmt(int i) {\r
+            return getRuleContext(Config_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Min_elements_stmtContext> min_elements_stmt() {\r
+            return getRuleContexts(Min_elements_stmtContext.class);\r
+        }\r
+\r
+        public List<Max_elements_stmtContext> max_elements_stmt() {\r
+            return getRuleContexts(Max_elements_stmtContext.class);\r
+        }\r
+\r
+        public List<Config_stmtContext> config_stmt() {\r
+            return getRuleContexts(Config_stmtContext.class);\r
+        }\r
+\r
+        public List<Must_stmtContext> must_stmt() {\r
+            return getRuleContexts(Must_stmtContext.class);\r
+        }\r
+\r
+        public Max_elements_stmtContext max_elements_stmt(int i) {\r
+            return getRuleContext(Max_elements_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Must_stmtContext must_stmt(int i) {\r
+            return getRuleContext(Must_stmtContext.class, i);\r
+        }\r
+\r
+        public Min_elements_stmtContext min_elements_stmt(int i) {\r
+            return getRuleContext(Min_elements_stmtContext.class, i);\r
+        }\r
+\r
+        public Refine_list_stmtsContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_refine_list_stmts;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterRefine_list_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitRefine_list_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRefine_list_stmts(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Refine_list_stmtsContext refine_list_stmts()\r
+            throws RecognitionException {\r
+        Refine_list_stmtsContext _localctx = new Refine_list_stmtsContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 38, RULE_refine_list_stmts);\r
+        try {\r
+            int _alt;\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(465);\r
+                _errHandler.sync(this);\r
+                _alt = getInterpreter().adaptivePredict(_input, 43, _ctx);\r
+                while (_alt != 2 && _alt != -1) {\r
+                    if (_alt == 1) {\r
+                        {\r
+                            setState(463);\r
+                            switch (_input.LA(1)) {\r
+                            case MUST_KEYWORD: {\r
+                                setState(457);\r
+                                must_stmt();\r
+                            }\r
+                                break;\r
+                            case CONFIG_KEYWORD: {\r
+                                setState(458);\r
+                                config_stmt();\r
+                            }\r
+                                break;\r
+                            case MIN_ELEMENTS_KEYWORD: {\r
+                                setState(459);\r
+                                min_elements_stmt();\r
+                            }\r
+                                break;\r
+                            case MAX_ELEMENTS_KEYWORD: {\r
+                                setState(460);\r
+                                max_elements_stmt();\r
+                            }\r
+                                break;\r
+                            case DESCRIPTION_KEYWORD: {\r
+                                setState(461);\r
+                                description_stmt();\r
+                            }\r
+                                break;\r
+                            case REFERENCE_KEYWORD: {\r
+                                setState(462);\r
+                                reference_stmt();\r
+                            }\r
+                                break;\r
+                            default:\r
+                                throw new NoViableAltException(this);\r
+                            }\r
+                        }\r
+                    }\r
+                    setState(467);\r
+                    _errHandler.sync(this);\r
+                    _alt = getInterpreter().adaptivePredict(_input, 43, _ctx);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Refine_leaf_list_stmtsContext extends ParserRuleContext {\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Config_stmtContext config_stmt(int i) {\r
+            return getRuleContext(Config_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Min_elements_stmtContext> min_elements_stmt() {\r
+            return getRuleContexts(Min_elements_stmtContext.class);\r
+        }\r
+\r
+        public List<Max_elements_stmtContext> max_elements_stmt() {\r
+            return getRuleContexts(Max_elements_stmtContext.class);\r
+        }\r
+\r
+        public List<Config_stmtContext> config_stmt() {\r
+            return getRuleContexts(Config_stmtContext.class);\r
+        }\r
+\r
+        public List<Must_stmtContext> must_stmt() {\r
+            return getRuleContexts(Must_stmtContext.class);\r
+        }\r
+\r
+        public Max_elements_stmtContext max_elements_stmt(int i) {\r
+            return getRuleContext(Max_elements_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Must_stmtContext must_stmt(int i) {\r
+            return getRuleContext(Must_stmtContext.class, i);\r
+        }\r
+\r
+        public Min_elements_stmtContext min_elements_stmt(int i) {\r
+            return getRuleContext(Min_elements_stmtContext.class, i);\r
+        }\r
+\r
+        public Refine_leaf_list_stmtsContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_refine_leaf_list_stmts;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .enterRefine_leaf_list_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .exitRefine_leaf_list_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRefine_leaf_list_stmts(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Refine_leaf_list_stmtsContext refine_leaf_list_stmts()\r
+            throws RecognitionException {\r
+        Refine_leaf_list_stmtsContext _localctx = new Refine_leaf_list_stmtsContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 40, RULE_refine_leaf_list_stmts);\r
+        try {\r
+            int _alt;\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(476);\r
+                _errHandler.sync(this);\r
+                _alt = getInterpreter().adaptivePredict(_input, 45, _ctx);\r
+                while (_alt != 2 && _alt != -1) {\r
+                    if (_alt == 1) {\r
+                        {\r
+                            setState(474);\r
+                            switch (_input.LA(1)) {\r
+                            case MUST_KEYWORD: {\r
+                                setState(468);\r
+                                must_stmt();\r
+                            }\r
+                                break;\r
+                            case CONFIG_KEYWORD: {\r
+                                setState(469);\r
+                                config_stmt();\r
+                            }\r
+                                break;\r
+                            case MIN_ELEMENTS_KEYWORD: {\r
+                                setState(470);\r
+                                min_elements_stmt();\r
+                            }\r
+                                break;\r
+                            case MAX_ELEMENTS_KEYWORD: {\r
+                                setState(471);\r
+                                max_elements_stmt();\r
+                            }\r
+                                break;\r
+                            case DESCRIPTION_KEYWORD: {\r
+                                setState(472);\r
+                                description_stmt();\r
+                            }\r
+                                break;\r
+                            case REFERENCE_KEYWORD: {\r
+                                setState(473);\r
+                                reference_stmt();\r
+                            }\r
+                                break;\r
+                            default:\r
+                                throw new NoViableAltException(this);\r
+                            }\r
+                        }\r
+                    }\r
+                    setState(478);\r
+                    _errHandler.sync(this);\r
+                    _alt = getInterpreter().adaptivePredict(_input, 45, _ctx);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Refine_leaf_stmtsContext extends ParserRuleContext {\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public List<Default_stmtContext> default_stmt() {\r
+            return getRuleContexts(Default_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Default_stmtContext default_stmt(int i) {\r
+            return getRuleContext(Default_stmtContext.class, i);\r
+        }\r
+\r
+        public Mandatory_stmtContext mandatory_stmt(int i) {\r
+            return getRuleContext(Mandatory_stmtContext.class, i);\r
+        }\r
+\r
+        public Config_stmtContext config_stmt(int i) {\r
+            return getRuleContext(Config_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Config_stmtContext> config_stmt() {\r
+            return getRuleContexts(Config_stmtContext.class);\r
+        }\r
+\r
+        public List<Must_stmtContext> must_stmt() {\r
+            return getRuleContexts(Must_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Mandatory_stmtContext> mandatory_stmt() {\r
+            return getRuleContexts(Mandatory_stmtContext.class);\r
+        }\r
+\r
+        public Must_stmtContext must_stmt(int i) {\r
+            return getRuleContext(Must_stmtContext.class, i);\r
+        }\r
+\r
+        public Refine_leaf_stmtsContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_refine_leaf_stmts;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterRefine_leaf_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitRefine_leaf_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRefine_leaf_stmts(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Refine_leaf_stmtsContext refine_leaf_stmts()\r
+            throws RecognitionException {\r
+        Refine_leaf_stmtsContext _localctx = new Refine_leaf_stmtsContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 42, RULE_refine_leaf_stmts);\r
+        try {\r
+            int _alt;\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(487);\r
+                _errHandler.sync(this);\r
+                _alt = getInterpreter().adaptivePredict(_input, 47, _ctx);\r
+                while (_alt != 2 && _alt != -1) {\r
+                    if (_alt == 1) {\r
+                        {\r
+                            setState(485);\r
+                            switch (_input.LA(1)) {\r
+                            case MUST_KEYWORD: {\r
+                                setState(479);\r
+                                must_stmt();\r
+                            }\r
+                                break;\r
+                            case DEFAULT_KEYWORD: {\r
+                                setState(480);\r
+                                default_stmt();\r
+                            }\r
+                                break;\r
+                            case CONFIG_KEYWORD: {\r
+                                setState(481);\r
+                                config_stmt();\r
+                            }\r
+                                break;\r
+                            case MANDATORY_KEYWORD: {\r
+                                setState(482);\r
+                                mandatory_stmt();\r
+                            }\r
+                                break;\r
+                            case DESCRIPTION_KEYWORD: {\r
+                                setState(483);\r
+                                description_stmt();\r
+                            }\r
+                                break;\r
+                            case REFERENCE_KEYWORD: {\r
+                                setState(484);\r
+                                reference_stmt();\r
+                            }\r
+                                break;\r
+                            default:\r
+                                throw new NoViableAltException(this);\r
+                            }\r
+                        }\r
+                    }\r
+                    setState(489);\r
+                    _errHandler.sync(this);\r
+                    _alt = getInterpreter().adaptivePredict(_input, 47, _ctx);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Refine_container_stmtsContext extends ParserRuleContext {\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public List<Presence_stmtContext> presence_stmt() {\r
+            return getRuleContexts(Presence_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Config_stmtContext config_stmt(int i) {\r
+            return getRuleContext(Config_stmtContext.class, i);\r
+        }\r
+\r
+        public Presence_stmtContext presence_stmt(int i) {\r
+            return getRuleContext(Presence_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Config_stmtContext> config_stmt() {\r
+            return getRuleContexts(Config_stmtContext.class);\r
+        }\r
+\r
+        public List<Must_stmtContext> must_stmt() {\r
+            return getRuleContexts(Must_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Must_stmtContext must_stmt(int i) {\r
+            return getRuleContext(Must_stmtContext.class, i);\r
+        }\r
+\r
+        public Refine_container_stmtsContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_refine_container_stmts;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .enterRefine_container_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .exitRefine_container_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRefine_container_stmts(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Refine_container_stmtsContext refine_container_stmts()\r
+            throws RecognitionException {\r
+        Refine_container_stmtsContext _localctx = new Refine_container_stmtsContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 44, RULE_refine_container_stmts);\r
+        try {\r
+            int _alt;\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(497);\r
+                _errHandler.sync(this);\r
+                _alt = getInterpreter().adaptivePredict(_input, 49, _ctx);\r
+                while (_alt != 2 && _alt != -1) {\r
+                    if (_alt == 1) {\r
+                        {\r
+                            setState(495);\r
+                            switch (_input.LA(1)) {\r
+                            case MUST_KEYWORD: {\r
+                                setState(490);\r
+                                must_stmt();\r
+                            }\r
+                                break;\r
+                            case PRESENCE_KEYWORD: {\r
+                                setState(491);\r
+                                presence_stmt();\r
+                            }\r
+                                break;\r
+                            case CONFIG_KEYWORD: {\r
+                                setState(492);\r
+                                config_stmt();\r
+                            }\r
+                                break;\r
+                            case DESCRIPTION_KEYWORD: {\r
+                                setState(493);\r
+                                description_stmt();\r
+                            }\r
+                                break;\r
+                            case REFERENCE_KEYWORD: {\r
+                                setState(494);\r
+                                reference_stmt();\r
+                            }\r
+                                break;\r
+                            default:\r
+                                throw new NoViableAltException(this);\r
+                            }\r
+                        }\r
+                    }\r
+                    setState(499);\r
+                    _errHandler.sync(this);\r
+                    _alt = getInterpreter().adaptivePredict(_input, 49, _ctx);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Refune_pomContext extends ParserRuleContext {\r
+        public Refine_list_stmtsContext refine_list_stmts() {\r
+            return getRuleContext(Refine_list_stmtsContext.class, 0);\r
+        }\r
+\r
+        public Refine_choice_stmtsContext refine_choice_stmts() {\r
+            return getRuleContext(Refine_choice_stmtsContext.class, 0);\r
+        }\r
+\r
+        public Refine_leaf_list_stmtsContext refine_leaf_list_stmts() {\r
+            return getRuleContext(Refine_leaf_list_stmtsContext.class, 0);\r
+        }\r
+\r
+        public Refine_case_stmtsContext refine_case_stmts() {\r
+            return getRuleContext(Refine_case_stmtsContext.class, 0);\r
+        }\r
+\r
+        public Refine_leaf_stmtsContext refine_leaf_stmts() {\r
+            return getRuleContext(Refine_leaf_stmtsContext.class, 0);\r
+        }\r
+\r
+        public Refine_anyxml_stmtsContext refine_anyxml_stmts() {\r
+            return getRuleContext(Refine_anyxml_stmtsContext.class, 0);\r
+        }\r
+\r
+        public Refine_container_stmtsContext refine_container_stmts() {\r
+            return getRuleContext(Refine_container_stmtsContext.class, 0);\r
+        }\r
+\r
+        public Refune_pomContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_refune_pom;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterRefune_pom(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitRefune_pom(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRefune_pom(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Refune_pomContext refune_pom() throws RecognitionException {\r
+        Refune_pomContext _localctx = new Refune_pomContext(_ctx, getState());\r
+        enterRule(_localctx, 46, RULE_refune_pom);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(507);\r
+                switch (getInterpreter().adaptivePredict(_input, 50, _ctx)) {\r
+                case 1: {\r
+                    setState(500);\r
+                    refine_container_stmts();\r
+                }\r
+                    break;\r
+\r
+                case 2: {\r
+                    setState(501);\r
+                    refine_leaf_stmts();\r
+                }\r
+                    break;\r
+\r
+                case 3: {\r
+                    setState(502);\r
+                    refine_leaf_list_stmts();\r
+                }\r
+                    break;\r
+\r
+                case 4: {\r
+                    setState(503);\r
+                    refine_list_stmts();\r
+                }\r
+                    break;\r
+\r
+                case 5: {\r
+                    setState(504);\r
+                    refine_choice_stmts();\r
+                }\r
+                    break;\r
+\r
+                case 6: {\r
+                    setState(505);\r
+                    refine_case_stmts();\r
+                }\r
+                    break;\r
+\r
+                case 7: {\r
+                    setState(506);\r
+                    refine_anyxml_stmts();\r
+                }\r
+                    break;\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Refine_stmtContext extends ParserRuleContext {\r
+        public List<Refune_pomContext> refune_pom() {\r
+            return getRuleContexts(Refune_pomContext.class);\r
+        }\r
+\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public Refune_pomContext refune_pom(int i) {\r
+            return getRuleContext(Refune_pomContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public TerminalNode REFINE_KEYWORD() {\r
+            return getToken(YangParser.REFINE_KEYWORD, 0);\r
+        }\r
+\r
+        public Refine_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_refine_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterRefine_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitRefine_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRefine_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Refine_stmtContext refine_stmt() throws RecognitionException {\r
+        Refine_stmtContext _localctx = new Refine_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 48, RULE_refine_stmt);\r
+        try {\r
+            int _alt;\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(509);\r
+                match(REFINE_KEYWORD);\r
+                setState(510);\r
+                string();\r
+                setState(520);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(511);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(512);\r
+                        match(LEFT_BRACE);\r
+                        setState(514);\r
+                        _errHandler.sync(this);\r
+                        _alt = getInterpreter().adaptivePredict(_input, 51,\r
+                                _ctx);\r
+                        do {\r
+                            switch (_alt) {\r
+                            case 1: {\r
+                                {\r
+                                    setState(513);\r
+                                    refune_pom();\r
+                                }\r
+                            }\r
+                                break;\r
+                            default:\r
+                                throw new NoViableAltException(this);\r
+                            }\r
+                            setState(516);\r
+                            _errHandler.sync(this);\r
+                            _alt = getInterpreter().adaptivePredict(_input, 51,\r
+                                    _ctx);\r
+                        } while (_alt != 2 && _alt != -1);\r
+                        setState(518);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Uses_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public List<When_stmtContext> when_stmt() {\r
+            return getRuleContexts(When_stmtContext.class);\r
+        }\r
+\r
+        public List<Uses_augment_stmtContext> uses_augment_stmt() {\r
+            return getRuleContexts(Uses_augment_stmtContext.class);\r
+        }\r
+\r
+        public If_feature_stmtContext if_feature_stmt(int i) {\r
+            return getRuleContext(If_feature_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode USES_KEYWORD() {\r
+            return getToken(YangParser.USES_KEYWORD, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public List<If_feature_stmtContext> if_feature_stmt() {\r
+            return getRuleContexts(If_feature_stmtContext.class);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public Refine_stmtContext refine_stmt(int i) {\r
+            return getRuleContext(Refine_stmtContext.class, i);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public When_stmtContext when_stmt(int i) {\r
+            return getRuleContext(When_stmtContext.class, i);\r
+        }\r
+\r
+        public Uses_augment_stmtContext uses_augment_stmt(int i) {\r
+            return getRuleContext(Uses_augment_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Refine_stmtContext> refine_stmt() {\r
+            return getRuleContexts(Refine_stmtContext.class);\r
+        }\r
+\r
+        public Uses_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_uses_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterUses_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitUses_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitUses_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Uses_stmtContext uses_stmt() throws RecognitionException {\r
+        Uses_stmtContext _localctx = new Uses_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 50, RULE_uses_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(522);\r
+                match(USES_KEYWORD);\r
+                setState(523);\r
+                string();\r
+                setState(540);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(524);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(525);\r
+                        match(LEFT_BRACE);\r
+                        setState(536);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 10)) & ~0x3f) == 0 && ((1L << (_la - 10)) & ((1L << (WHEN_KEYWORD - 10))\r
+                                | (1L << (STATUS_KEYWORD - 10))\r
+                                | (1L << (REFINE_KEYWORD - 10))\r
+                                | (1L << (REFERENCE_KEYWORD - 10))\r
+                                | (1L << (IF_FEATURE_KEYWORD - 10))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 10))\r
+                                | (1L << (AUGMENT_KEYWORD - 10)) | (1L << (IDENTIFIER - 10)))) != 0)) {\r
+                            {\r
+                                setState(534);\r
+                                switch (_input.LA(1)) {\r
+                                case IDENTIFIER: {\r
+                                    setState(526);\r
+                                    identifier_stmt();\r
+                                }\r
+                                    break;\r
+                                case WHEN_KEYWORD: {\r
+                                    setState(527);\r
+                                    when_stmt();\r
+                                }\r
+                                    break;\r
+                                case IF_FEATURE_KEYWORD: {\r
+                                    setState(528);\r
+                                    if_feature_stmt();\r
+                                }\r
+                                    break;\r
+                                case STATUS_KEYWORD: {\r
+                                    setState(529);\r
+                                    status_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(530);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(531);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFINE_KEYWORD: {\r
+                                    setState(532);\r
+                                    refine_stmt();\r
+                                }\r
+                                    break;\r
+                                case AUGMENT_KEYWORD: {\r
+                                    setState(533);\r
+                                    uses_augment_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(538);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(539);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Anyxml_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public List<When_stmtContext> when_stmt() {\r
+            return getRuleContexts(When_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode ANYXML_KEYWORD() {\r
+            return getToken(YangParser.ANYXML_KEYWORD, 0);\r
+        }\r
+\r
+        public If_feature_stmtContext if_feature_stmt(int i) {\r
+            return getRuleContext(If_feature_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Mandatory_stmtContext> mandatory_stmt() {\r
+            return getRuleContexts(Mandatory_stmtContext.class);\r
+        }\r
+\r
+        public Must_stmtContext must_stmt(int i) {\r
+            return getRuleContext(Must_stmtContext.class, i);\r
+        }\r
+\r
+        public List<If_feature_stmtContext> if_feature_stmt() {\r
+            return getRuleContexts(If_feature_stmtContext.class);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public Mandatory_stmtContext mandatory_stmt(int i) {\r
+            return getRuleContext(Mandatory_stmtContext.class, i);\r
+        }\r
+\r
+        public Config_stmtContext config_stmt(int i) {\r
+            return getRuleContext(Config_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public List<Config_stmtContext> config_stmt() {\r
+            return getRuleContexts(Config_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public List<Must_stmtContext> must_stmt() {\r
+            return getRuleContexts(Must_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public When_stmtContext when_stmt(int i) {\r
+            return getRuleContext(When_stmtContext.class, i);\r
+        }\r
+\r
+        public Anyxml_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_anyxml_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterAnyxml_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitAnyxml_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitAnyxml_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Anyxml_stmtContext anyxml_stmt() throws RecognitionException {\r
+        Anyxml_stmtContext _localctx = new Anyxml_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 52, RULE_anyxml_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(542);\r
+                match(ANYXML_KEYWORD);\r
+                setState(543);\r
+                string();\r
+                setState(561);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(544);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(545);\r
+                        match(LEFT_BRACE);\r
+                        setState(557);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 10)) & ~0x3f) == 0 && ((1L << (_la - 10)) & ((1L << (WHEN_KEYWORD - 10))\r
+                                | (1L << (STATUS_KEYWORD - 10))\r
+                                | (1L << (REFERENCE_KEYWORD - 10))\r
+                                | (1L << (MUST_KEYWORD - 10))\r
+                                | (1L << (MANDATORY_KEYWORD - 10))\r
+                                | (1L << (IF_FEATURE_KEYWORD - 10))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 10))\r
+                                | (1L << (CONFIG_KEYWORD - 10)) | (1L << (IDENTIFIER - 10)))) != 0)) {\r
+                            {\r
+                                setState(555);\r
+                                switch (_input.LA(1)) {\r
+                                case IDENTIFIER: {\r
+                                    setState(546);\r
+                                    identifier_stmt();\r
+                                }\r
+                                    break;\r
+                                case WHEN_KEYWORD: {\r
+                                    setState(547);\r
+                                    when_stmt();\r
+                                }\r
+                                    break;\r
+                                case IF_FEATURE_KEYWORD: {\r
+                                    setState(548);\r
+                                    if_feature_stmt();\r
+                                }\r
+                                    break;\r
+                                case MUST_KEYWORD: {\r
+                                    setState(549);\r
+                                    must_stmt();\r
+                                }\r
+                                    break;\r
+                                case CONFIG_KEYWORD: {\r
+                                    setState(550);\r
+                                    config_stmt();\r
+                                }\r
+                                    break;\r
+                                case MANDATORY_KEYWORD: {\r
+                                    setState(551);\r
+                                    mandatory_stmt();\r
+                                }\r
+                                    break;\r
+                                case STATUS_KEYWORD: {\r
+                                    setState(552);\r
+                                    status_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(553);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(554);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(559);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(560);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Case_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public List<When_stmtContext> when_stmt() {\r
+            return getRuleContexts(When_stmtContext.class);\r
+        }\r
+\r
+        public If_feature_stmtContext if_feature_stmt(int i) {\r
+            return getRuleContext(If_feature_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Data_def_stmtContext data_def_stmt(int i) {\r
+            return getRuleContext(Data_def_stmtContext.class, i);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public List<If_feature_stmtContext> if_feature_stmt() {\r
+            return getRuleContexts(If_feature_stmtContext.class);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode CASE_KEYWORD() {\r
+            return getToken(YangParser.CASE_KEYWORD, 0);\r
+        }\r
+\r
+        public List<Data_def_stmtContext> data_def_stmt() {\r
+            return getRuleContexts(Data_def_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public When_stmtContext when_stmt(int i) {\r
+            return getRuleContext(When_stmtContext.class, i);\r
+        }\r
+\r
+        public Case_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_case_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterCase_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitCase_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitCase_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Case_stmtContext case_stmt() throws RecognitionException {\r
+        Case_stmtContext _localctx = new Case_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 54, RULE_case_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(563);\r
+                match(CASE_KEYWORD);\r
+                setState(564);\r
+                string();\r
+                setState(580);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(565);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(566);\r
+                        match(LEFT_BRACE);\r
+                        setState(576);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 10)) & ~0x3f) == 0 && ((1L << (_la - 10)) & ((1L << (WHEN_KEYWORD - 10))\r
+                                | (1L << (USES_KEYWORD - 10))\r
+                                | (1L << (STATUS_KEYWORD - 10))\r
+                                | (1L << (REFERENCE_KEYWORD - 10))\r
+                                | (1L << (LIST_KEYWORD - 10))\r
+                                | (1L << (LEAF_LIST_KEYWORD - 10))\r
+                                | (1L << (LEAF_KEYWORD - 10))\r
+                                | (1L << (IF_FEATURE_KEYWORD - 10))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 10))\r
+                                | (1L << (CONTAINER_KEYWORD - 10))\r
+                                | (1L << (CHOICE_KEYWORD - 10))\r
+                                | (1L << (ANYXML_KEYWORD - 10)) | (1L << (IDENTIFIER - 10)))) != 0)) {\r
+                            {\r
+                                setState(574);\r
+                                switch (_input.LA(1)) {\r
+                                case IDENTIFIER: {\r
+                                    setState(567);\r
+                                    identifier_stmt();\r
+                                }\r
+                                    break;\r
+                                case WHEN_KEYWORD: {\r
+                                    setState(568);\r
+                                    when_stmt();\r
+                                }\r
+                                    break;\r
+                                case IF_FEATURE_KEYWORD: {\r
+                                    setState(569);\r
+                                    if_feature_stmt();\r
+                                }\r
+                                    break;\r
+                                case STATUS_KEYWORD: {\r
+                                    setState(570);\r
+                                    status_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(571);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(572);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                case USES_KEYWORD:\r
+                                case LIST_KEYWORD:\r
+                                case LEAF_LIST_KEYWORD:\r
+                                case LEAF_KEYWORD:\r
+                                case CONTAINER_KEYWORD:\r
+                                case CHOICE_KEYWORD:\r
+                                case ANYXML_KEYWORD: {\r
+                                    setState(573);\r
+                                    data_def_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(578);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(579);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Short_case_stmtContext extends ParserRuleContext {\r
+        public Anyxml_stmtContext anyxml_stmt() {\r
+            return getRuleContext(Anyxml_stmtContext.class, 0);\r
+        }\r
+\r
+        public List_stmtContext list_stmt() {\r
+            return getRuleContext(List_stmtContext.class, 0);\r
+        }\r
+\r
+        public Leaf_stmtContext leaf_stmt() {\r
+            return getRuleContext(Leaf_stmtContext.class, 0);\r
+        }\r
+\r
+        public Container_stmtContext container_stmt() {\r
+            return getRuleContext(Container_stmtContext.class, 0);\r
+        }\r
+\r
+        public Leaf_list_stmtContext leaf_list_stmt() {\r
+            return getRuleContext(Leaf_list_stmtContext.class, 0);\r
+        }\r
+\r
+        public Short_case_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_short_case_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterShort_case_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitShort_case_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitShort_case_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Short_case_stmtContext short_case_stmt()\r
+            throws RecognitionException {\r
+        Short_case_stmtContext _localctx = new Short_case_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 56, RULE_short_case_stmt);\r
+        try {\r
+            setState(587);\r
+            switch (_input.LA(1)) {\r
+            case CONTAINER_KEYWORD:\r
+                enterOuterAlt(_localctx, 1);\r
+                {\r
+                    setState(582);\r
+                    container_stmt();\r
+                }\r
+                break;\r
+            case LEAF_KEYWORD:\r
+                enterOuterAlt(_localctx, 2);\r
+                {\r
+                    setState(583);\r
+                    leaf_stmt();\r
+                }\r
+                break;\r
+            case LEAF_LIST_KEYWORD:\r
+                enterOuterAlt(_localctx, 3);\r
+                {\r
+                    setState(584);\r
+                    leaf_list_stmt();\r
+                }\r
+                break;\r
+            case LIST_KEYWORD:\r
+                enterOuterAlt(_localctx, 4);\r
+                {\r
+                    setState(585);\r
+                    list_stmt();\r
+                }\r
+                break;\r
+            case ANYXML_KEYWORD:\r
+                enterOuterAlt(_localctx, 5);\r
+                {\r
+                    setState(586);\r
+                    anyxml_stmt();\r
+                }\r
+                break;\r
+            default:\r
+                throw new NoViableAltException(this);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Choice_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Default_stmtContext default_stmt(int i) {\r
+            return getRuleContext(Default_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode CHOICE_KEYWORD() {\r
+            return getToken(YangParser.CHOICE_KEYWORD, 0);\r
+        }\r
+\r
+        public List<When_stmtContext> when_stmt() {\r
+            return getRuleContexts(When_stmtContext.class);\r
+        }\r
+\r
+        public List<Case_stmtContext> case_stmt() {\r
+            return getRuleContexts(Case_stmtContext.class);\r
+        }\r
+\r
+        public If_feature_stmtContext if_feature_stmt(int i) {\r
+            return getRuleContext(If_feature_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Mandatory_stmtContext> mandatory_stmt() {\r
+            return getRuleContexts(Mandatory_stmtContext.class);\r
+        }\r
+\r
+        public List<If_feature_stmtContext> if_feature_stmt() {\r
+            return getRuleContexts(If_feature_stmtContext.class);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Default_stmtContext> default_stmt() {\r
+            return getRuleContexts(Default_stmtContext.class);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public Mandatory_stmtContext mandatory_stmt(int i) {\r
+            return getRuleContext(Mandatory_stmtContext.class, i);\r
+        }\r
+\r
+        public Config_stmtContext config_stmt(int i) {\r
+            return getRuleContext(Config_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public Short_case_stmtContext short_case_stmt(int i) {\r
+            return getRuleContext(Short_case_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Short_case_stmtContext> short_case_stmt() {\r
+            return getRuleContexts(Short_case_stmtContext.class);\r
+        }\r
+\r
+        public List<Config_stmtContext> config_stmt() {\r
+            return getRuleContexts(Config_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public When_stmtContext when_stmt(int i) {\r
+            return getRuleContext(When_stmtContext.class, i);\r
+        }\r
+\r
+        public Case_stmtContext case_stmt(int i) {\r
+            return getRuleContext(Case_stmtContext.class, i);\r
+        }\r
+\r
+        public Choice_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_choice_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterChoice_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitChoice_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitChoice_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Choice_stmtContext choice_stmt() throws RecognitionException {\r
+        Choice_stmtContext _localctx = new Choice_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 58, RULE_choice_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(589);\r
+                match(CHOICE_KEYWORD);\r
+                setState(590);\r
+                string();\r
+                setState(610);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(591);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(592);\r
+                        match(LEFT_BRACE);\r
+                        setState(606);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 10)) & ~0x3f) == 0 && ((1L << (_la - 10)) & ((1L << (WHEN_KEYWORD - 10))\r
+                                | (1L << (STATUS_KEYWORD - 10))\r
+                                | (1L << (REFERENCE_KEYWORD - 10))\r
+                                | (1L << (MANDATORY_KEYWORD - 10))\r
+                                | (1L << (LIST_KEYWORD - 10))\r
+                                | (1L << (LEAF_LIST_KEYWORD - 10))\r
+                                | (1L << (LEAF_KEYWORD - 10))\r
+                                | (1L << (IF_FEATURE_KEYWORD - 10))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 10))\r
+                                | (1L << (DEFAULT_KEYWORD - 10))\r
+                                | (1L << (CONTAINER_KEYWORD - 10))\r
+                                | (1L << (CONFIG_KEYWORD - 10))\r
+                                | (1L << (CASE_KEYWORD - 10))\r
+                                | (1L << (ANYXML_KEYWORD - 10)) | (1L << (IDENTIFIER - 10)))) != 0)) {\r
+                            {\r
+                                setState(604);\r
+                                switch (_input.LA(1)) {\r
+                                case IDENTIFIER: {\r
+                                    setState(593);\r
+                                    identifier_stmt();\r
+                                }\r
+                                    break;\r
+                                case WHEN_KEYWORD: {\r
+                                    setState(594);\r
+                                    when_stmt();\r
+                                }\r
+                                    break;\r
+                                case IF_FEATURE_KEYWORD: {\r
+                                    setState(595);\r
+                                    if_feature_stmt();\r
+                                }\r
+                                    break;\r
+                                case DEFAULT_KEYWORD: {\r
+                                    setState(596);\r
+                                    default_stmt();\r
+                                }\r
+                                    break;\r
+                                case CONFIG_KEYWORD: {\r
+                                    setState(597);\r
+                                    config_stmt();\r
+                                }\r
+                                    break;\r
+                                case MANDATORY_KEYWORD: {\r
+                                    setState(598);\r
+                                    mandatory_stmt();\r
+                                }\r
+                                    break;\r
+                                case STATUS_KEYWORD: {\r
+                                    setState(599);\r
+                                    status_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(600);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(601);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                case LIST_KEYWORD:\r
+                                case LEAF_LIST_KEYWORD:\r
+                                case LEAF_KEYWORD:\r
+                                case CONTAINER_KEYWORD:\r
+                                case ANYXML_KEYWORD: {\r
+                                    setState(602);\r
+                                    short_case_stmt();\r
+                                }\r
+                                    break;\r
+                                case CASE_KEYWORD: {\r
+                                    setState(603);\r
+                                    case_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(608);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(609);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Unique_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode UNIQUE_KEYWORD() {\r
+            return getToken(YangParser.UNIQUE_KEYWORD, 0);\r
+        }\r
+\r
+        public Unique_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_unique_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterUnique_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitUnique_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitUnique_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Unique_stmtContext unique_stmt() throws RecognitionException {\r
+        Unique_stmtContext _localctx = new Unique_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 60, RULE_unique_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(612);\r
+                match(UNIQUE_KEYWORD);\r
+                setState(613);\r
+                string();\r
+                setState(614);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Key_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode KEY_KEYWORD() {\r
+            return getToken(YangParser.KEY_KEYWORD, 0);\r
+        }\r
+\r
+        public Key_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_key_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterKey_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitKey_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitKey_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Key_stmtContext key_stmt() throws RecognitionException {\r
+        Key_stmtContext _localctx = new Key_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 62, RULE_key_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(616);\r
+                match(KEY_KEYWORD);\r
+                setState(617);\r
+                string();\r
+                setState(618);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class List_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<When_stmtContext> when_stmt() {\r
+            return getRuleContexts(When_stmtContext.class);\r
+        }\r
+\r
+        public List<Max_elements_stmtContext> max_elements_stmt() {\r
+            return getRuleContexts(Max_elements_stmtContext.class);\r
+        }\r
+\r
+        public Data_def_stmtContext data_def_stmt(int i) {\r
+            return getRuleContext(Data_def_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Typedef_stmtContext> typedef_stmt() {\r
+            return getRuleContexts(Typedef_stmtContext.class);\r
+        }\r
+\r
+        public Min_elements_stmtContext min_elements_stmt(int i) {\r
+            return getRuleContext(Min_elements_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Data_def_stmtContext> data_def_stmt() {\r
+            return getRuleContexts(Data_def_stmtContext.class);\r
+        }\r
+\r
+        public Config_stmtContext config_stmt(int i) {\r
+            return getRuleContext(Config_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Min_elements_stmtContext> min_elements_stmt() {\r
+            return getRuleContexts(Min_elements_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public When_stmtContext when_stmt(int i) {\r
+            return getRuleContext(When_stmtContext.class, i);\r
+        }\r
+\r
+        public Unique_stmtContext unique_stmt(int i) {\r
+            return getRuleContext(Unique_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Grouping_stmtContext> grouping_stmt() {\r
+            return getRuleContexts(Grouping_stmtContext.class);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Typedef_stmtContext typedef_stmt(int i) {\r
+            return getRuleContext(Typedef_stmtContext.class, i);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Ordered_by_stmtContext ordered_by_stmt(int i) {\r
+            return getRuleContext(Ordered_by_stmtContext.class, i);\r
+        }\r
+\r
+        public Grouping_stmtContext grouping_stmt(int i) {\r
+            return getRuleContext(Grouping_stmtContext.class, i);\r
+        }\r
+\r
+        public If_feature_stmtContext if_feature_stmt(int i) {\r
+            return getRuleContext(If_feature_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Ordered_by_stmtContext> ordered_by_stmt() {\r
+            return getRuleContexts(Ordered_by_stmtContext.class);\r
+        }\r
+\r
+        public Must_stmtContext must_stmt(int i) {\r
+            return getRuleContext(Must_stmtContext.class, i);\r
+        }\r
+\r
+        public List<If_feature_stmtContext> if_feature_stmt() {\r
+            return getRuleContexts(If_feature_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode LIST_KEYWORD() {\r
+            return getToken(YangParser.LIST_KEYWORD, 0);\r
+        }\r
+\r
+        public Key_stmtContext key_stmt(int i) {\r
+            return getRuleContext(Key_stmtContext.class, i);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public List<Must_stmtContext> must_stmt() {\r
+            return getRuleContexts(Must_stmtContext.class);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Config_stmtContext> config_stmt() {\r
+            return getRuleContexts(Config_stmtContext.class);\r
+        }\r
+\r
+        public List<Unique_stmtContext> unique_stmt() {\r
+            return getRuleContexts(Unique_stmtContext.class);\r
+        }\r
+\r
+        public Max_elements_stmtContext max_elements_stmt(int i) {\r
+            return getRuleContext(Max_elements_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Key_stmtContext> key_stmt() {\r
+            return getRuleContexts(Key_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public List_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_list_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterList_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitList_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitList_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final List_stmtContext list_stmt() throws RecognitionException {\r
+        List_stmtContext _localctx = new List_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 64, RULE_list_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(620);\r
+                match(LIST_KEYWORD);\r
+                setState(621);\r
+                string();\r
+                setState(622);\r
+                match(LEFT_BRACE);\r
+                setState(639);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                do {\r
+                    {\r
+                        setState(639);\r
+                        switch (_input.LA(1)) {\r
+                        case IDENTIFIER: {\r
+                            setState(623);\r
+                            identifier_stmt();\r
+                        }\r
+                            break;\r
+                        case WHEN_KEYWORD: {\r
+                            setState(624);\r
+                            when_stmt();\r
+                        }\r
+                            break;\r
+                        case IF_FEATURE_KEYWORD: {\r
+                            setState(625);\r
+                            if_feature_stmt();\r
+                        }\r
+                            break;\r
+                        case MUST_KEYWORD: {\r
+                            setState(626);\r
+                            must_stmt();\r
+                        }\r
+                            break;\r
+                        case KEY_KEYWORD: {\r
+                            setState(627);\r
+                            key_stmt();\r
+                        }\r
+                            break;\r
+                        case UNIQUE_KEYWORD: {\r
+                            setState(628);\r
+                            unique_stmt();\r
+                        }\r
+                            break;\r
+                        case CONFIG_KEYWORD: {\r
+                            setState(629);\r
+                            config_stmt();\r
+                        }\r
+                            break;\r
+                        case MIN_ELEMENTS_KEYWORD: {\r
+                            setState(630);\r
+                            min_elements_stmt();\r
+                        }\r
+                            break;\r
+                        case MAX_ELEMENTS_KEYWORD: {\r
+                            setState(631);\r
+                            max_elements_stmt();\r
+                        }\r
+                            break;\r
+                        case ORDERED_BY_KEYWORD: {\r
+                            setState(632);\r
+                            ordered_by_stmt();\r
+                        }\r
+                            break;\r
+                        case STATUS_KEYWORD: {\r
+                            setState(633);\r
+                            status_stmt();\r
+                        }\r
+                            break;\r
+                        case DESCRIPTION_KEYWORD: {\r
+                            setState(634);\r
+                            description_stmt();\r
+                        }\r
+                            break;\r
+                        case REFERENCE_KEYWORD: {\r
+                            setState(635);\r
+                            reference_stmt();\r
+                        }\r
+                            break;\r
+                        case TYPEDEF_KEYWORD: {\r
+                            setState(636);\r
+                            typedef_stmt();\r
+                        }\r
+                            break;\r
+                        case GROUPING_KEYWORD: {\r
+                            setState(637);\r
+                            grouping_stmt();\r
+                        }\r
+                            break;\r
+                        case USES_KEYWORD:\r
+                        case LIST_KEYWORD:\r
+                        case LEAF_LIST_KEYWORD:\r
+                        case LEAF_KEYWORD:\r
+                        case CONTAINER_KEYWORD:\r
+                        case CHOICE_KEYWORD:\r
+                        case ANYXML_KEYWORD: {\r
+                            setState(638);\r
+                            data_def_stmt();\r
+                        }\r
+                            break;\r
+                        default:\r
+                            throw new NoViableAltException(this);\r
+                        }\r
+                    }\r
+                    setState(641);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                } while (((((_la - 10)) & ~0x3f) == 0 && ((1L << (_la - 10)) & ((1L << (WHEN_KEYWORD - 10))\r
+                        | (1L << (USES_KEYWORD - 10))\r
+                        | (1L << (UNIQUE_KEYWORD - 10))\r
+                        | (1L << (TYPEDEF_KEYWORD - 10))\r
+                        | (1L << (STATUS_KEYWORD - 10))\r
+                        | (1L << (REFERENCE_KEYWORD - 10))\r
+                        | (1L << (ORDERED_BY_KEYWORD - 10))\r
+                        | (1L << (MUST_KEYWORD - 10))\r
+                        | (1L << (MIN_ELEMENTS_KEYWORD - 10))\r
+                        | (1L << (MAX_ELEMENTS_KEYWORD - 10))\r
+                        | (1L << (LIST_KEYWORD - 10))\r
+                        | (1L << (LEAF_LIST_KEYWORD - 10))\r
+                        | (1L << (LEAF_KEYWORD - 10))\r
+                        | (1L << (KEY_KEYWORD - 10))\r
+                        | (1L << (IF_FEATURE_KEYWORD - 10))\r
+                        | (1L << (GROUPING_KEYWORD - 10))\r
+                        | (1L << (DESCRIPTION_KEYWORD - 10))\r
+                        | (1L << (CONTAINER_KEYWORD - 10))\r
+                        | (1L << (CONFIG_KEYWORD - 10))\r
+                        | (1L << (CHOICE_KEYWORD - 10))\r
+                        | (1L << (ANYXML_KEYWORD - 10)) | (1L << (IDENTIFIER - 10)))) != 0));\r
+                setState(643);\r
+                match(RIGHT_BRACE);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Leaf_list_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<When_stmtContext> when_stmt() {\r
+            return getRuleContexts(When_stmtContext.class);\r
+        }\r
+\r
+        public Type_stmtContext type_stmt(int i) {\r
+            return getRuleContext(Type_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Max_elements_stmtContext> max_elements_stmt() {\r
+            return getRuleContexts(Max_elements_stmtContext.class);\r
+        }\r
+\r
+        public Min_elements_stmtContext min_elements_stmt(int i) {\r
+            return getRuleContext(Min_elements_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEAF_LIST_KEYWORD() {\r
+            return getToken(YangParser.LEAF_LIST_KEYWORD, 0);\r
+        }\r
+\r
+        public Config_stmtContext config_stmt(int i) {\r
+            return getRuleContext(Config_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Min_elements_stmtContext> min_elements_stmt() {\r
+            return getRuleContexts(Min_elements_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public When_stmtContext when_stmt(int i) {\r
+            return getRuleContext(When_stmtContext.class, i);\r
+        }\r
+\r
+        public Units_stmtContext units_stmt(int i) {\r
+            return getRuleContext(Units_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Ordered_by_stmtContext ordered_by_stmt(int i) {\r
+            return getRuleContext(Ordered_by_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Units_stmtContext> units_stmt() {\r
+            return getRuleContexts(Units_stmtContext.class);\r
+        }\r
+\r
+        public If_feature_stmtContext if_feature_stmt(int i) {\r
+            return getRuleContext(If_feature_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Ordered_by_stmtContext> ordered_by_stmt() {\r
+            return getRuleContexts(Ordered_by_stmtContext.class);\r
+        }\r
+\r
+        public List<Type_stmtContext> type_stmt() {\r
+            return getRuleContexts(Type_stmtContext.class);\r
+        }\r
+\r
+        public List<If_feature_stmtContext> if_feature_stmt() {\r
+            return getRuleContexts(If_feature_stmtContext.class);\r
+        }\r
+\r
+        public Must_stmtContext must_stmt(int i) {\r
+            return getRuleContext(Must_stmtContext.class, i);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Must_stmtContext> must_stmt() {\r
+            return getRuleContexts(Must_stmtContext.class);\r
+        }\r
+\r
+        public List<Config_stmtContext> config_stmt() {\r
+            return getRuleContexts(Config_stmtContext.class);\r
+        }\r
+\r
+        public Max_elements_stmtContext max_elements_stmt(int i) {\r
+            return getRuleContext(Max_elements_stmtContext.class, i);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Leaf_list_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_leaf_list_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterLeaf_list_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitLeaf_list_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitLeaf_list_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Leaf_list_stmtContext leaf_list_stmt()\r
+            throws RecognitionException {\r
+        Leaf_list_stmtContext _localctx = new Leaf_list_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 66, RULE_leaf_list_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(645);\r
+                match(LEAF_LIST_KEYWORD);\r
+                setState(646);\r
+                string();\r
+                setState(647);\r
+                match(LEFT_BRACE);\r
+                setState(663);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                while (((((_la - 10)) & ~0x3f) == 0 && ((1L << (_la - 10)) & ((1L << (WHEN_KEYWORD - 10))\r
+                        | (1L << (UNITS_KEYWORD - 10))\r
+                        | (1L << (TYPE_KEYWORD - 10))\r
+                        | (1L << (STATUS_KEYWORD - 10))\r
+                        | (1L << (REFERENCE_KEYWORD - 10))\r
+                        | (1L << (ORDERED_BY_KEYWORD - 10))\r
+                        | (1L << (MUST_KEYWORD - 10))\r
+                        | (1L << (MIN_ELEMENTS_KEYWORD - 10))\r
+                        | (1L << (MAX_ELEMENTS_KEYWORD - 10))\r
+                        | (1L << (IF_FEATURE_KEYWORD - 10))\r
+                        | (1L << (DESCRIPTION_KEYWORD - 10))\r
+                        | (1L << (CONFIG_KEYWORD - 10)) | (1L << (IDENTIFIER - 10)))) != 0)) {\r
+                    {\r
+                        setState(661);\r
+                        switch (_input.LA(1)) {\r
+                        case IDENTIFIER: {\r
+                            setState(648);\r
+                            identifier_stmt();\r
+                        }\r
+                            break;\r
+                        case WHEN_KEYWORD: {\r
+                            setState(649);\r
+                            when_stmt();\r
+                        }\r
+                            break;\r
+                        case IF_FEATURE_KEYWORD: {\r
+                            setState(650);\r
+                            if_feature_stmt();\r
+                        }\r
+                            break;\r
+                        case TYPE_KEYWORD: {\r
+                            setState(651);\r
+                            type_stmt();\r
+                        }\r
+                            break;\r
+                        case UNITS_KEYWORD: {\r
+                            setState(652);\r
+                            units_stmt();\r
+                        }\r
+                            break;\r
+                        case MUST_KEYWORD: {\r
+                            setState(653);\r
+                            must_stmt();\r
+                        }\r
+                            break;\r
+                        case CONFIG_KEYWORD: {\r
+                            setState(654);\r
+                            config_stmt();\r
+                        }\r
+                            break;\r
+                        case MIN_ELEMENTS_KEYWORD: {\r
+                            setState(655);\r
+                            min_elements_stmt();\r
+                        }\r
+                            break;\r
+                        case MAX_ELEMENTS_KEYWORD: {\r
+                            setState(656);\r
+                            max_elements_stmt();\r
+                        }\r
+                            break;\r
+                        case ORDERED_BY_KEYWORD: {\r
+                            setState(657);\r
+                            ordered_by_stmt();\r
+                        }\r
+                            break;\r
+                        case STATUS_KEYWORD: {\r
+                            setState(658);\r
+                            status_stmt();\r
+                        }\r
+                            break;\r
+                        case DESCRIPTION_KEYWORD: {\r
+                            setState(659);\r
+                            description_stmt();\r
+                        }\r
+                            break;\r
+                        case REFERENCE_KEYWORD: {\r
+                            setState(660);\r
+                            reference_stmt();\r
+                        }\r
+                            break;\r
+                        default:\r
+                            throw new NoViableAltException(this);\r
+                        }\r
+                    }\r
+                    setState(665);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                }\r
+                setState(666);\r
+                match(RIGHT_BRACE);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Leaf_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<When_stmtContext> when_stmt() {\r
+            return getRuleContexts(When_stmtContext.class);\r
+        }\r
+\r
+        public Type_stmtContext type_stmt(int i) {\r
+            return getRuleContext(Type_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Mandatory_stmtContext> mandatory_stmt() {\r
+            return getRuleContexts(Mandatory_stmtContext.class);\r
+        }\r
+\r
+        public Config_stmtContext config_stmt(int i) {\r
+            return getRuleContext(Config_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEAF_KEYWORD() {\r
+            return getToken(YangParser.LEAF_KEYWORD, 0);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public When_stmtContext when_stmt(int i) {\r
+            return getRuleContext(When_stmtContext.class, i);\r
+        }\r
+\r
+        public Units_stmtContext units_stmt(int i) {\r
+            return getRuleContext(Units_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Default_stmtContext default_stmt(int i) {\r
+            return getRuleContext(Default_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Units_stmtContext> units_stmt() {\r
+            return getRuleContexts(Units_stmtContext.class);\r
+        }\r
+\r
+        public If_feature_stmtContext if_feature_stmt(int i) {\r
+            return getRuleContext(If_feature_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Type_stmtContext> type_stmt() {\r
+            return getRuleContexts(Type_stmtContext.class);\r
+        }\r
+\r
+        public List<If_feature_stmtContext> if_feature_stmt() {\r
+            return getRuleContexts(If_feature_stmtContext.class);\r
+        }\r
+\r
+        public Must_stmtContext must_stmt(int i) {\r
+            return getRuleContext(Must_stmtContext.class, i);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Default_stmtContext> default_stmt() {\r
+            return getRuleContexts(Default_stmtContext.class);\r
+        }\r
+\r
+        public Mandatory_stmtContext mandatory_stmt(int i) {\r
+            return getRuleContext(Mandatory_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Must_stmtContext> must_stmt() {\r
+            return getRuleContexts(Must_stmtContext.class);\r
+        }\r
+\r
+        public List<Config_stmtContext> config_stmt() {\r
+            return getRuleContexts(Config_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Leaf_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_leaf_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterLeaf_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitLeaf_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitLeaf_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Leaf_stmtContext leaf_stmt() throws RecognitionException {\r
+        Leaf_stmtContext _localctx = new Leaf_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 68, RULE_leaf_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(668);\r
+                match(LEAF_KEYWORD);\r
+                setState(669);\r
+                string();\r
+                setState(670);\r
+                match(LEFT_BRACE);\r
+                setState(685);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                while (((((_la - 10)) & ~0x3f) == 0 && ((1L << (_la - 10)) & ((1L << (WHEN_KEYWORD - 10))\r
+                        | (1L << (UNITS_KEYWORD - 10))\r
+                        | (1L << (TYPE_KEYWORD - 10))\r
+                        | (1L << (STATUS_KEYWORD - 10))\r
+                        | (1L << (REFERENCE_KEYWORD - 10))\r
+                        | (1L << (MUST_KEYWORD - 10))\r
+                        | (1L << (MANDATORY_KEYWORD - 10))\r
+                        | (1L << (IF_FEATURE_KEYWORD - 10))\r
+                        | (1L << (DESCRIPTION_KEYWORD - 10))\r
+                        | (1L << (DEFAULT_KEYWORD - 10))\r
+                        | (1L << (CONFIG_KEYWORD - 10)) | (1L << (IDENTIFIER - 10)))) != 0)) {\r
+                    {\r
+                        setState(683);\r
+                        switch (_input.LA(1)) {\r
+                        case IDENTIFIER: {\r
+                            setState(671);\r
+                            identifier_stmt();\r
+                        }\r
+                            break;\r
+                        case WHEN_KEYWORD: {\r
+                            setState(672);\r
+                            when_stmt();\r
+                        }\r
+                            break;\r
+                        case IF_FEATURE_KEYWORD: {\r
+                            setState(673);\r
+                            if_feature_stmt();\r
+                        }\r
+                            break;\r
+                        case TYPE_KEYWORD: {\r
+                            setState(674);\r
+                            type_stmt();\r
+                        }\r
+                            break;\r
+                        case UNITS_KEYWORD: {\r
+                            setState(675);\r
+                            units_stmt();\r
+                        }\r
+                            break;\r
+                        case MUST_KEYWORD: {\r
+                            setState(676);\r
+                            must_stmt();\r
+                        }\r
+                            break;\r
+                        case DEFAULT_KEYWORD: {\r
+                            setState(677);\r
+                            default_stmt();\r
+                        }\r
+                            break;\r
+                        case CONFIG_KEYWORD: {\r
+                            setState(678);\r
+                            config_stmt();\r
+                        }\r
+                            break;\r
+                        case MANDATORY_KEYWORD: {\r
+                            setState(679);\r
+                            mandatory_stmt();\r
+                        }\r
+                            break;\r
+                        case STATUS_KEYWORD: {\r
+                            setState(680);\r
+                            status_stmt();\r
+                        }\r
+                            break;\r
+                        case DESCRIPTION_KEYWORD: {\r
+                            setState(681);\r
+                            description_stmt();\r
+                        }\r
+                            break;\r
+                        case REFERENCE_KEYWORD: {\r
+                            setState(682);\r
+                            reference_stmt();\r
+                        }\r
+                            break;\r
+                        default:\r
+                            throw new NoViableAltException(this);\r
+                        }\r
+                    }\r
+                    setState(687);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                }\r
+                setState(688);\r
+                match(RIGHT_BRACE);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Container_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<When_stmtContext> when_stmt() {\r
+            return getRuleContexts(When_stmtContext.class);\r
+        }\r
+\r
+        public Data_def_stmtContext data_def_stmt(int i) {\r
+            return getRuleContext(Data_def_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Typedef_stmtContext> typedef_stmt() {\r
+            return getRuleContexts(Typedef_stmtContext.class);\r
+        }\r
+\r
+        public List<Data_def_stmtContext> data_def_stmt() {\r
+            return getRuleContexts(Data_def_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public Config_stmtContext config_stmt(int i) {\r
+            return getRuleContext(Config_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public When_stmtContext when_stmt(int i) {\r
+            return getRuleContext(When_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Grouping_stmtContext> grouping_stmt() {\r
+            return getRuleContexts(Grouping_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode CONTAINER_KEYWORD() {\r
+            return getToken(YangParser.CONTAINER_KEYWORD, 0);\r
+        }\r
+\r
+        public List<Presence_stmtContext> presence_stmt() {\r
+            return getRuleContexts(Presence_stmtContext.class);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Typedef_stmtContext typedef_stmt(int i) {\r
+            return getRuleContext(Typedef_stmtContext.class, i);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Grouping_stmtContext grouping_stmt(int i) {\r
+            return getRuleContext(Grouping_stmtContext.class, i);\r
+        }\r
+\r
+        public If_feature_stmtContext if_feature_stmt(int i) {\r
+            return getRuleContext(If_feature_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public List<If_feature_stmtContext> if_feature_stmt() {\r
+            return getRuleContexts(If_feature_stmtContext.class);\r
+        }\r
+\r
+        public Must_stmtContext must_stmt(int i) {\r
+            return getRuleContext(Must_stmtContext.class, i);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public Presence_stmtContext presence_stmt(int i) {\r
+            return getRuleContext(Presence_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Must_stmtContext> must_stmt() {\r
+            return getRuleContexts(Must_stmtContext.class);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Config_stmtContext> config_stmt() {\r
+            return getRuleContexts(Config_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Container_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_container_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterContainer_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitContainer_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitContainer_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Container_stmtContext container_stmt()\r
+            throws RecognitionException {\r
+        Container_stmtContext _localctx = new Container_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 70, RULE_container_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(690);\r
+                match(CONTAINER_KEYWORD);\r
+                setState(691);\r
+                string();\r
+                setState(712);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(692);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(693);\r
+                        match(LEFT_BRACE);\r
+                        setState(708);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 10)) & ~0x3f) == 0 && ((1L << (_la - 10)) & ((1L << (WHEN_KEYWORD - 10))\r
+                                | (1L << (USES_KEYWORD - 10))\r
+                                | (1L << (TYPEDEF_KEYWORD - 10))\r
+                                | (1L << (STATUS_KEYWORD - 10))\r
+                                | (1L << (REFERENCE_KEYWORD - 10))\r
+                                | (1L << (PRESENCE_KEYWORD - 10))\r
+                                | (1L << (MUST_KEYWORD - 10))\r
+                                | (1L << (LIST_KEYWORD - 10))\r
+                                | (1L << (LEAF_LIST_KEYWORD - 10))\r
+                                | (1L << (LEAF_KEYWORD - 10))\r
+                                | (1L << (IF_FEATURE_KEYWORD - 10))\r
+                                | (1L << (GROUPING_KEYWORD - 10))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 10))\r
+                                | (1L << (CONTAINER_KEYWORD - 10))\r
+                                | (1L << (CONFIG_KEYWORD - 10))\r
+                                | (1L << (CHOICE_KEYWORD - 10))\r
+                                | (1L << (ANYXML_KEYWORD - 10)) | (1L << (IDENTIFIER - 10)))) != 0)) {\r
+                            {\r
+                                setState(706);\r
+                                switch (_input.LA(1)) {\r
+                                case IDENTIFIER: {\r
+                                    setState(694);\r
+                                    identifier_stmt();\r
+                                }\r
+                                    break;\r
+                                case WHEN_KEYWORD: {\r
+                                    setState(695);\r
+                                    when_stmt();\r
+                                }\r
+                                    break;\r
+                                case IF_FEATURE_KEYWORD: {\r
+                                    setState(696);\r
+                                    if_feature_stmt();\r
+                                }\r
+                                    break;\r
+                                case MUST_KEYWORD: {\r
+                                    setState(697);\r
+                                    must_stmt();\r
+                                }\r
+                                    break;\r
+                                case PRESENCE_KEYWORD: {\r
+                                    setState(698);\r
+                                    presence_stmt();\r
+                                }\r
+                                    break;\r
+                                case CONFIG_KEYWORD: {\r
+                                    setState(699);\r
+                                    config_stmt();\r
+                                }\r
+                                    break;\r
+                                case STATUS_KEYWORD: {\r
+                                    setState(700);\r
+                                    status_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(701);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(702);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                case TYPEDEF_KEYWORD: {\r
+                                    setState(703);\r
+                                    typedef_stmt();\r
+                                }\r
+                                    break;\r
+                                case GROUPING_KEYWORD: {\r
+                                    setState(704);\r
+                                    grouping_stmt();\r
+                                }\r
+                                    break;\r
+                                case USES_KEYWORD:\r
+                                case LIST_KEYWORD:\r
+                                case LEAF_LIST_KEYWORD:\r
+                                case LEAF_KEYWORD:\r
+                                case CONTAINER_KEYWORD:\r
+                                case CHOICE_KEYWORD:\r
+                                case ANYXML_KEYWORD: {\r
+                                    setState(705);\r
+                                    data_def_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(710);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(711);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Grouping_stmtContext extends ParserRuleContext {\r
+        public List<Grouping_stmtContext> grouping_stmt() {\r
+            return getRuleContexts(Grouping_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Typedef_stmtContext typedef_stmt(int i) {\r
+            return getRuleContext(Typedef_stmtContext.class, i);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Grouping_stmtContext grouping_stmt(int i) {\r
+            return getRuleContext(Grouping_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Data_def_stmtContext data_def_stmt(int i) {\r
+            return getRuleContext(Data_def_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Typedef_stmtContext> typedef_stmt() {\r
+            return getRuleContexts(Typedef_stmtContext.class);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Data_def_stmtContext> data_def_stmt() {\r
+            return getRuleContexts(Data_def_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode GROUPING_KEYWORD() {\r
+            return getToken(YangParser.GROUPING_KEYWORD, 0);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Grouping_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_grouping_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterGrouping_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitGrouping_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitGrouping_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Grouping_stmtContext grouping_stmt()\r
+            throws RecognitionException {\r
+        Grouping_stmtContext _localctx = new Grouping_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 72, RULE_grouping_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(714);\r
+                match(GROUPING_KEYWORD);\r
+                setState(715);\r
+                string();\r
+                setState(731);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(716);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(717);\r
+                        match(LEFT_BRACE);\r
+                        setState(727);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 12)) & ~0x3f) == 0 && ((1L << (_la - 12)) & ((1L << (USES_KEYWORD - 12))\r
+                                | (1L << (TYPEDEF_KEYWORD - 12))\r
+                                | (1L << (STATUS_KEYWORD - 12))\r
+                                | (1L << (REFERENCE_KEYWORD - 12))\r
+                                | (1L << (LIST_KEYWORD - 12))\r
+                                | (1L << (LEAF_LIST_KEYWORD - 12))\r
+                                | (1L << (LEAF_KEYWORD - 12))\r
+                                | (1L << (GROUPING_KEYWORD - 12))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 12))\r
+                                | (1L << (CONTAINER_KEYWORD - 12))\r
+                                | (1L << (CHOICE_KEYWORD - 12))\r
+                                | (1L << (ANYXML_KEYWORD - 12)) | (1L << (IDENTIFIER - 12)))) != 0)) {\r
+                            {\r
+                                setState(725);\r
+                                switch (_input.LA(1)) {\r
+                                case IDENTIFIER: {\r
+                                    setState(718);\r
+                                    identifier_stmt();\r
+                                }\r
+                                    break;\r
+                                case STATUS_KEYWORD: {\r
+                                    setState(719);\r
+                                    status_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(720);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(721);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                case TYPEDEF_KEYWORD: {\r
+                                    setState(722);\r
+                                    typedef_stmt();\r
+                                }\r
+                                    break;\r
+                                case GROUPING_KEYWORD: {\r
+                                    setState(723);\r
+                                    grouping_stmt();\r
+                                }\r
+                                    break;\r
+                                case USES_KEYWORD:\r
+                                case LIST_KEYWORD:\r
+                                case LEAF_LIST_KEYWORD:\r
+                                case LEAF_KEYWORD:\r
+                                case CONTAINER_KEYWORD:\r
+                                case CHOICE_KEYWORD:\r
+                                case ANYXML_KEYWORD: {\r
+                                    setState(724);\r
+                                    data_def_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(729);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(730);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Value_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode VALUE_KEYWORD() {\r
+            return getToken(YangParser.VALUE_KEYWORD, 0);\r
+        }\r
+\r
+        public Value_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_value_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterValue_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitValue_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitValue_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Value_stmtContext value_stmt() throws RecognitionException {\r
+        Value_stmtContext _localctx = new Value_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 74, RULE_value_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(733);\r
+                match(VALUE_KEYWORD);\r
+                setState(734);\r
+                string();\r
+                setState(735);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Max_value_argContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public Max_value_argContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_max_value_arg;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterMax_value_arg(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitMax_value_arg(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitMax_value_arg(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Max_value_argContext max_value_arg()\r
+            throws RecognitionException {\r
+        Max_value_argContext _localctx = new Max_value_argContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 76, RULE_max_value_arg);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(737);\r
+                string();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Max_elements_stmtContext extends ParserRuleContext {\r
+        public TerminalNode MAX_ELEMENTS_KEYWORD() {\r
+            return getToken(YangParser.MAX_ELEMENTS_KEYWORD, 0);\r
+        }\r
+\r
+        public Max_value_argContext max_value_arg() {\r
+            return getRuleContext(Max_value_argContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Max_elements_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_max_elements_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterMax_elements_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitMax_elements_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitMax_elements_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Max_elements_stmtContext max_elements_stmt()\r
+            throws RecognitionException {\r
+        Max_elements_stmtContext _localctx = new Max_elements_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 78, RULE_max_elements_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(739);\r
+                match(MAX_ELEMENTS_KEYWORD);\r
+                setState(740);\r
+                max_value_arg();\r
+                setState(741);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Min_elements_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode MIN_ELEMENTS_KEYWORD() {\r
+            return getToken(YangParser.MIN_ELEMENTS_KEYWORD, 0);\r
+        }\r
+\r
+        public Min_elements_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_min_elements_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterMin_elements_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitMin_elements_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitMin_elements_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Min_elements_stmtContext min_elements_stmt()\r
+            throws RecognitionException {\r
+        Min_elements_stmtContext _localctx = new Min_elements_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 80, RULE_min_elements_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(743);\r
+                match(MIN_ELEMENTS_KEYWORD);\r
+                setState(744);\r
+                string();\r
+                setState(745);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Error_app_tag_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode ERROR_APP_TAG_KEYWORD() {\r
+            return getToken(YangParser.ERROR_APP_TAG_KEYWORD, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Error_app_tag_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_error_app_tag_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterError_app_tag_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitError_app_tag_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitError_app_tag_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Error_app_tag_stmtContext error_app_tag_stmt()\r
+            throws RecognitionException {\r
+        Error_app_tag_stmtContext _localctx = new Error_app_tag_stmtContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 82, RULE_error_app_tag_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(747);\r
+                match(ERROR_APP_TAG_KEYWORD);\r
+                setState(748);\r
+                string();\r
+                setState(749);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Error_message_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode ERROR_MESSAGE_KEYWORD() {\r
+            return getToken(YangParser.ERROR_MESSAGE_KEYWORD, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Error_message_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_error_message_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterError_message_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitError_message_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitError_message_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Error_message_stmtContext error_message_stmt()\r
+            throws RecognitionException {\r
+        Error_message_stmtContext _localctx = new Error_message_stmtContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 84, RULE_error_message_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(751);\r
+                match(ERROR_MESSAGE_KEYWORD);\r
+                setState(752);\r
+                string();\r
+                setState(753);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Must_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public List<Error_app_tag_stmtContext> error_app_tag_stmt() {\r
+            return getRuleContexts(Error_app_tag_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode MUST_KEYWORD() {\r
+            return getToken(YangParser.MUST_KEYWORD, 0);\r
+        }\r
+\r
+        public Error_message_stmtContext error_message_stmt(int i) {\r
+            return getRuleContext(Error_message_stmtContext.class, i);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public Error_app_tag_stmtContext error_app_tag_stmt(int i) {\r
+            return getRuleContext(Error_app_tag_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Error_message_stmtContext> error_message_stmt() {\r
+            return getRuleContexts(Error_message_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Must_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_must_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterMust_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitMust_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitMust_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Must_stmtContext must_stmt() throws RecognitionException {\r
+        Must_stmtContext _localctx = new Must_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 86, RULE_must_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(755);\r
+                match(MUST_KEYWORD);\r
+                setState(756);\r
+                string();\r
+                setState(770);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(757);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(758);\r
+                        match(LEFT_BRACE);\r
+                        setState(766);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 24)) & ~0x3f) == 0 && ((1L << (_la - 24)) & ((1L << (REFERENCE_KEYWORD - 24))\r
+                                | (1L << (ERROR_MESSAGE_KEYWORD - 24))\r
+                                | (1L << (ERROR_APP_TAG_KEYWORD - 24))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 24)) | (1L << (IDENTIFIER - 24)))) != 0)) {\r
+                            {\r
+                                setState(764);\r
+                                switch (_input.LA(1)) {\r
+                                case IDENTIFIER: {\r
+                                    setState(759);\r
+                                    identifier_stmt();\r
+                                }\r
+                                    break;\r
+                                case ERROR_MESSAGE_KEYWORD: {\r
+                                    setState(760);\r
+                                    error_message_stmt();\r
+                                }\r
+                                    break;\r
+                                case ERROR_APP_TAG_KEYWORD: {\r
+                                    setState(761);\r
+                                    error_app_tag_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(762);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(763);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(768);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(769);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Ordered_by_argContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public Ordered_by_argContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_ordered_by_arg;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterOrdered_by_arg(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitOrdered_by_arg(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitOrdered_by_arg(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Ordered_by_argContext ordered_by_arg()\r
+            throws RecognitionException {\r
+        Ordered_by_argContext _localctx = new Ordered_by_argContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 88, RULE_ordered_by_arg);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(772);\r
+                string();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Ordered_by_stmtContext extends ParserRuleContext {\r
+        public Ordered_by_argContext ordered_by_arg() {\r
+            return getRuleContext(Ordered_by_argContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode ORDERED_BY_KEYWORD() {\r
+            return getToken(YangParser.ORDERED_BY_KEYWORD, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Ordered_by_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_ordered_by_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterOrdered_by_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitOrdered_by_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitOrdered_by_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Ordered_by_stmtContext ordered_by_stmt()\r
+            throws RecognitionException {\r
+        Ordered_by_stmtContext _localctx = new Ordered_by_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 90, RULE_ordered_by_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(774);\r
+                match(ORDERED_BY_KEYWORD);\r
+                setState(775);\r
+                ordered_by_arg();\r
+                setState(776);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Presence_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode PRESENCE_KEYWORD() {\r
+            return getToken(YangParser.PRESENCE_KEYWORD, 0);\r
+        }\r
+\r
+        public Presence_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_presence_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterPresence_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitPresence_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitPresence_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Presence_stmtContext presence_stmt()\r
+            throws RecognitionException {\r
+        Presence_stmtContext _localctx = new Presence_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 92, RULE_presence_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(778);\r
+                match(PRESENCE_KEYWORD);\r
+                setState(779);\r
+                string();\r
+                setState(780);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Mandatory_argContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public Mandatory_argContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_mandatory_arg;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterMandatory_arg(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitMandatory_arg(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitMandatory_arg(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Mandatory_argContext mandatory_arg()\r
+            throws RecognitionException {\r
+        Mandatory_argContext _localctx = new Mandatory_argContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 94, RULE_mandatory_arg);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(782);\r
+                string();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Mandatory_stmtContext extends ParserRuleContext {\r
+        public TerminalNode MANDATORY_KEYWORD() {\r
+            return getToken(YangParser.MANDATORY_KEYWORD, 0);\r
+        }\r
+\r
+        public Mandatory_argContext mandatory_arg() {\r
+            return getRuleContext(Mandatory_argContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Mandatory_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_mandatory_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterMandatory_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitMandatory_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitMandatory_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Mandatory_stmtContext mandatory_stmt()\r
+            throws RecognitionException {\r
+        Mandatory_stmtContext _localctx = new Mandatory_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 96, RULE_mandatory_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(784);\r
+                match(MANDATORY_KEYWORD);\r
+                setState(785);\r
+                mandatory_arg();\r
+                setState(786);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Config_argContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public Config_argContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_config_arg;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterConfig_arg(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitConfig_arg(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitConfig_arg(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Config_argContext config_arg() throws RecognitionException {\r
+        Config_argContext _localctx = new Config_argContext(_ctx, getState());\r
+        enterRule(_localctx, 98, RULE_config_arg);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(788);\r
+                string();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Config_stmtContext extends ParserRuleContext {\r
+        public Config_argContext config_arg() {\r
+            return getRuleContext(Config_argContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode CONFIG_KEYWORD() {\r
+            return getToken(YangParser.CONFIG_KEYWORD, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Config_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_config_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterConfig_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitConfig_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitConfig_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Config_stmtContext config_stmt() throws RecognitionException {\r
+        Config_stmtContext _localctx = new Config_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 100, RULE_config_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(790);\r
+                match(CONFIG_KEYWORD);\r
+                setState(791);\r
+                config_arg();\r
+                setState(792);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Status_argContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public Status_argContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_status_arg;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterStatus_arg(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitStatus_arg(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitStatus_arg(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Status_argContext status_arg() throws RecognitionException {\r
+        Status_argContext _localctx = new Status_argContext(_ctx, getState());\r
+        enterRule(_localctx, 102, RULE_status_arg);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(794);\r
+                string();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Status_stmtContext extends ParserRuleContext {\r
+        public Status_argContext status_arg() {\r
+            return getRuleContext(Status_argContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode STATUS_KEYWORD() {\r
+            return getToken(YangParser.STATUS_KEYWORD, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Status_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_status_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterStatus_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitStatus_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitStatus_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Status_stmtContext status_stmt() throws RecognitionException {\r
+        Status_stmtContext _localctx = new Status_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 104, RULE_status_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(796);\r
+                match(STATUS_KEYWORD);\r
+                setState(797);\r
+                status_arg();\r
+                setState(798);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Position_stmtContext extends ParserRuleContext {\r
+        public TerminalNode POSITION_KEYWORD() {\r
+            return getToken(YangParser.POSITION_KEYWORD, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Position_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_position_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterPosition_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitPosition_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitPosition_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Position_stmtContext position_stmt()\r
+            throws RecognitionException {\r
+        Position_stmtContext _localctx = new Position_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 106, RULE_position_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(800);\r
+                match(POSITION_KEYWORD);\r
+                setState(801);\r
+                string();\r
+                setState(802);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Bit_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Position_stmtContext position_stmt(int i) {\r
+            return getRuleContext(Position_stmtContext.class, i);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Position_stmtContext> position_stmt() {\r
+            return getRuleContexts(Position_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode BIT_KEYWORD() {\r
+            return getToken(YangParser.BIT_KEYWORD, 0);\r
+        }\r
+\r
+        public Bit_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_bit_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterBit_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitBit_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitBit_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Bit_stmtContext bit_stmt() throws RecognitionException {\r
+        Bit_stmtContext _localctx = new Bit_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 108, RULE_bit_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(804);\r
+                match(BIT_KEYWORD);\r
+                setState(805);\r
+                string();\r
+                setState(819);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(806);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(807);\r
+                        match(LEFT_BRACE);\r
+                        setState(815);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 18)) & ~0x3f) == 0 && ((1L << (_la - 18)) & ((1L << (STATUS_KEYWORD - 18))\r
+                                | (1L << (REFERENCE_KEYWORD - 18))\r
+                                | (1L << (POSITION_KEYWORD - 18))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 18)) | (1L << (IDENTIFIER - 18)))) != 0)) {\r
+                            {\r
+                                setState(813);\r
+                                switch (_input.LA(1)) {\r
+                                case IDENTIFIER: {\r
+                                    setState(808);\r
+                                    identifier_stmt();\r
+                                }\r
+                                    break;\r
+                                case POSITION_KEYWORD: {\r
+                                    setState(809);\r
+                                    position_stmt();\r
+                                }\r
+                                    break;\r
+                                case STATUS_KEYWORD: {\r
+                                    setState(810);\r
+                                    status_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(811);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(812);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(817);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(818);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Bits_specificationContext extends ParserRuleContext {\r
+        public Bit_stmtContext bit_stmt(int i) {\r
+            return getRuleContext(Bit_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Bit_stmtContext> bit_stmt() {\r
+            return getRuleContexts(Bit_stmtContext.class);\r
+        }\r
+\r
+        public Bits_specificationContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_bits_specification;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterBits_specification(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitBits_specification(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitBits_specification(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Bits_specificationContext bits_specification()\r
+            throws RecognitionException {\r
+        Bits_specificationContext _localctx = new Bits_specificationContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 110, RULE_bits_specification);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(822);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                do {\r
+                    {\r
+                        {\r
+                            setState(821);\r
+                            bit_stmt();\r
+                        }\r
+                    }\r
+                    setState(824);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                } while (_la == BIT_KEYWORD);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Union_specificationContext extends ParserRuleContext {\r
+        public Type_stmtContext type_stmt(int i) {\r
+            return getRuleContext(Type_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Type_stmtContext> type_stmt() {\r
+            return getRuleContexts(Type_stmtContext.class);\r
+        }\r
+\r
+        public Union_specificationContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_union_specification;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterUnion_specification(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitUnion_specification(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitUnion_specification(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Union_specificationContext union_specification()\r
+            throws RecognitionException {\r
+        Union_specificationContext _localctx = new Union_specificationContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 112, RULE_union_specification);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(827);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                do {\r
+                    {\r
+                        {\r
+                            setState(826);\r
+                            type_stmt();\r
+                        }\r
+                    }\r
+                    setState(829);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                } while (_la == TYPE_KEYWORD);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Identityref_specificationContext extends\r
+            ParserRuleContext {\r
+        public Base_stmtContext base_stmt() {\r
+            return getRuleContext(Base_stmtContext.class, 0);\r
+        }\r
+\r
+        public Identityref_specificationContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_identityref_specification;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .enterIdentityref_specification(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .exitIdentityref_specification(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitIdentityref_specification(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Identityref_specificationContext identityref_specification()\r
+            throws RecognitionException {\r
+        Identityref_specificationContext _localctx = new Identityref_specificationContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 114, RULE_identityref_specification);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(831);\r
+                base_stmt();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Instance_identifier_specificationContext extends\r
+            ParserRuleContext {\r
+        public Require_instance_stmtContext require_instance_stmt() {\r
+            return getRuleContext(Require_instance_stmtContext.class, 0);\r
+        }\r
+\r
+        public Instance_identifier_specificationContext(\r
+                ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_instance_identifier_specification;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .enterInstance_identifier_specification(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .exitInstance_identifier_specification(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitInstance_identifier_specification(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Instance_identifier_specificationContext instance_identifier_specification()\r
+            throws RecognitionException {\r
+        Instance_identifier_specificationContext _localctx = new Instance_identifier_specificationContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 116, RULE_instance_identifier_specification);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(834);\r
+                _la = _input.LA(1);\r
+                if (_la == REQUIRE_INSTANCE_KEYWORD) {\r
+                    {\r
+                        setState(833);\r
+                        require_instance_stmt();\r
+                    }\r
+                }\r
+\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Require_instance_argContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public Require_instance_argContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_require_instance_arg;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterRequire_instance_arg(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitRequire_instance_arg(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRequire_instance_arg(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Require_instance_argContext require_instance_arg()\r
+            throws RecognitionException {\r
+        Require_instance_argContext _localctx = new Require_instance_argContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 118, RULE_require_instance_arg);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(836);\r
+                string();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Require_instance_stmtContext extends ParserRuleContext {\r
+        public Require_instance_argContext require_instance_arg() {\r
+            return getRuleContext(Require_instance_argContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode REQUIRE_INSTANCE_KEYWORD() {\r
+            return getToken(YangParser.REQUIRE_INSTANCE_KEYWORD, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Require_instance_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_require_instance_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .enterRequire_instance_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitRequire_instance_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRequire_instance_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Require_instance_stmtContext require_instance_stmt()\r
+            throws RecognitionException {\r
+        Require_instance_stmtContext _localctx = new Require_instance_stmtContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 120, RULE_require_instance_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(838);\r
+                match(REQUIRE_INSTANCE_KEYWORD);\r
+                setState(839);\r
+                require_instance_arg();\r
+                setState(840);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Path_stmtContext extends ParserRuleContext {\r
+        public TerminalNode PATH_KEYWORD() {\r
+            return getToken(YangParser.PATH_KEYWORD, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Path_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_path_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterPath_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitPath_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitPath_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Path_stmtContext path_stmt() throws RecognitionException {\r
+        Path_stmtContext _localctx = new Path_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 122, RULE_path_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(842);\r
+                match(PATH_KEYWORD);\r
+                setState(843);\r
+                string();\r
+                setState(844);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Leafref_specificationContext extends ParserRuleContext {\r
+        public Path_stmtContext path_stmt() {\r
+            return getRuleContext(Path_stmtContext.class, 0);\r
+        }\r
+\r
+        public Leafref_specificationContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_leafref_specification;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .enterLeafref_specification(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitLeafref_specification(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitLeafref_specification(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Leafref_specificationContext leafref_specification()\r
+            throws RecognitionException {\r
+        Leafref_specificationContext _localctx = new Leafref_specificationContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 124, RULE_leafref_specification);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(846);\r
+                path_stmt();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Enum_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public Value_stmtContext value_stmt(int i) {\r
+            return getRuleContext(Value_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Value_stmtContext> value_stmt() {\r
+            return getRuleContexts(Value_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode ENUM_KEYWORD() {\r
+            return getToken(YangParser.ENUM_KEYWORD, 0);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Enum_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_enum_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterEnum_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitEnum_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitEnum_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Enum_stmtContext enum_stmt() throws RecognitionException {\r
+        Enum_stmtContext _localctx = new Enum_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 126, RULE_enum_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(848);\r
+                match(ENUM_KEYWORD);\r
+                setState(849);\r
+                string();\r
+                setState(863);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(850);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(851);\r
+                        match(LEFT_BRACE);\r
+                        setState(859);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 11)) & ~0x3f) == 0 && ((1L << (_la - 11)) & ((1L << (VALUE_KEYWORD - 11))\r
+                                | (1L << (STATUS_KEYWORD - 11))\r
+                                | (1L << (REFERENCE_KEYWORD - 11))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 11)) | (1L << (IDENTIFIER - 11)))) != 0)) {\r
+                            {\r
+                                setState(857);\r
+                                switch (_input.LA(1)) {\r
+                                case IDENTIFIER: {\r
+                                    setState(852);\r
+                                    identifier_stmt();\r
+                                }\r
+                                    break;\r
+                                case VALUE_KEYWORD: {\r
+                                    setState(853);\r
+                                    value_stmt();\r
+                                }\r
+                                    break;\r
+                                case STATUS_KEYWORD: {\r
+                                    setState(854);\r
+                                    status_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(855);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(856);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(861);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(862);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Enum_specificationContext extends ParserRuleContext {\r
+        public List<Enum_stmtContext> enum_stmt() {\r
+            return getRuleContexts(Enum_stmtContext.class);\r
+        }\r
+\r
+        public Enum_stmtContext enum_stmt(int i) {\r
+            return getRuleContext(Enum_stmtContext.class, i);\r
+        }\r
+\r
+        public Enum_specificationContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_enum_specification;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterEnum_specification(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitEnum_specification(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitEnum_specification(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Enum_specificationContext enum_specification()\r
+            throws RecognitionException {\r
+        Enum_specificationContext _localctx = new Enum_specificationContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 128, RULE_enum_specification);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(866);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                do {\r
+                    {\r
+                        {\r
+                            setState(865);\r
+                            enum_stmt();\r
+                        }\r
+                    }\r
+                    setState(868);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                } while (_la == ENUM_KEYWORD);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Default_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode DEFAULT_KEYWORD() {\r
+            return getToken(YangParser.DEFAULT_KEYWORD, 0);\r
+        }\r
+\r
+        public Default_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_default_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterDefault_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitDefault_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitDefault_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Default_stmtContext default_stmt() throws RecognitionException {\r
+        Default_stmtContext _localctx = new Default_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 130, RULE_default_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(870);\r
+                match(DEFAULT_KEYWORD);\r
+                setState(871);\r
+                string();\r
+                setState(872);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Pattern_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public List<Error_app_tag_stmtContext> error_app_tag_stmt() {\r
+            return getRuleContexts(Error_app_tag_stmtContext.class);\r
+        }\r
+\r
+        public Error_message_stmtContext error_message_stmt(int i) {\r
+            return getRuleContext(Error_message_stmtContext.class, i);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode PATTERN_KEYWORD() {\r
+            return getToken(YangParser.PATTERN_KEYWORD, 0);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public Error_app_tag_stmtContext error_app_tag_stmt(int i) {\r
+            return getRuleContext(Error_app_tag_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Error_message_stmtContext> error_message_stmt() {\r
+            return getRuleContexts(Error_message_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Pattern_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_pattern_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterPattern_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitPattern_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitPattern_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Pattern_stmtContext pattern_stmt() throws RecognitionException {\r
+        Pattern_stmtContext _localctx = new Pattern_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 132, RULE_pattern_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(874);\r
+                match(PATTERN_KEYWORD);\r
+                setState(875);\r
+                string();\r
+                setState(889);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(876);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(877);\r
+                        match(LEFT_BRACE);\r
+                        setState(885);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 24)) & ~0x3f) == 0 && ((1L << (_la - 24)) & ((1L << (REFERENCE_KEYWORD - 24))\r
+                                | (1L << (ERROR_MESSAGE_KEYWORD - 24))\r
+                                | (1L << (ERROR_APP_TAG_KEYWORD - 24))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 24)) | (1L << (IDENTIFIER - 24)))) != 0)) {\r
+                            {\r
+                                setState(883);\r
+                                switch (_input.LA(1)) {\r
+                                case IDENTIFIER: {\r
+                                    setState(878);\r
+                                    identifier_stmt();\r
+                                }\r
+                                    break;\r
+                                case ERROR_MESSAGE_KEYWORD: {\r
+                                    setState(879);\r
+                                    error_message_stmt();\r
+                                }\r
+                                    break;\r
+                                case ERROR_APP_TAG_KEYWORD: {\r
+                                    setState(880);\r
+                                    error_app_tag_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(881);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(882);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(887);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(888);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Length_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public List<Error_app_tag_stmtContext> error_app_tag_stmt() {\r
+            return getRuleContexts(Error_app_tag_stmtContext.class);\r
+        }\r
+\r
+        public Error_message_stmtContext error_message_stmt(int i) {\r
+            return getRuleContext(Error_message_stmtContext.class, i);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode LENGTH_KEYWORD() {\r
+            return getToken(YangParser.LENGTH_KEYWORD, 0);\r
+        }\r
+\r
+        public Error_app_tag_stmtContext error_app_tag_stmt(int i) {\r
+            return getRuleContext(Error_app_tag_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Error_message_stmtContext> error_message_stmt() {\r
+            return getRuleContexts(Error_message_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Length_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_length_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterLength_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitLength_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitLength_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Length_stmtContext length_stmt() throws RecognitionException {\r
+        Length_stmtContext _localctx = new Length_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 134, RULE_length_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(891);\r
+                match(LENGTH_KEYWORD);\r
+                setState(892);\r
+                string();\r
+                setState(906);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(893);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(894);\r
+                        match(LEFT_BRACE);\r
+                        setState(902);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 24)) & ~0x3f) == 0 && ((1L << (_la - 24)) & ((1L << (REFERENCE_KEYWORD - 24))\r
+                                | (1L << (ERROR_MESSAGE_KEYWORD - 24))\r
+                                | (1L << (ERROR_APP_TAG_KEYWORD - 24))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 24)) | (1L << (IDENTIFIER - 24)))) != 0)) {\r
+                            {\r
+                                setState(900);\r
+                                switch (_input.LA(1)) {\r
+                                case IDENTIFIER: {\r
+                                    setState(895);\r
+                                    identifier_stmt();\r
+                                }\r
+                                    break;\r
+                                case ERROR_MESSAGE_KEYWORD: {\r
+                                    setState(896);\r
+                                    error_message_stmt();\r
+                                }\r
+                                    break;\r
+                                case ERROR_APP_TAG_KEYWORD: {\r
+                                    setState(897);\r
+                                    error_app_tag_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(898);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(899);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(904);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(905);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class String_restrictionsContext extends ParserRuleContext {\r
+        public Length_stmtContext length_stmt(int i) {\r
+            return getRuleContext(Length_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Pattern_stmtContext> pattern_stmt() {\r
+            return getRuleContexts(Pattern_stmtContext.class);\r
+        }\r
+\r
+        public List<Length_stmtContext> length_stmt() {\r
+            return getRuleContexts(Length_stmtContext.class);\r
+        }\r
+\r
+        public Pattern_stmtContext pattern_stmt(int i) {\r
+            return getRuleContext(Pattern_stmtContext.class, i);\r
+        }\r
+\r
+        public String_restrictionsContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_string_restrictions;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterString_restrictions(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitString_restrictions(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitString_restrictions(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final String_restrictionsContext string_restrictions()\r
+            throws RecognitionException {\r
+        String_restrictionsContext _localctx = new String_restrictionsContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 136, RULE_string_restrictions);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(912);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                while (_la == PATTERN_KEYWORD || _la == LENGTH_KEYWORD) {\r
+                    {\r
+                        setState(910);\r
+                        switch (_input.LA(1)) {\r
+                        case LENGTH_KEYWORD: {\r
+                            setState(908);\r
+                            length_stmt();\r
+                        }\r
+                            break;\r
+                        case PATTERN_KEYWORD: {\r
+                            setState(909);\r
+                            pattern_stmt();\r
+                        }\r
+                            break;\r
+                        default:\r
+                            throw new NoViableAltException(this);\r
+                        }\r
+                    }\r
+                    setState(914);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Fraction_digits_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode FRACTION_DIGITS_KEYWORD() {\r
+            return getToken(YangParser.FRACTION_DIGITS_KEYWORD, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Fraction_digits_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_fraction_digits_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterFraction_digits_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitFraction_digits_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitFraction_digits_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Fraction_digits_stmtContext fraction_digits_stmt()\r
+            throws RecognitionException {\r
+        Fraction_digits_stmtContext _localctx = new Fraction_digits_stmtContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 138, RULE_fraction_digits_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(915);\r
+                match(FRACTION_DIGITS_KEYWORD);\r
+                setState(916);\r
+                string();\r
+                setState(917);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Decimal64_specificationContext extends\r
+            ParserRuleContext {\r
+        public Fraction_digits_stmtContext fraction_digits_stmt() {\r
+            return getRuleContext(Fraction_digits_stmtContext.class, 0);\r
+        }\r
+\r
+        public Numerical_restrictionsContext numerical_restrictions() {\r
+            return getRuleContext(Numerical_restrictionsContext.class, 0);\r
+        }\r
+\r
+        public Decimal64_specificationContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_decimal64_specification;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .enterDecimal64_specification(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .exitDecimal64_specification(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitDecimal64_specification(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Decimal64_specificationContext decimal64_specification()\r
+            throws RecognitionException {\r
+        Decimal64_specificationContext _localctx = new Decimal64_specificationContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 140, RULE_decimal64_specification);\r
+        int _la;\r
+        try {\r
+            setState(927);\r
+            switch (getInterpreter().adaptivePredict(_input, 101, _ctx)) {\r
+            case 1:\r
+                enterOuterAlt(_localctx, 1);\r
+                {\r
+                    setState(920);\r
+                    _la = _input.LA(1);\r
+                    if (_la == RANGE_KEYWORD) {\r
+                        {\r
+                            setState(919);\r
+                            numerical_restrictions();\r
+                        }\r
+                    }\r
+\r
+                    setState(922);\r
+                    fraction_digits_stmt();\r
+                }\r
+                break;\r
+\r
+            case 2:\r
+                enterOuterAlt(_localctx, 2);\r
+                {\r
+                    setState(923);\r
+                    fraction_digits_stmt();\r
+                    setState(925);\r
+                    _la = _input.LA(1);\r
+                    if (_la == RANGE_KEYWORD) {\r
+                        {\r
+                            setState(924);\r
+                            numerical_restrictions();\r
+                        }\r
+                    }\r
+\r
+                }\r
+                break;\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Range_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public List<Error_app_tag_stmtContext> error_app_tag_stmt() {\r
+            return getRuleContexts(Error_app_tag_stmtContext.class);\r
+        }\r
+\r
+        public Error_message_stmtContext error_message_stmt(int i) {\r
+            return getRuleContext(Error_message_stmtContext.class, i);\r
+        }\r
+\r
+        public Identifier_stmtContext identifier_stmt(int i) {\r
+            return getRuleContext(Identifier_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public TerminalNode RANGE_KEYWORD() {\r
+            return getToken(YangParser.RANGE_KEYWORD, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Identifier_stmtContext> identifier_stmt() {\r
+            return getRuleContexts(Identifier_stmtContext.class);\r
+        }\r
+\r
+        public Error_app_tag_stmtContext error_app_tag_stmt(int i) {\r
+            return getRuleContext(Error_app_tag_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Error_message_stmtContext> error_message_stmt() {\r
+            return getRuleContexts(Error_message_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Range_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_range_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterRange_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitRange_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRange_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Range_stmtContext range_stmt() throws RecognitionException {\r
+        Range_stmtContext _localctx = new Range_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 142, RULE_range_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(929);\r
+                match(RANGE_KEYWORD);\r
+                setState(930);\r
+                string();\r
+                setState(944);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(931);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(932);\r
+                        match(LEFT_BRACE);\r
+                        setState(940);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 24)) & ~0x3f) == 0 && ((1L << (_la - 24)) & ((1L << (REFERENCE_KEYWORD - 24))\r
+                                | (1L << (ERROR_MESSAGE_KEYWORD - 24))\r
+                                | (1L << (ERROR_APP_TAG_KEYWORD - 24))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 24)) | (1L << (IDENTIFIER - 24)))) != 0)) {\r
+                            {\r
+                                setState(938);\r
+                                switch (_input.LA(1)) {\r
+                                case IDENTIFIER: {\r
+                                    setState(933);\r
+                                    identifier_stmt();\r
+                                }\r
+                                    break;\r
+                                case ERROR_MESSAGE_KEYWORD: {\r
+                                    setState(934);\r
+                                    error_message_stmt();\r
+                                }\r
+                                    break;\r
+                                case ERROR_APP_TAG_KEYWORD: {\r
+                                    setState(935);\r
+                                    error_app_tag_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(936);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(937);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(942);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(943);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Numerical_restrictionsContext extends ParserRuleContext {\r
+        public Range_stmtContext range_stmt() {\r
+            return getRuleContext(Range_stmtContext.class, 0);\r
+        }\r
+\r
+        public Numerical_restrictionsContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_numerical_restrictions;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .enterNumerical_restrictions(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .exitNumerical_restrictions(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitNumerical_restrictions(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Numerical_restrictionsContext numerical_restrictions()\r
+            throws RecognitionException {\r
+        Numerical_restrictionsContext _localctx = new Numerical_restrictionsContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 144, RULE_numerical_restrictions);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(946);\r
+                range_stmt();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Type_body_stmtsContext extends ParserRuleContext {\r
+        public Bits_specificationContext bits_specification() {\r
+            return getRuleContext(Bits_specificationContext.class, 0);\r
+        }\r
+\r
+        public Identityref_specificationContext identityref_specification() {\r
+            return getRuleContext(Identityref_specificationContext.class, 0);\r
+        }\r
+\r
+        public Enum_specificationContext enum_specification() {\r
+            return getRuleContext(Enum_specificationContext.class, 0);\r
+        }\r
+\r
+        public Numerical_restrictionsContext numerical_restrictions() {\r
+            return getRuleContext(Numerical_restrictionsContext.class, 0);\r
+        }\r
+\r
+        public String_restrictionsContext string_restrictions() {\r
+            return getRuleContext(String_restrictionsContext.class, 0);\r
+        }\r
+\r
+        public Leafref_specificationContext leafref_specification() {\r
+            return getRuleContext(Leafref_specificationContext.class, 0);\r
+        }\r
+\r
+        public Decimal64_specificationContext decimal64_specification() {\r
+            return getRuleContext(Decimal64_specificationContext.class, 0);\r
+        }\r
+\r
+        public Union_specificationContext union_specification() {\r
+            return getRuleContext(Union_specificationContext.class, 0);\r
+        }\r
+\r
+        public Instance_identifier_specificationContext instance_identifier_specification() {\r
+            return getRuleContext(\r
+                    Instance_identifier_specificationContext.class, 0);\r
+        }\r
+\r
+        public Type_body_stmtsContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_type_body_stmts;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterType_body_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitType_body_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitType_body_stmts(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Type_body_stmtsContext type_body_stmts()\r
+            throws RecognitionException {\r
+        Type_body_stmtsContext _localctx = new Type_body_stmtsContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 146, RULE_type_body_stmts);\r
+        try {\r
+            setState(957);\r
+            switch (getInterpreter().adaptivePredict(_input, 105, _ctx)) {\r
+            case 1:\r
+                enterOuterAlt(_localctx, 1);\r
+                {\r
+                    setState(948);\r
+                    numerical_restrictions();\r
+                }\r
+                break;\r
+\r
+            case 2:\r
+                enterOuterAlt(_localctx, 2);\r
+                {\r
+                    setState(949);\r
+                    decimal64_specification();\r
+                }\r
+                break;\r
+\r
+            case 3:\r
+                enterOuterAlt(_localctx, 3);\r
+                {\r
+                    setState(950);\r
+                    string_restrictions();\r
+                }\r
+                break;\r
+\r
+            case 4:\r
+                enterOuterAlt(_localctx, 4);\r
+                {\r
+                    setState(951);\r
+                    enum_specification();\r
+                }\r
+                break;\r
+\r
+            case 5:\r
+                enterOuterAlt(_localctx, 5);\r
+                {\r
+                    setState(952);\r
+                    leafref_specification();\r
+                }\r
+                break;\r
+\r
+            case 6:\r
+                enterOuterAlt(_localctx, 6);\r
+                {\r
+                    setState(953);\r
+                    identityref_specification();\r
+                }\r
+                break;\r
+\r
+            case 7:\r
+                enterOuterAlt(_localctx, 7);\r
+                {\r
+                    setState(954);\r
+                    instance_identifier_specification();\r
+                }\r
+                break;\r
+\r
+            case 8:\r
+                enterOuterAlt(_localctx, 8);\r
+                {\r
+                    setState(955);\r
+                    bits_specification();\r
+                }\r
+                break;\r
+\r
+            case 9:\r
+                enterOuterAlt(_localctx, 9);\r
+                {\r
+                    setState(956);\r
+                    union_specification();\r
+                }\r
+                break;\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Type_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public TerminalNode TYPE_KEYWORD() {\r
+            return getToken(YangParser.TYPE_KEYWORD, 0);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Type_body_stmtsContext type_body_stmts() {\r
+            return getRuleContext(Type_body_stmtsContext.class, 0);\r
+        }\r
+\r
+        public Type_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_type_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterType_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitType_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitType_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Type_stmtContext type_stmt() throws RecognitionException {\r
+        Type_stmtContext _localctx = new Type_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 148, RULE_type_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(959);\r
+                match(TYPE_KEYWORD);\r
+                setState(960);\r
+                string();\r
+                setState(966);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(961);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(962);\r
+                        match(LEFT_BRACE);\r
+                        setState(963);\r
+                        type_body_stmts();\r
+                        setState(964);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Typedef_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public Units_stmtContext units_stmt(int i) {\r
+            return getRuleContext(Units_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Default_stmtContext default_stmt(int i) {\r
+            return getRuleContext(Default_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Units_stmtContext> units_stmt() {\r
+            return getRuleContexts(Units_stmtContext.class);\r
+        }\r
+\r
+        public Type_stmtContext type_stmt(int i) {\r
+            return getRuleContext(Type_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Type_stmtContext> type_stmt() {\r
+            return getRuleContexts(Type_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode TYPEDEF_KEYWORD() {\r
+            return getToken(YangParser.TYPEDEF_KEYWORD, 0);\r
+        }\r
+\r
+        public List<Default_stmtContext> default_stmt() {\r
+            return getRuleContexts(Default_stmtContext.class);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Typedef_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_typedef_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterTypedef_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitTypedef_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitTypedef_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Typedef_stmtContext typedef_stmt() throws RecognitionException {\r
+        Typedef_stmtContext _localctx = new Typedef_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 150, RULE_typedef_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(968);\r
+                match(TYPEDEF_KEYWORD);\r
+                setState(969);\r
+                string();\r
+                setState(970);\r
+                match(LEFT_BRACE);\r
+                setState(977);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                do {\r
+                    {\r
+                        setState(977);\r
+                        switch (_input.LA(1)) {\r
+                        case TYPE_KEYWORD: {\r
+                            setState(971);\r
+                            type_stmt();\r
+                        }\r
+                            break;\r
+                        case UNITS_KEYWORD: {\r
+                            setState(972);\r
+                            units_stmt();\r
+                        }\r
+                            break;\r
+                        case DEFAULT_KEYWORD: {\r
+                            setState(973);\r
+                            default_stmt();\r
+                        }\r
+                            break;\r
+                        case STATUS_KEYWORD: {\r
+                            setState(974);\r
+                            status_stmt();\r
+                        }\r
+                            break;\r
+                        case DESCRIPTION_KEYWORD: {\r
+                            setState(975);\r
+                            description_stmt();\r
+                        }\r
+                            break;\r
+                        case REFERENCE_KEYWORD: {\r
+                            setState(976);\r
+                            reference_stmt();\r
+                        }\r
+                            break;\r
+                        default:\r
+                            throw new NoViableAltException(this);\r
+                        }\r
+                    }\r
+                    setState(979);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                } while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << UNITS_KEYWORD)\r
+                        | (1L << TYPE_KEYWORD)\r
+                        | (1L << STATUS_KEYWORD)\r
+                        | (1L << REFERENCE_KEYWORD)\r
+                        | (1L << DESCRIPTION_KEYWORD) | (1L << DEFAULT_KEYWORD))) != 0));\r
+                setState(981);\r
+                match(RIGHT_BRACE);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class If_feature_stmtContext extends ParserRuleContext {\r
+        public TerminalNode IF_FEATURE_KEYWORD() {\r
+            return getToken(YangParser.IF_FEATURE_KEYWORD, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public If_feature_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_if_feature_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterIf_feature_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitIf_feature_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitIf_feature_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final If_feature_stmtContext if_feature_stmt()\r
+            throws RecognitionException {\r
+        If_feature_stmtContext _localctx = new If_feature_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 152, RULE_if_feature_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(983);\r
+                match(IF_FEATURE_KEYWORD);\r
+                setState(984);\r
+                string();\r
+                setState(985);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Feature_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public If_feature_stmtContext if_feature_stmt(int i) {\r
+            return getRuleContext(If_feature_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public List<If_feature_stmtContext> if_feature_stmt() {\r
+            return getRuleContexts(If_feature_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode FEATURE_KEYWORD() {\r
+            return getToken(YangParser.FEATURE_KEYWORD, 0);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Feature_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_feature_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterFeature_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitFeature_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitFeature_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Feature_stmtContext feature_stmt() throws RecognitionException {\r
+        Feature_stmtContext _localctx = new Feature_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 154, RULE_feature_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(987);\r
+                match(FEATURE_KEYWORD);\r
+                setState(988);\r
+                string();\r
+                setState(1001);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(989);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(990);\r
+                        match(LEFT_BRACE);\r
+                        setState(997);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << STATUS_KEYWORD)\r
+                                | (1L << REFERENCE_KEYWORD)\r
+                                | (1L << IF_FEATURE_KEYWORD) | (1L << DESCRIPTION_KEYWORD))) != 0)) {\r
+                            {\r
+                                setState(995);\r
+                                switch (_input.LA(1)) {\r
+                                case IF_FEATURE_KEYWORD: {\r
+                                    setState(991);\r
+                                    if_feature_stmt();\r
+                                }\r
+                                    break;\r
+                                case STATUS_KEYWORD: {\r
+                                    setState(992);\r
+                                    status_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(993);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(994);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(999);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(1000);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Base_stmtContext extends ParserRuleContext {\r
+        public TerminalNode BASE_KEYWORD() {\r
+            return getToken(YangParser.BASE_KEYWORD, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Base_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_base_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterBase_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitBase_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitBase_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Base_stmtContext base_stmt() throws RecognitionException {\r
+        Base_stmtContext _localctx = new Base_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 156, RULE_base_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1003);\r
+                match(BASE_KEYWORD);\r
+                setState(1004);\r
+                string();\r
+                setState(1005);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Identity_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Base_stmtContext base_stmt(int i) {\r
+            return getRuleContext(Base_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode IDENTITY_KEYWORD() {\r
+            return getToken(YangParser.IDENTITY_KEYWORD, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Base_stmtContext> base_stmt() {\r
+            return getRuleContexts(Base_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Identity_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_identity_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterIdentity_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitIdentity_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitIdentity_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Identity_stmtContext identity_stmt()\r
+            throws RecognitionException {\r
+        Identity_stmtContext _localctx = new Identity_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 158, RULE_identity_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1007);\r
+                match(IDENTITY_KEYWORD);\r
+                setState(1008);\r
+                string();\r
+                setState(1021);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(1009);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(1010);\r
+                        match(LEFT_BRACE);\r
+                        setState(1017);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 18)) & ~0x3f) == 0 && ((1L << (_la - 18)) & ((1L << (STATUS_KEYWORD - 18))\r
+                                | (1L << (REFERENCE_KEYWORD - 18))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 18)) | (1L << (BASE_KEYWORD - 18)))) != 0)) {\r
+                            {\r
+                                setState(1015);\r
+                                switch (_input.LA(1)) {\r
+                                case BASE_KEYWORD: {\r
+                                    setState(1011);\r
+                                    base_stmt();\r
+                                }\r
+                                    break;\r
+                                case STATUS_KEYWORD: {\r
+                                    setState(1012);\r
+                                    status_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(1013);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(1014);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(1019);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(1020);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Yin_element_argContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public Yin_element_argContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_yin_element_arg;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterYin_element_arg(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitYin_element_arg(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitYin_element_arg(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Yin_element_argContext yin_element_arg()\r
+            throws RecognitionException {\r
+        Yin_element_argContext _localctx = new Yin_element_argContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 160, RULE_yin_element_arg);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1023);\r
+                string();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Yin_element_stmtContext extends ParserRuleContext {\r
+        public TerminalNode YIN_ELEMENT_KEYWORD() {\r
+            return getToken(YangParser.YIN_ELEMENT_KEYWORD, 0);\r
+        }\r
+\r
+        public Yin_element_argContext yin_element_arg() {\r
+            return getRuleContext(Yin_element_argContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Yin_element_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_yin_element_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterYin_element_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitYin_element_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitYin_element_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Yin_element_stmtContext yin_element_stmt()\r
+            throws RecognitionException {\r
+        Yin_element_stmtContext _localctx = new Yin_element_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 162, RULE_yin_element_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1025);\r
+                match(YIN_ELEMENT_KEYWORD);\r
+                setState(1026);\r
+                yin_element_arg();\r
+                setState(1027);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Argument_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public Yin_element_stmtContext yin_element_stmt() {\r
+            return getRuleContext(Yin_element_stmtContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public TerminalNode ARGUMENT_KEYWORD() {\r
+            return getToken(YangParser.ARGUMENT_KEYWORD, 0);\r
+        }\r
+\r
+        public Argument_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_argument_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterArgument_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitArgument_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitArgument_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Argument_stmtContext argument_stmt()\r
+            throws RecognitionException {\r
+        Argument_stmtContext _localctx = new Argument_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 164, RULE_argument_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1029);\r
+                match(ARGUMENT_KEYWORD);\r
+                setState(1030);\r
+                string();\r
+                setState(1037);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(1031);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(1032);\r
+                        match(LEFT_BRACE);\r
+                        setState(1034);\r
+                        _la = _input.LA(1);\r
+                        if (_la == YIN_ELEMENT_KEYWORD) {\r
+                            {\r
+                                setState(1033);\r
+                                yin_element_stmt();\r
+                            }\r
+                        }\r
+\r
+                        setState(1036);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Extension_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public TerminalNode EXTENSION_KEYWORD() {\r
+            return getToken(YangParser.EXTENSION_KEYWORD, 0);\r
+        }\r
+\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Argument_stmtContext> argument_stmt() {\r
+            return getRuleContexts(Argument_stmtContext.class);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Status_stmtContext status_stmt(int i) {\r
+            return getRuleContext(Status_stmtContext.class, i);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public List<Status_stmtContext> status_stmt() {\r
+            return getRuleContexts(Status_stmtContext.class);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Argument_stmtContext argument_stmt(int i) {\r
+            return getRuleContext(Argument_stmtContext.class, i);\r
+        }\r
+\r
+        public Extension_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_extension_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterExtension_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitExtension_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitExtension_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Extension_stmtContext extension_stmt()\r
+            throws RecognitionException {\r
+        Extension_stmtContext _localctx = new Extension_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 166, RULE_extension_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1039);\r
+                match(EXTENSION_KEYWORD);\r
+                setState(1040);\r
+                string();\r
+                setState(1053);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(1041);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(1042);\r
+                        match(LEFT_BRACE);\r
+                        setState(1049);\r
+                        _errHandler.sync(this);\r
+                        _la = _input.LA(1);\r
+                        while (((((_la - 18)) & ~0x3f) == 0 && ((1L << (_la - 18)) & ((1L << (STATUS_KEYWORD - 18))\r
+                                | (1L << (REFERENCE_KEYWORD - 18))\r
+                                | (1L << (DESCRIPTION_KEYWORD - 18)) | (1L << (ARGUMENT_KEYWORD - 18)))) != 0)) {\r
+                            {\r
+                                setState(1047);\r
+                                switch (_input.LA(1)) {\r
+                                case ARGUMENT_KEYWORD: {\r
+                                    setState(1043);\r
+                                    argument_stmt();\r
+                                }\r
+                                    break;\r
+                                case STATUS_KEYWORD: {\r
+                                    setState(1044);\r
+                                    status_stmt();\r
+                                }\r
+                                    break;\r
+                                case DESCRIPTION_KEYWORD: {\r
+                                    setState(1045);\r
+                                    description_stmt();\r
+                                }\r
+                                    break;\r
+                                case REFERENCE_KEYWORD: {\r
+                                    setState(1046);\r
+                                    reference_stmt();\r
+                                }\r
+                                    break;\r
+                                default:\r
+                                    throw new NoViableAltException(this);\r
+                                }\r
+                            }\r
+                            setState(1051);\r
+                            _errHandler.sync(this);\r
+                            _la = _input.LA(1);\r
+                        }\r
+                        setState(1052);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Revision_date_stmtContext extends ParserRuleContext {\r
+        public TerminalNode REVISION_DATE_KEYWORD() {\r
+            return getToken(YangParser.REVISION_DATE_KEYWORD, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Revision_date_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_revision_date_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterRevision_date_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitRevision_date_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRevision_date_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Revision_date_stmtContext revision_date_stmt()\r
+            throws RecognitionException {\r
+        Revision_date_stmtContext _localctx = new Revision_date_stmtContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 168, RULE_revision_date_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1055);\r
+                match(REVISION_DATE_KEYWORD);\r
+                setState(1056);\r
+                string();\r
+                setState(1057);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Revision_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt() {\r
+            return getRuleContext(Reference_stmtContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public TerminalNode REVISION_KEYWORD() {\r
+            return getToken(YangParser.REVISION_KEYWORD, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt() {\r
+            return getRuleContext(Description_stmtContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Revision_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_revision_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterRevision_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitRevision_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRevision_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Revision_stmtContext revision_stmt()\r
+            throws RecognitionException {\r
+        Revision_stmtContext _localctx = new Revision_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 170, RULE_revision_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1059);\r
+                match(REVISION_KEYWORD);\r
+                setState(1060);\r
+                string();\r
+                setState(1070);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(1061);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(1062);\r
+                        match(LEFT_BRACE);\r
+                        setState(1064);\r
+                        _la = _input.LA(1);\r
+                        if (_la == DESCRIPTION_KEYWORD) {\r
+                            {\r
+                                setState(1063);\r
+                                description_stmt();\r
+                            }\r
+                        }\r
+\r
+                        setState(1067);\r
+                        _la = _input.LA(1);\r
+                        if (_la == REFERENCE_KEYWORD) {\r
+                            {\r
+                                setState(1066);\r
+                                reference_stmt();\r
+                            }\r
+                        }\r
+\r
+                        setState(1069);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Units_stmtContext extends ParserRuleContext {\r
+        public TerminalNode UNITS_KEYWORD() {\r
+            return getToken(YangParser.UNITS_KEYWORD, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Units_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_units_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterUnits_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitUnits_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitUnits_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Units_stmtContext units_stmt() throws RecognitionException {\r
+        Units_stmtContext _localctx = new Units_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 172, RULE_units_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1072);\r
+                match(UNITS_KEYWORD);\r
+                setState(1073);\r
+                string();\r
+                setState(1074);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Reference_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode REFERENCE_KEYWORD() {\r
+            return getToken(YangParser.REFERENCE_KEYWORD, 0);\r
+        }\r
+\r
+        public Reference_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_reference_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterReference_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitReference_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitReference_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Reference_stmtContext reference_stmt()\r
+            throws RecognitionException {\r
+        Reference_stmtContext _localctx = new Reference_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 174, RULE_reference_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1076);\r
+                match(REFERENCE_KEYWORD);\r
+                setState(1077);\r
+                string();\r
+                setState(1078);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Description_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode DESCRIPTION_KEYWORD() {\r
+            return getToken(YangParser.DESCRIPTION_KEYWORD, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Description_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_description_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterDescription_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitDescription_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitDescription_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Description_stmtContext description_stmt()\r
+            throws RecognitionException {\r
+        Description_stmtContext _localctx = new Description_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 176, RULE_description_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1080);\r
+                match(DESCRIPTION_KEYWORD);\r
+                setState(1081);\r
+                string();\r
+                setState(1082);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Contact_stmtContext extends ParserRuleContext {\r
+        public TerminalNode CONTACT_KEYWORD() {\r
+            return getToken(YangParser.CONTACT_KEYWORD, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Contact_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_contact_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterContact_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitContact_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitContact_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Contact_stmtContext contact_stmt() throws RecognitionException {\r
+        Contact_stmtContext _localctx = new Contact_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 178, RULE_contact_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1084);\r
+                match(CONTACT_KEYWORD);\r
+                setState(1085);\r
+                string();\r
+                setState(1086);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Organization_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode ORGANIZATION_KEYWORD() {\r
+            return getToken(YangParser.ORGANIZATION_KEYWORD, 0);\r
+        }\r
+\r
+        public Organization_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_organization_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterOrganization_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitOrganization_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitOrganization_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Organization_stmtContext organization_stmt()\r
+            throws RecognitionException {\r
+        Organization_stmtContext _localctx = new Organization_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 180, RULE_organization_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1088);\r
+                match(ORGANIZATION_KEYWORD);\r
+                setState(1089);\r
+                string();\r
+                setState(1090);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Belongs_to_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode BELONGS_TO_KEYWORD() {\r
+            return getToken(YangParser.BELONGS_TO_KEYWORD, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Prefix_stmtContext prefix_stmt() {\r
+            return getRuleContext(Prefix_stmtContext.class, 0);\r
+        }\r
+\r
+        public Belongs_to_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_belongs_to_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterBelongs_to_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitBelongs_to_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitBelongs_to_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Belongs_to_stmtContext belongs_to_stmt()\r
+            throws RecognitionException {\r
+        Belongs_to_stmtContext _localctx = new Belongs_to_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 182, RULE_belongs_to_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1092);\r
+                match(BELONGS_TO_KEYWORD);\r
+                setState(1093);\r
+                string();\r
+                setState(1094);\r
+                match(LEFT_BRACE);\r
+                setState(1095);\r
+                prefix_stmt();\r
+                setState(1096);\r
+                match(RIGHT_BRACE);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Prefix_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode PREFIX_KEYWORD() {\r
+            return getToken(YangParser.PREFIX_KEYWORD, 0);\r
+        }\r
+\r
+        public Prefix_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_prefix_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterPrefix_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitPrefix_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitPrefix_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Prefix_stmtContext prefix_stmt() throws RecognitionException {\r
+        Prefix_stmtContext _localctx = new Prefix_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 184, RULE_prefix_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1098);\r
+                match(PREFIX_KEYWORD);\r
+                setState(1099);\r
+                string();\r
+                setState(1100);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Namespace_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode NAMESPACE_KEYWORD() {\r
+            return getToken(YangParser.NAMESPACE_KEYWORD, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public Namespace_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_namespace_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterNamespace_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitNamespace_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitNamespace_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Namespace_stmtContext namespace_stmt()\r
+            throws RecognitionException {\r
+        Namespace_stmtContext _localctx = new Namespace_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 186, RULE_namespace_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1102);\r
+                match(NAMESPACE_KEYWORD);\r
+                setState(1103);\r
+                string();\r
+                setState(1104);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Include_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public TerminalNode SEMICOLON() {\r
+            return getToken(YangParser.SEMICOLON, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode INCLUDE_KEYWORD() {\r
+            return getToken(YangParser.INCLUDE_KEYWORD, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Revision_date_stmtContext revision_date_stmt() {\r
+            return getRuleContext(Revision_date_stmtContext.class, 0);\r
+        }\r
+\r
+        public Include_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_include_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterInclude_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitInclude_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitInclude_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Include_stmtContext include_stmt() throws RecognitionException {\r
+        Include_stmtContext _localctx = new Include_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 188, RULE_include_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1106);\r
+                match(INCLUDE_KEYWORD);\r
+                setState(1107);\r
+                string();\r
+                setState(1114);\r
+                switch (_input.LA(1)) {\r
+                case SEMICOLON: {\r
+                    setState(1108);\r
+                    match(SEMICOLON);\r
+                }\r
+                    break;\r
+                case LEFT_BRACE: {\r
+                    {\r
+                        setState(1109);\r
+                        match(LEFT_BRACE);\r
+                        setState(1111);\r
+                        _la = _input.LA(1);\r
+                        if (_la == REVISION_DATE_KEYWORD) {\r
+                            {\r
+                                setState(1110);\r
+                                revision_date_stmt();\r
+                            }\r
+                        }\r
+\r
+                        setState(1113);\r
+                        match(RIGHT_BRACE);\r
+                    }\r
+                }\r
+                    break;\r
+                default:\r
+                    throw new NoViableAltException(this);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Import_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Prefix_stmtContext prefix_stmt() {\r
+            return getRuleContext(Prefix_stmtContext.class, 0);\r
+        }\r
+\r
+        public Revision_date_stmtContext revision_date_stmt() {\r
+            return getRuleContext(Revision_date_stmtContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode IMPORT_KEYWORD() {\r
+            return getToken(YangParser.IMPORT_KEYWORD, 0);\r
+        }\r
+\r
+        public Import_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_import_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterImport_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitImport_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitImport_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Import_stmtContext import_stmt() throws RecognitionException {\r
+        Import_stmtContext _localctx = new Import_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 190, RULE_import_stmt);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1116);\r
+                match(IMPORT_KEYWORD);\r
+                setState(1117);\r
+                string();\r
+                setState(1118);\r
+                match(LEFT_BRACE);\r
+                setState(1119);\r
+                prefix_stmt();\r
+                setState(1121);\r
+                _la = _input.LA(1);\r
+                if (_la == REVISION_DATE_KEYWORD) {\r
+                    {\r
+                        setState(1120);\r
+                        revision_date_stmt();\r
+                    }\r
+                }\r
+\r
+                setState(1123);\r
+                match(RIGHT_BRACE);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Yang_version_stmtContext extends ParserRuleContext {\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public StmtendContext stmtend() {\r
+            return getRuleContext(StmtendContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode YANG_VERSION_KEYWORD() {\r
+            return getToken(YangParser.YANG_VERSION_KEYWORD, 0);\r
+        }\r
+\r
+        public Yang_version_stmtContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_yang_version_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterYang_version_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitYang_version_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitYang_version_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Yang_version_stmtContext yang_version_stmt()\r
+            throws RecognitionException {\r
+        Yang_version_stmtContext _localctx = new Yang_version_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 192, RULE_yang_version_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1125);\r
+                match(YANG_VERSION_KEYWORD);\r
+                setState(1126);\r
+                string();\r
+                setState(1127);\r
+                stmtend();\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Data_def_stmtContext extends ParserRuleContext {\r
+        public Uses_stmtContext uses_stmt() {\r
+            return getRuleContext(Uses_stmtContext.class, 0);\r
+        }\r
+\r
+        public Anyxml_stmtContext anyxml_stmt() {\r
+            return getRuleContext(Anyxml_stmtContext.class, 0);\r
+        }\r
+\r
+        public List_stmtContext list_stmt() {\r
+            return getRuleContext(List_stmtContext.class, 0);\r
+        }\r
+\r
+        public Leaf_stmtContext leaf_stmt() {\r
+            return getRuleContext(Leaf_stmtContext.class, 0);\r
+        }\r
+\r
+        public Container_stmtContext container_stmt() {\r
+            return getRuleContext(Container_stmtContext.class, 0);\r
+        }\r
+\r
+        public Choice_stmtContext choice_stmt() {\r
+            return getRuleContext(Choice_stmtContext.class, 0);\r
+        }\r
+\r
+        public Leaf_list_stmtContext leaf_list_stmt() {\r
+            return getRuleContext(Leaf_list_stmtContext.class, 0);\r
+        }\r
+\r
+        public Data_def_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_data_def_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterData_def_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitData_def_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitData_def_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Data_def_stmtContext data_def_stmt()\r
+            throws RecognitionException {\r
+        Data_def_stmtContext _localctx = new Data_def_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 194, RULE_data_def_stmt);\r
+        try {\r
+            setState(1136);\r
+            switch (_input.LA(1)) {\r
+            case CONTAINER_KEYWORD:\r
+                enterOuterAlt(_localctx, 1);\r
+                {\r
+                    setState(1129);\r
+                    container_stmt();\r
+                }\r
+                break;\r
+            case LEAF_KEYWORD:\r
+                enterOuterAlt(_localctx, 2);\r
+                {\r
+                    setState(1130);\r
+                    leaf_stmt();\r
+                }\r
+                break;\r
+            case LEAF_LIST_KEYWORD:\r
+                enterOuterAlt(_localctx, 3);\r
+                {\r
+                    setState(1131);\r
+                    leaf_list_stmt();\r
+                }\r
+                break;\r
+            case LIST_KEYWORD:\r
+                enterOuterAlt(_localctx, 4);\r
+                {\r
+                    setState(1132);\r
+                    list_stmt();\r
+                }\r
+                break;\r
+            case CHOICE_KEYWORD:\r
+                enterOuterAlt(_localctx, 5);\r
+                {\r
+                    setState(1133);\r
+                    choice_stmt();\r
+                }\r
+                break;\r
+            case ANYXML_KEYWORD:\r
+                enterOuterAlt(_localctx, 6);\r
+                {\r
+                    setState(1134);\r
+                    anyxml_stmt();\r
+                }\r
+                break;\r
+            case USES_KEYWORD:\r
+                enterOuterAlt(_localctx, 7);\r
+                {\r
+                    setState(1135);\r
+                    uses_stmt();\r
+                }\r
+                break;\r
+            default:\r
+                throw new NoViableAltException(this);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Body_stmtsContext extends ParserRuleContext {\r
+        public List<Grouping_stmtContext> grouping_stmt() {\r
+            return getRuleContexts(Grouping_stmtContext.class);\r
+        }\r
+\r
+        public List<Feature_stmtContext> feature_stmt() {\r
+            return getRuleContexts(Feature_stmtContext.class);\r
+        }\r
+\r
+        public Identity_stmtContext identity_stmt(int i) {\r
+            return getRuleContext(Identity_stmtContext.class, i);\r
+        }\r
+\r
+        public Typedef_stmtContext typedef_stmt(int i) {\r
+            return getRuleContext(Typedef_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Notification_stmtContext> notification_stmt() {\r
+            return getRuleContexts(Notification_stmtContext.class);\r
+        }\r
+\r
+        public Grouping_stmtContext grouping_stmt(int i) {\r
+            return getRuleContext(Grouping_stmtContext.class, i);\r
+        }\r
+\r
+        public Deviation_stmtContext deviation_stmt(int i) {\r
+            return getRuleContext(Deviation_stmtContext.class, i);\r
+        }\r
+\r
+        public Rpc_stmtContext rpc_stmt(int i) {\r
+            return getRuleContext(Rpc_stmtContext.class, i);\r
+        }\r
+\r
+        public Feature_stmtContext feature_stmt(int i) {\r
+            return getRuleContext(Feature_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Augment_stmtContext> augment_stmt() {\r
+            return getRuleContexts(Augment_stmtContext.class);\r
+        }\r
+\r
+        public List<Rpc_stmtContext> rpc_stmt() {\r
+            return getRuleContexts(Rpc_stmtContext.class);\r
+        }\r
+\r
+        public List<Typedef_stmtContext> typedef_stmt() {\r
+            return getRuleContexts(Typedef_stmtContext.class);\r
+        }\r
+\r
+        public Data_def_stmtContext data_def_stmt(int i) {\r
+            return getRuleContext(Data_def_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Extension_stmtContext> extension_stmt() {\r
+            return getRuleContexts(Extension_stmtContext.class);\r
+        }\r
+\r
+        public Extension_stmtContext extension_stmt(int i) {\r
+            return getRuleContext(Extension_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Data_def_stmtContext> data_def_stmt() {\r
+            return getRuleContexts(Data_def_stmtContext.class);\r
+        }\r
+\r
+        public List<Identity_stmtContext> identity_stmt() {\r
+            return getRuleContexts(Identity_stmtContext.class);\r
+        }\r
+\r
+        public List<Deviation_stmtContext> deviation_stmt() {\r
+            return getRuleContexts(Deviation_stmtContext.class);\r
+        }\r
+\r
+        public Augment_stmtContext augment_stmt(int i) {\r
+            return getRuleContext(Augment_stmtContext.class, i);\r
+        }\r
+\r
+        public Notification_stmtContext notification_stmt(int i) {\r
+            return getRuleContext(Notification_stmtContext.class, i);\r
+        }\r
+\r
+        public Body_stmtsContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_body_stmts;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterBody_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitBody_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitBody_stmts(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Body_stmtsContext body_stmts() throws RecognitionException {\r
+        Body_stmtsContext _localctx = new Body_stmtsContext(_ctx, getState());\r
+        enterRule(_localctx, 196, RULE_body_stmts);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1152);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                while (((((_la - 12)) & ~0x3f) == 0 && ((1L << (_la - 12)) & ((1L << (USES_KEYWORD - 12))\r
+                        | (1L << (TYPEDEF_KEYWORD - 12))\r
+                        | (1L << (RPC_KEYWORD - 12))\r
+                        | (1L << (NOTIFICATION_KEYWORD - 12))\r
+                        | (1L << (LIST_KEYWORD - 12))\r
+                        | (1L << (LEAF_LIST_KEYWORD - 12))\r
+                        | (1L << (LEAF_KEYWORD - 12))\r
+                        | (1L << (IDENTITY_KEYWORD - 12))\r
+                        | (1L << (GROUPING_KEYWORD - 12))\r
+                        | (1L << (FEATURE_KEYWORD - 12))\r
+                        | (1L << (DEVIATION_KEYWORD - 12))\r
+                        | (1L << (EXTENSION_KEYWORD - 12))\r
+                        | (1L << (CONTAINER_KEYWORD - 12))\r
+                        | (1L << (CHOICE_KEYWORD - 12))\r
+                        | (1L << (AUGMENT_KEYWORD - 12)) | (1L << (ANYXML_KEYWORD - 12)))) != 0)) {\r
+                    {\r
+                        {\r
+                            setState(1148);\r
+                            switch (_input.LA(1)) {\r
+                            case EXTENSION_KEYWORD: {\r
+                                setState(1138);\r
+                                extension_stmt();\r
+                            }\r
+                                break;\r
+                            case FEATURE_KEYWORD: {\r
+                                setState(1139);\r
+                                feature_stmt();\r
+                            }\r
+                                break;\r
+                            case IDENTITY_KEYWORD: {\r
+                                setState(1140);\r
+                                identity_stmt();\r
+                            }\r
+                                break;\r
+                            case TYPEDEF_KEYWORD: {\r
+                                setState(1141);\r
+                                typedef_stmt();\r
+                            }\r
+                                break;\r
+                            case GROUPING_KEYWORD: {\r
+                                setState(1142);\r
+                                grouping_stmt();\r
+                            }\r
+                                break;\r
+                            case USES_KEYWORD:\r
+                            case LIST_KEYWORD:\r
+                            case LEAF_LIST_KEYWORD:\r
+                            case LEAF_KEYWORD:\r
+                            case CONTAINER_KEYWORD:\r
+                            case CHOICE_KEYWORD:\r
+                            case ANYXML_KEYWORD: {\r
+                                setState(1143);\r
+                                data_def_stmt();\r
+                            }\r
+                                break;\r
+                            case AUGMENT_KEYWORD: {\r
+                                setState(1144);\r
+                                augment_stmt();\r
+                            }\r
+                                break;\r
+                            case RPC_KEYWORD: {\r
+                                setState(1145);\r
+                                rpc_stmt();\r
+                            }\r
+                                break;\r
+                            case NOTIFICATION_KEYWORD: {\r
+                                setState(1146);\r
+                                notification_stmt();\r
+                            }\r
+                                break;\r
+                            case DEVIATION_KEYWORD: {\r
+                                setState(1147);\r
+                                deviation_stmt();\r
+                            }\r
+                                break;\r
+                            default:\r
+                                throw new NoViableAltException(this);\r
+                            }\r
+                        }\r
+                    }\r
+                    setState(1154);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Revision_stmtsContext extends ParserRuleContext {\r
+        public List<Revision_stmtContext> revision_stmt() {\r
+            return getRuleContexts(Revision_stmtContext.class);\r
+        }\r
+\r
+        public Revision_stmtContext revision_stmt(int i) {\r
+            return getRuleContext(Revision_stmtContext.class, i);\r
+        }\r
+\r
+        public Revision_stmtsContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_revision_stmts;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterRevision_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitRevision_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitRevision_stmts(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Revision_stmtsContext revision_stmts()\r
+            throws RecognitionException {\r
+        Revision_stmtsContext _localctx = new Revision_stmtsContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 198, RULE_revision_stmts);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1158);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                while (_la == REVISION_KEYWORD) {\r
+                    {\r
+                        {\r
+                            setState(1155);\r
+                            revision_stmt();\r
+                        }\r
+                    }\r
+                    setState(1160);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Linkage_stmtsContext extends ParserRuleContext {\r
+        public List<Include_stmtContext> include_stmt() {\r
+            return getRuleContexts(Include_stmtContext.class);\r
+        }\r
+\r
+        public Import_stmtContext import_stmt(int i) {\r
+            return getRuleContext(Import_stmtContext.class, i);\r
+        }\r
+\r
+        public Include_stmtContext include_stmt(int i) {\r
+            return getRuleContext(Include_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Import_stmtContext> import_stmt() {\r
+            return getRuleContexts(Import_stmtContext.class);\r
+        }\r
+\r
+        public Linkage_stmtsContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_linkage_stmts;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterLinkage_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitLinkage_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitLinkage_stmts(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Linkage_stmtsContext linkage_stmts()\r
+            throws RecognitionException {\r
+        Linkage_stmtsContext _localctx = new Linkage_stmtsContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 200, RULE_linkage_stmts);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1165);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                while (_la == INCLUDE_KEYWORD || _la == IMPORT_KEYWORD) {\r
+                    {\r
+                        setState(1163);\r
+                        switch (_input.LA(1)) {\r
+                        case IMPORT_KEYWORD: {\r
+                            setState(1161);\r
+                            import_stmt();\r
+                        }\r
+                            break;\r
+                        case INCLUDE_KEYWORD: {\r
+                            setState(1162);\r
+                            include_stmt();\r
+                        }\r
+                            break;\r
+                        default:\r
+                            throw new NoViableAltException(this);\r
+                        }\r
+                    }\r
+                    setState(1167);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Meta_stmtsContext extends ParserRuleContext {\r
+        public List<Reference_stmtContext> reference_stmt() {\r
+            return getRuleContexts(Reference_stmtContext.class);\r
+        }\r
+\r
+        public Description_stmtContext description_stmt(int i) {\r
+            return getRuleContext(Description_stmtContext.class, i);\r
+        }\r
+\r
+        public Organization_stmtContext organization_stmt(int i) {\r
+            return getRuleContext(Organization_stmtContext.class, i);\r
+        }\r
+\r
+        public Contact_stmtContext contact_stmt(int i) {\r
+            return getRuleContext(Contact_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Contact_stmtContext> contact_stmt() {\r
+            return getRuleContexts(Contact_stmtContext.class);\r
+        }\r
+\r
+        public List<Organization_stmtContext> organization_stmt() {\r
+            return getRuleContexts(Organization_stmtContext.class);\r
+        }\r
+\r
+        public List<Description_stmtContext> description_stmt() {\r
+            return getRuleContexts(Description_stmtContext.class);\r
+        }\r
+\r
+        public Reference_stmtContext reference_stmt(int i) {\r
+            return getRuleContext(Reference_stmtContext.class, i);\r
+        }\r
+\r
+        public Meta_stmtsContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_meta_stmts;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterMeta_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitMeta_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitMeta_stmts(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Meta_stmtsContext meta_stmts() throws RecognitionException {\r
+        Meta_stmtsContext _localctx = new Meta_stmtsContext(_ctx, getState());\r
+        enterRule(_localctx, 202, RULE_meta_stmts);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1174);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << REFERENCE_KEYWORD)\r
+                        | (1L << ORGANIZATION_KEYWORD)\r
+                        | (1L << DESCRIPTION_KEYWORD) | (1L << CONTACT_KEYWORD))) != 0)) {\r
+                    {\r
+                        setState(1172);\r
+                        switch (_input.LA(1)) {\r
+                        case ORGANIZATION_KEYWORD: {\r
+                            setState(1168);\r
+                            organization_stmt();\r
+                        }\r
+                            break;\r
+                        case CONTACT_KEYWORD: {\r
+                            setState(1169);\r
+                            contact_stmt();\r
+                        }\r
+                            break;\r
+                        case DESCRIPTION_KEYWORD: {\r
+                            setState(1170);\r
+                            description_stmt();\r
+                        }\r
+                            break;\r
+                        case REFERENCE_KEYWORD: {\r
+                            setState(1171);\r
+                            reference_stmt();\r
+                        }\r
+                            break;\r
+                        default:\r
+                            throw new NoViableAltException(this);\r
+                        }\r
+                    }\r
+                    setState(1176);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                }\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Submodule_header_stmtsContext extends ParserRuleContext {\r
+        public Belongs_to_stmtContext belongs_to_stmt(int i) {\r
+            return getRuleContext(Belongs_to_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Belongs_to_stmtContext> belongs_to_stmt() {\r
+            return getRuleContexts(Belongs_to_stmtContext.class);\r
+        }\r
+\r
+        public Yang_version_stmtContext yang_version_stmt(int i) {\r
+            return getRuleContext(Yang_version_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Yang_version_stmtContext> yang_version_stmt() {\r
+            return getRuleContexts(Yang_version_stmtContext.class);\r
+        }\r
+\r
+        public Submodule_header_stmtsContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_submodule_header_stmts;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .enterSubmodule_header_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener)\r
+                        .exitSubmodule_header_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitSubmodule_header_stmts(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Submodule_header_stmtsContext submodule_header_stmts()\r
+            throws RecognitionException {\r
+        Submodule_header_stmtsContext _localctx = new Submodule_header_stmtsContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 204, RULE_submodule_header_stmts);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1179);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                do {\r
+                    {\r
+                        setState(1179);\r
+                        switch (_input.LA(1)) {\r
+                        case YANG_VERSION_KEYWORD: {\r
+                            setState(1177);\r
+                            yang_version_stmt();\r
+                        }\r
+                            break;\r
+                        case BELONGS_TO_KEYWORD: {\r
+                            setState(1178);\r
+                            belongs_to_stmt();\r
+                        }\r
+                            break;\r
+                        default:\r
+                            throw new NoViableAltException(this);\r
+                        }\r
+                    }\r
+                    setState(1181);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                } while (_la == YANG_VERSION_KEYWORD\r
+                        || _la == BELONGS_TO_KEYWORD);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Module_header_stmtsContext extends ParserRuleContext {\r
+        public List<Namespace_stmtContext> namespace_stmt() {\r
+            return getRuleContexts(Namespace_stmtContext.class);\r
+        }\r
+\r
+        public Namespace_stmtContext namespace_stmt(int i) {\r
+            return getRuleContext(Namespace_stmtContext.class, i);\r
+        }\r
+\r
+        public Yang_version_stmtContext yang_version_stmt(int i) {\r
+            return getRuleContext(Yang_version_stmtContext.class, i);\r
+        }\r
+\r
+        public Prefix_stmtContext prefix_stmt(int i) {\r
+            return getRuleContext(Prefix_stmtContext.class, i);\r
+        }\r
+\r
+        public List<Prefix_stmtContext> prefix_stmt() {\r
+            return getRuleContexts(Prefix_stmtContext.class);\r
+        }\r
+\r
+        public List<Yang_version_stmtContext> yang_version_stmt() {\r
+            return getRuleContexts(Yang_version_stmtContext.class);\r
+        }\r
+\r
+        public Module_header_stmtsContext(ParserRuleContext parent,\r
+                int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_module_header_stmts;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterModule_header_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitModule_header_stmts(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitModule_header_stmts(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Module_header_stmtsContext module_header_stmts()\r
+            throws RecognitionException {\r
+        Module_header_stmtsContext _localctx = new Module_header_stmtsContext(\r
+                _ctx, getState());\r
+        enterRule(_localctx, 206, RULE_module_header_stmts);\r
+        int _la;\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1186);\r
+                _errHandler.sync(this);\r
+                _la = _input.LA(1);\r
+                do {\r
+                    {\r
+                        setState(1186);\r
+                        switch (_input.LA(1)) {\r
+                        case YANG_VERSION_KEYWORD: {\r
+                            setState(1183);\r
+                            yang_version_stmt();\r
+                        }\r
+                            break;\r
+                        case NAMESPACE_KEYWORD: {\r
+                            setState(1184);\r
+                            namespace_stmt();\r
+                        }\r
+                            break;\r
+                        case PREFIX_KEYWORD: {\r
+                            setState(1185);\r
+                            prefix_stmt();\r
+                        }\r
+                            break;\r
+                        default:\r
+                            throw new NoViableAltException(this);\r
+                        }\r
+                    }\r
+                    setState(1188);\r
+                    _errHandler.sync(this);\r
+                    _la = _input.LA(1);\r
+                } while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << YANG_VERSION_KEYWORD)\r
+                        | (1L << PREFIX_KEYWORD) | (1L << NAMESPACE_KEYWORD))) != 0));\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Submodule_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public Linkage_stmtsContext linkage_stmts() {\r
+            return getRuleContext(Linkage_stmtsContext.class, 0);\r
+        }\r
+\r
+        public Revision_stmtsContext revision_stmts() {\r
+            return getRuleContext(Revision_stmtsContext.class, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public Body_stmtsContext body_stmts() {\r
+            return getRuleContext(Body_stmtsContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public TerminalNode SUBMODULE_KEYWORD() {\r
+            return getToken(YangParser.SUBMODULE_KEYWORD, 0);\r
+        }\r
+\r
+        public Submodule_header_stmtsContext submodule_header_stmts() {\r
+            return getRuleContext(Submodule_header_stmtsContext.class, 0);\r
+        }\r
+\r
+        public Meta_stmtsContext meta_stmts() {\r
+            return getRuleContext(Meta_stmtsContext.class, 0);\r
+        }\r
+\r
+        public Submodule_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_submodule_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterSubmodule_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitSubmodule_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitSubmodule_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Submodule_stmtContext submodule_stmt()\r
+            throws RecognitionException {\r
+        Submodule_stmtContext _localctx = new Submodule_stmtContext(_ctx,\r
+                getState());\r
+        enterRule(_localctx, 208, RULE_submodule_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1190);\r
+                match(SUBMODULE_KEYWORD);\r
+                setState(1191);\r
+                string();\r
+                setState(1192);\r
+                match(LEFT_BRACE);\r
+                setState(1193);\r
+                submodule_header_stmts();\r
+                setState(1194);\r
+                linkage_stmts();\r
+                setState(1195);\r
+                meta_stmts();\r
+                setState(1196);\r
+                revision_stmts();\r
+                setState(1197);\r
+                body_stmts();\r
+                setState(1198);\r
+                match(RIGHT_BRACE);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static class Module_stmtContext extends ParserRuleContext {\r
+        public TerminalNode RIGHT_BRACE() {\r
+            return getToken(YangParser.RIGHT_BRACE, 0);\r
+        }\r
+\r
+        public Linkage_stmtsContext linkage_stmts() {\r
+            return getRuleContext(Linkage_stmtsContext.class, 0);\r
+        }\r
+\r
+        public Revision_stmtsContext revision_stmts() {\r
+            return getRuleContext(Revision_stmtsContext.class, 0);\r
+        }\r
+\r
+        public StringContext string() {\r
+            return getRuleContext(StringContext.class, 0);\r
+        }\r
+\r
+        public Body_stmtsContext body_stmts() {\r
+            return getRuleContext(Body_stmtsContext.class, 0);\r
+        }\r
+\r
+        public Module_header_stmtsContext module_header_stmts() {\r
+            return getRuleContext(Module_header_stmtsContext.class, 0);\r
+        }\r
+\r
+        public TerminalNode MODULE_KEYWORD() {\r
+            return getToken(YangParser.MODULE_KEYWORD, 0);\r
+        }\r
+\r
+        public TerminalNode LEFT_BRACE() {\r
+            return getToken(YangParser.LEFT_BRACE, 0);\r
+        }\r
+\r
+        public Meta_stmtsContext meta_stmts() {\r
+            return getRuleContext(Meta_stmtsContext.class, 0);\r
+        }\r
+\r
+        public Module_stmtContext(ParserRuleContext parent, int invokingState) {\r
+            super(parent, invokingState);\r
+        }\r
+\r
+        @Override\r
+        public int getRuleIndex() {\r
+            return RULE_module_stmt;\r
+        }\r
+\r
+        @Override\r
+        public void enterRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).enterModule_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public void exitRule(ParseTreeListener listener) {\r
+            if (listener instanceof YangParserListener)\r
+                ((YangParserListener) listener).exitModule_stmt(this);\r
+        }\r
+\r
+        @Override\r
+        public <T> T accept(ParseTreeVisitor<? extends T> visitor) {\r
+            if (visitor instanceof YangParserVisitor)\r
+                return ((YangParserVisitor<? extends T>) visitor)\r
+                        .visitModule_stmt(this);\r
+            else\r
+                return visitor.visitChildren(this);\r
+        }\r
+    }\r
+\r
+    public final Module_stmtContext module_stmt() throws RecognitionException {\r
+        Module_stmtContext _localctx = new Module_stmtContext(_ctx, getState());\r
+        enterRule(_localctx, 210, RULE_module_stmt);\r
+        try {\r
+            enterOuterAlt(_localctx, 1);\r
+            {\r
+                setState(1200);\r
+                match(MODULE_KEYWORD);\r
+                setState(1201);\r
+                string();\r
+                setState(1202);\r
+                match(LEFT_BRACE);\r
+                setState(1203);\r
+                module_header_stmts();\r
+                setState(1204);\r
+                linkage_stmts();\r
+                setState(1205);\r
+                meta_stmts();\r
+                setState(1206);\r
+                revision_stmts();\r
+                setState(1207);\r
+                body_stmts();\r
+                setState(1208);\r
+                match(RIGHT_BRACE);\r
+            }\r
+        } catch (RecognitionException re) {\r
+            _localctx.exception = re;\r
+            _errHandler.reportError(this, re);\r
+            _errHandler.recover(this, re);\r
+        } finally {\r
+            exitRule();\r
+        }\r
+        return _localctx;\r
+    }\r
+\r
+    public static final String _serializedATN = "\2\3M\u04bd\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4"\r
+            + "\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20"\r
+            + "\4\21\t\21\4\22\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27"\r
+            + "\4\30\t\30\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36"\r
+            + "\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4"\r
+            + ")\t)\4*\t*\4+\t+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62"\r
+            + "\4\63\t\63\4\64\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4"\r
+            + ";\t;\4<\t<\4=\t=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\t"\r
+            + "F\4G\tG\4H\tH\4I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4"\r
+            + "R\tR\4S\tS\4T\tT\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]"\r
+            + "\t]\4^\t^\4_\t_\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th"\r
+            + "\4i\ti\4j\tj\4k\tk\3\2\3\2\5\2\u00d9\n\2\3\3\3\3\3\3\7\3\u00de\n\3\f\3"\r
+            + "\16\3\u00e1\13\3\3\4\3\4\5\4\u00e5\n\4\3\4\3\4\3\5\3\5\5\5\u00eb\n\5\3"\r
+            + "\5\3\5\5\5\u00ef\n\5\3\5\5\5\u00f2\n\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6"\r
+            + "\3\6\3\6\3\6\7\6\u00ff\n\6\f\6\16\6\u0102\13\6\3\6\5\6\u0105\n\6\3\7\3"\r
+            + "\7\3\7\3\7\3\7\3\7\3\7\3\7\7\7\u010f\n\7\f\7\16\7\u0112\13\7\3\7\5\7\u0115"\r
+            + "\n\7\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\7\b\u0123\n\b\f\b"\r
+            + "\16\b\u0126\13\b\3\b\5\b\u0129\n\b\3\t\3\t\3\t\3\t\3\t\5\t\u0130\n\t\3"\r
+            + "\t\5\t\u0133\n\t\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\6\n\u013e\n\n\r\n"\r
+            + "\16\n\u013f\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13"\r
+            + "\3\13\7\13\u014f\n\13\f\13\16\13\u0152\13\13\3\13\5\13\u0155\n\13\3\f"\r
+            + "\3\f\3\f\3\f\3\f\6\f\u015c\n\f\r\f\16\f\u015d\3\f\3\f\3\r\3\r\3\r\3\r"\r
+            + "\3\r\6\r\u0167\n\r\r\r\16\r\u0168\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16"\r
+            + "\3\16\3\16\3\16\3\16\3\16\3\16\7\16\u0179\n\16\f\16\16\16\u017c\13\16"\r
+            + "\3\16\5\16\u017f\n\16\3\17\3\17\3\17\3\17\3\17\3\17\7\17\u0187\n\17\f"\r
+            + "\17\16\17\u018a\13\17\3\17\5\17\u018d\n\17\3\20\3\20\3\20\3\20\3\20\3"\r
+            + "\20\3\20\3\20\3\20\3\20\3\20\6\20\u019a\n\20\r\20\16\20\u019b\3\20\3\20"\r
+            + "\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\6\21\u01ab\n\21"\r
+            + "\r\21\16\21\u01ac\3\21\3\21\3\22\3\22\3\22\3\22\3\22\7\22\u01b6\n\22\f"\r
+            + "\22\16\22\u01b9\13\22\3\23\3\23\7\23\u01bd\n\23\f\23\16\23\u01c0\13\23"\r
+            + "\3\24\3\24\3\24\3\24\3\24\7\24\u01c7\n\24\f\24\16\24\u01ca\13\24\3\25"\r
+            + "\3\25\3\25\3\25\3\25\3\25\7\25\u01d2\n\25\f\25\16\25\u01d5\13\25\3\26"\r
+            + "\3\26\3\26\3\26\3\26\3\26\7\26\u01dd\n\26\f\26\16\26\u01e0\13\26\3\27"\r
+            + "\3\27\3\27\3\27\3\27\3\27\7\27\u01e8\n\27\f\27\16\27\u01eb\13\27\3\30"\r
+            + "\3\30\3\30\3\30\3\30\7\30\u01f2\n\30\f\30\16\30\u01f5\13\30\3\31\3\31"\r
+            + "\3\31\3\31\3\31\3\31\3\31\5\31\u01fe\n\31\3\32\3\32\3\32\3\32\3\32\6\32"\r
+            + "\u0205\n\32\r\32\16\32\u0206\3\32\3\32\5\32\u020b\n\32\3\33\3\33\3\33"\r
+            + "\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\7\33\u0219\n\33\f\33\16"\r
+            + "\33\u021c\13\33\3\33\5\33\u021f\n\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34"\r
+            + "\3\34\3\34\3\34\3\34\3\34\3\34\7\34\u022e\n\34\f\34\16\34\u0231\13\34"\r
+            + "\3\34\5\34\u0234\n\34\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35"\r
+            + "\3\35\7\35\u0241\n\35\f\35\16\35\u0244\13\35\3\35\5\35\u0247\n\35\3\36"\r
+            + "\3\36\3\36\3\36\3\36\5\36\u024e\n\36\3\37\3\37\3\37\3\37\3\37\3\37\3\37"\r
+            + "\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\7\37\u025f\n\37\f\37\16\37\u0262"\r
+            + "\13\37\3\37\5\37\u0265\n\37\3 \3 \3 \3 \3!\3!\3!\3!\3\"\3\"\3\"\3\"\3"\r
+            + "\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\6\"\u0282\n"\r
+            + "\"\r\"\16\"\u0283\3\"\3\"\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3"\r
+            + "#\3#\7#\u0298\n#\f#\16#\u029b\13#\3#\3#\3$\3$\3$\3$\3$\3$\3$\3$\3$\3$"\r
+            + "\3$\3$\3$\3$\3$\7$\u02ae\n$\f$\16$\u02b1\13$\3$\3$\3%\3%\3%\3%\3%\3%\3"\r
+            + "%\3%\3%\3%\3%\3%\3%\3%\3%\3%\7%\u02c5\n%\f%\16%\u02c8\13%\3%\5%\u02cb"\r
+            + "\n%\3&\3&\3&\3&\3&\3&\3&\3&\3&\3&\3&\7&\u02d8\n&\f&\16&\u02db\13&\3&\5"\r
+            + "&\u02de\n&\3\'\3\'\3\'\3\'\3(\3(\3)\3)\3)\3)\3*\3*\3*\3*\3+\3+\3+\3+\3"\r
+            + ",\3,\3,\3,\3-\3-\3-\3-\3-\3-\3-\3-\3-\7-\u02ff\n-\f-\16-\u0302\13-\3-"\r
+            + "\5-\u0305\n-\3.\3.\3/\3/\3/\3/\3\60\3\60\3\60\3\60\3\61\3\61\3\62\3\62"\r
+            + "\3\62\3\62\3\63\3\63\3\64\3\64\3\64\3\64\3\65\3\65\3\66\3\66\3\66\3\66"\r
+            + "\3\67\3\67\3\67\3\67\38\38\38\38\38\38\38\38\38\78\u0330\n8\f8\168\u0333"\r
+            + "\138\38\58\u0336\n8\39\69\u0339\n9\r9\169\u033a\3:\6:\u033e\n:\r:\16:"\r
+            + "\u033f\3;\3;\3<\5<\u0345\n<\3=\3=\3>\3>\3>\3>\3?\3?\3?\3?\3@\3@\3A\3A"\r
+            + "\3A\3A\3A\3A\3A\3A\3A\7A\u035c\nA\fA\16A\u035f\13A\3A\5A\u0362\nA\3B\6"\r
+            + "B\u0365\nB\rB\16B\u0366\3C\3C\3C\3C\3D\3D\3D\3D\3D\3D\3D\3D\3D\7D\u0376"\r
+            + "\nD\fD\16D\u0379\13D\3D\5D\u037c\nD\3E\3E\3E\3E\3E\3E\3E\3E\3E\7E\u0387"\r
+            + "\nE\fE\16E\u038a\13E\3E\5E\u038d\nE\3F\3F\7F\u0391\nF\fF\16F\u0394\13"\r
+            + "F\3G\3G\3G\3G\3H\5H\u039b\nH\3H\3H\3H\5H\u03a0\nH\5H\u03a2\nH\3I\3I\3"\r
+            + "I\3I\3I\3I\3I\3I\3I\7I\u03ad\nI\fI\16I\u03b0\13I\3I\5I\u03b3\nI\3J\3J"\r
+            + "\3K\3K\3K\3K\3K\3K\3K\3K\3K\5K\u03c0\nK\3L\3L\3L\3L\3L\3L\3L\5L\u03c9"\r
+            + "\nL\3M\3M\3M\3M\3M\3M\3M\3M\3M\6M\u03d4\nM\rM\16M\u03d5\3M\3M\3N\3N\3"\r
+            + "N\3N\3O\3O\3O\3O\3O\3O\3O\3O\7O\u03e6\nO\fO\16O\u03e9\13O\3O\5O\u03ec"\r
+            + "\nO\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\7Q\u03fa\nQ\fQ\16Q\u03fd\13Q\3"\r
+            + "Q\5Q\u0400\nQ\3R\3R\3S\3S\3S\3S\3T\3T\3T\3T\3T\5T\u040d\nT\3T\5T\u0410"\r
+            + "\nT\3U\3U\3U\3U\3U\3U\3U\3U\7U\u041a\nU\fU\16U\u041d\13U\3U\5U\u0420\n"\r
+            + "U\3V\3V\3V\3V\3W\3W\3W\3W\3W\5W\u042b\nW\3W\5W\u042e\nW\3W\5W\u0431\n"\r
+            + "W\3X\3X\3X\3X\3Y\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3\\\3\\\3\\\3\\\3]\3"\r
+            + "]\3]\3]\3]\3]\3^\3^\3^\3^\3_\3_\3_\3_\3`\3`\3`\3`\3`\5`\u045a\n`\3`\5"\r
+            + "`\u045d\n`\3a\3a\3a\3a\3a\5a\u0464\na\3a\3a\3b\3b\3b\3b\3c\3c\3c\3c\3"\r
+            + "c\3c\3c\5c\u0473\nc\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\5d\u047f\nd\7d\u0481"\r
+            + "\nd\fd\16d\u0484\13d\3e\7e\u0487\ne\fe\16e\u048a\13e\3f\3f\7f\u048e\n"\r
+            + "f\ff\16f\u0491\13f\3g\3g\3g\3g\7g\u0497\ng\fg\16g\u049a\13g\3h\3h\6h\u049e"\r
+            + "\nh\rh\16h\u049f\3i\3i\3i\6i\u04a5\ni\ri\16i\u04a6\3j\3j\3j\3j\3j\3j\3"\r
+            + "j\3j\3j\3j\3k\3k\3k\3k\3k\3k\3k\3k\3k\3k\3k\2l\2\4\6\b\n\f\16\20\22\24"\r
+            + "\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNPRTVXZ\\^`bdfhjlnprtv"\r
+            + "xz|~\u0080\u0082\u0084\u0086\u0088\u008a\u008c\u008e\u0090\u0092\u0094"\r
+            + "\u0096\u0098\u009a\u009c\u009e\u00a0\u00a2\u00a4\u00a6\u00a8\u00aa\u00ac"\r
+            + "\u00ae\u00b0\u00b2\u00b4\u00b6\u00b8\u00ba\u00bc\u00be\u00c0\u00c2\u00c4"\r
+            + "\u00c6\u00c8\u00ca\u00cc\u00ce\u00d0\u00d2\u00d4\2\2\u05a3\2\u00d8\3\2"\r
+            + "\2\2\4\u00da\3\2\2\2\6\u00e2\3\2\2\2\b\u00f1\3\2\2\2\n\u00f3\3\2\2\2\f"\r
+            + "\u0106\3\2\2\2\16\u0116\3\2\2\2\20\u012a\3\2\2\2\22\u0134\3\2\2\2\24\u0143"\r
+            + "\3\2\2\2\26\u0156\3\2\2\2\30\u0161\3\2\2\2\32\u016c\3\2\2\2\34\u0180\3"\r
+            + "\2\2\2\36\u018e\3\2\2\2 \u019f\3\2\2\2\"\u01b7\3\2\2\2$\u01be\3\2\2\2"\r
+            + "&\u01c8\3\2\2\2(\u01d3\3\2\2\2*\u01de\3\2\2\2,\u01e9\3\2\2\2.\u01f3\3"\r
+            + "\2\2\2\60\u01fd\3\2\2\2\62\u01ff\3\2\2\2\64\u020c\3\2\2\2\66\u0220\3\2"\r
+            + "\2\28\u0235\3\2\2\2:\u024d\3\2\2\2<\u024f\3\2\2\2>\u0266\3\2\2\2@\u026a"\r
+            + "\3\2\2\2B\u026e\3\2\2\2D\u0287\3\2\2\2F\u029e\3\2\2\2H\u02b4\3\2\2\2J"\r
+            + "\u02cc\3\2\2\2L\u02df\3\2\2\2N\u02e3\3\2\2\2P\u02e5\3\2\2\2R\u02e9\3\2"\r
+            + "\2\2T\u02ed\3\2\2\2V\u02f1\3\2\2\2X\u02f5\3\2\2\2Z\u0306\3\2\2\2\\\u0308"\r
+            + "\3\2\2\2^\u030c\3\2\2\2`\u0310\3\2\2\2b\u0312\3\2\2\2d\u0316\3\2\2\2f"\r
+            + "\u0318\3\2\2\2h\u031c\3\2\2\2j\u031e\3\2\2\2l\u0322\3\2\2\2n\u0326\3\2"\r
+            + "\2\2p\u0338\3\2\2\2r\u033d\3\2\2\2t\u0341\3\2\2\2v\u0344\3\2\2\2x\u0346"\r
+            + "\3\2\2\2z\u0348\3\2\2\2|\u034c\3\2\2\2~\u0350\3\2\2\2\u0080\u0352\3\2"\r
+            + "\2\2\u0082\u0364\3\2\2\2\u0084\u0368\3\2\2\2\u0086\u036c\3\2\2\2\u0088"\r
+            + "\u037d\3\2\2\2\u008a\u0392\3\2\2\2\u008c\u0395\3\2\2\2\u008e\u03a1\3\2"\r
+            + "\2\2\u0090\u03a3\3\2\2\2\u0092\u03b4\3\2\2\2\u0094\u03bf\3\2\2\2\u0096"\r
+            + "\u03c1\3\2\2\2\u0098\u03ca\3\2\2\2\u009a\u03d9\3\2\2\2\u009c\u03dd\3\2"\r
+            + "\2\2\u009e\u03ed\3\2\2\2\u00a0\u03f1\3\2\2\2\u00a2\u0401\3\2\2\2\u00a4"\r
+            + "\u0403\3\2\2\2\u00a6\u0407\3\2\2\2\u00a8\u0411\3\2\2\2\u00aa\u0421\3\2"\r
+            + "\2\2\u00ac\u0425\3\2\2\2\u00ae\u0432\3\2\2\2\u00b0\u0436\3\2\2\2\u00b2"\r
+            + "\u043a\3\2\2\2\u00b4\u043e\3\2\2\2\u00b6\u0442\3\2\2\2\u00b8\u0446\3\2"\r
+            + "\2\2\u00ba\u044c\3\2\2\2\u00bc\u0450\3\2\2\2\u00be\u0454\3\2\2\2\u00c0"\r
+            + "\u045e\3\2\2\2\u00c2\u0467\3\2\2\2\u00c4\u0472\3\2\2\2\u00c6\u0482\3\2"\r
+            + "\2\2\u00c8\u0488\3\2\2\2\u00ca\u048f\3\2\2\2\u00cc\u0498\3\2\2\2\u00ce"\r
+            + "\u049d\3\2\2\2\u00d0\u04a4\3\2\2\2\u00d2\u04a8\3\2\2\2\u00d4\u04b2\3\2"\r
+            + "\2\2\u00d6\u00d9\5\u00d4k\2\u00d7\u00d9\5\u00d2j\2\u00d8\u00d6\3\2\2\2"\r
+            + "\u00d8\u00d7\3\2\2\2\u00d9\3\3\2\2\2\u00da\u00df\7L\2\2\u00db\u00dc\7"\r
+            + "\6\2\2\u00dc\u00de\7L\2\2\u00dd\u00db\3\2\2\2\u00de\u00e1\3\2\2\2\u00df"\r
+            + "\u00dd\3\2\2\2\u00df\u00e0\3\2\2\2\u00e0\5\3\2\2\2\u00e1\u00df\3\2\2\2"\r
+            + "\u00e2\u00e4\7K\2\2\u00e3\u00e5\5\4\3\2\u00e4\u00e3\3\2\2\2\u00e4\u00e5"\r
+            + "\3\2\2\2\u00e5\u00e6\3\2\2\2\u00e6\u00e7\5\b\5\2\u00e7\7\3\2\2\2\u00e8"\r
+            + "\u00ea\7\3\2\2\u00e9\u00eb\5\6\4\2\u00ea\u00e9\3\2\2\2\u00ea\u00eb\3\2"\r
+            + "\2\2\u00eb\u00f2\3\2\2\2\u00ec\u00ee\7\4\2\2\u00ed\u00ef\5\6\4\2\u00ee"\r
+            + "\u00ed\3\2\2\2\u00ee\u00ef\3\2\2\2\u00ef\u00f0\3\2\2\2\u00f0\u00f2\7\5"\r
+            + "\2\2\u00f1\u00e8\3\2\2\2\u00f1\u00ec\3\2\2\2\u00f2\t\3\2\2\2\u00f3\u00f4"\r
+            + "\78\2\2\u00f4\u0104\5\4\3\2\u00f5\u0105\7\3\2\2\u00f6\u0100\7\4\2\2\u00f7"\r
+            + "\u00ff\5\u0096L\2\u00f8\u00ff\5\u00aeX\2\u00f9\u00ff\5\u0084C\2\u00fa"\r
+            + "\u00ff\5f\64\2\u00fb\u00ff\5b\62\2\u00fc\u00ff\5R*\2\u00fd\u00ff\5P)\2"\r
+            + "\u00fe\u00f7\3\2\2\2\u00fe\u00f8\3\2\2\2\u00fe\u00f9\3\2\2\2\u00fe\u00fa"\r
+            + "\3\2\2\2\u00fe\u00fb\3\2\2\2\u00fe\u00fc\3\2\2\2\u00fe\u00fd\3\2\2\2\u00ff"\r
+            + "\u0102\3\2\2\2\u0100\u00fe\3\2\2\2\u0100\u0101\3\2\2\2\u0101\u0103\3\2"\r
+            + "\2\2\u0102\u0100\3\2\2\2\u0103\u0105\7\5\2\2\u0104\u00f5\3\2\2\2\u0104"\r
+            + "\u00f6\3\2\2\2\u0105\13\3\2\2\2\u0106\u0107\78\2\2\u0107\u0114\5\4\3\2"\r
+            + "\u0108\u0115\7\3\2\2\u0109\u0110\7\4\2\2\u010a\u010f\5\u00aeX\2\u010b"\r
+            + "\u010f\5X-\2\u010c\u010f\5> \2\u010d\u010f\5\u0084C\2\u010e\u010a\3\2"\r
+            + "\2\2\u010e\u010b\3\2\2\2\u010e\u010c\3\2\2\2\u010e\u010d\3\2\2\2\u010f"\r
+            + "\u0112\3\2\2\2\u0110\u010e\3\2\2\2\u0110\u0111\3\2\2\2\u0111\u0113\3\2"\r
+            + "\2\2\u0112\u0110\3\2\2\2\u0113\u0115\7\5\2\2\u0114\u0108\3\2\2\2\u0114"\r
+            + "\u0109\3\2\2\2\u0115\r\3\2\2\2\u0116\u0117\78\2\2\u0117\u0128\5\4\3\2"\r
+            + "\u0118\u0129\7\3\2\2\u0119\u0124\7\4\2\2\u011a\u0123\5\u00aeX\2\u011b"\r
+            + "\u0123\5X-\2\u011c\u0123\5> \2\u011d\u0123\5\u0084C\2\u011e\u0123\5f\64"\r
+            + "\2\u011f\u0123\5b\62\2\u0120\u0123\5R*\2\u0121\u0123\5P)\2\u0122\u011a"\r
+            + "\3\2\2\2\u0122\u011b\3\2\2\2\u0122\u011c\3\2\2\2\u0122\u011d\3\2\2\2\u0122"\r
+            + "\u011e\3\2\2\2\u0122\u011f\3\2\2\2\u0122\u0120\3\2\2\2\u0122\u0121\3\2"\r
+            + "\2\2\u0123\u0126\3\2\2\2\u0124\u0122\3\2\2\2\u0124\u0125\3\2\2\2\u0125"\r
+            + "\u0127\3\2\2\2\u0126\u0124\3\2\2\2\u0127\u0129\7\5\2\2\u0128\u0118\3\2"\r
+            + "\2\2\u0128\u0119\3\2\2\2\u0129\17\3\2\2\2\u012a\u012b\78\2\2\u012b\u0132"\r
+            + "\5\4\3\2\u012c\u0133\7\3\2\2\u012d\u012f\7\4\2\2\u012e\u0130\5\6\4\2\u012f"\r
+            + "\u012e\3\2\2\2\u012f\u0130\3\2\2\2\u0130\u0131\3\2\2\2\u0131\u0133\7\5"\r
+            + "\2\2\u0132\u012c\3\2\2\2\u0132\u012d\3\2\2\2\u0133\21\3\2\2\2\u0134\u0135"\r
+            + "\79\2\2\u0135\u0136\5\4\3\2\u0136\u013d\7\4\2\2\u0137\u013e\5\u00b2Z\2"\r
+            + "\u0138\u013e\5\u00b0Y\2\u0139\u013e\5\20\t\2\u013a\u013e\5\16\b\2\u013b"\r
+            + "\u013e\5\n\6\2\u013c\u013e\5\f\7\2\u013d\u0137\3\2\2\2\u013d\u0138\3\2"\r
+            + "\2\2\u013d\u0139\3\2\2\2\u013d\u013a\3\2\2\2\u013d\u013b\3\2\2\2\u013d"\r
+            + "\u013c\3\2\2\2\u013e\u013f\3\2\2\2\u013f\u013d\3\2\2\2\u013f\u0140\3\2"\r
+            + "\2\2\u0140\u0141\3\2\2\2\u0141\u0142\7\5\2\2\u0142\23\3\2\2\2\u0143\u0144"\r
+            + "\7$\2\2\u0144\u0154\5\4\3\2\u0145\u0155\7\3\2\2\u0146\u0150\7\4\2\2\u0147"\r
+            + "\u014f\5\u009aN\2\u0148\u014f\5j\66\2\u0149\u014f\5\u00b2Z\2\u014a\u014f"\r
+            + "\5\u00b0Y\2\u014b\u014f\5\u0098M\2\u014c\u014f\5J&\2\u014d\u014f\5\u00c4"\r
+            + "c\2\u014e\u0147\3\2\2\2\u014e\u0148\3\2\2\2\u014e\u0149\3\2\2\2\u014e"\r
+            + "\u014a\3\2\2\2\u014e\u014b\3\2\2\2\u014e\u014c\3\2\2\2\u014e\u014d\3\2"\r
+            + "\2\2\u014f\u0152\3\2\2\2\u0150\u014e\3\2\2\2\u0150\u0151\3\2\2\2\u0151"\r
+            + "\u0153\3\2\2\2\u0152\u0150\3\2\2\2\u0153\u0155\7\5\2\2\u0154\u0145\3\2"\r
+            + "\2\2\u0154\u0146\3\2\2\2\u0155\25\3\2\2\2\u0156\u0157\7!\2\2\u0157\u015b"\r
+            + "\7\4\2\2\u0158\u015c\5\u0098M\2\u0159\u015c\5J&\2\u015a\u015c\5\u00c4"\r
+            + "c\2\u015b\u0158\3\2\2\2\u015b\u0159\3\2\2\2\u015b\u015a\3\2\2\2\u015c"\r
+            + "\u015d\3\2\2\2\u015d\u015b\3\2\2\2\u015d\u015e\3\2\2\2\u015e\u015f\3\2"\r
+            + "\2\2\u015f\u0160\7\5\2\2\u0160\27\3\2\2\2\u0161\u0162\7\60\2\2\u0162\u0166"\r
+            + "\7\4\2\2\u0163\u0167\5\u0098M\2\u0164\u0167\5J&\2\u0165\u0167\5\u00c4"\r
+            + "c\2\u0166\u0163\3\2\2\2\u0166\u0164\3\2\2\2\u0166\u0165\3\2\2\2\u0167"\r
+            + "\u0168\3\2\2\2\u0168\u0166\3\2\2\2\u0168\u0169\3\2\2\2\u0169\u016a\3\2"\r
+            + "\2\2\u016a\u016b\7\5\2\2\u016b\31\3\2\2\2\u016c\u016d\7\25\2\2\u016d\u017e"\r
+            + "\5\4\3\2\u016e\u017f\7\3\2\2\u016f\u017a\7\4\2\2\u0170\u0179\5\u009aN"\r
+            + "\2\u0171\u0179\5j\66\2\u0172\u0179\5\u00b2Z\2\u0173\u0179\5\u00b0Y\2\u0174"\r
+            + "\u0179\5\u0098M\2\u0175\u0179\5J&\2\u0176\u0179\5\30\r\2\u0177\u0179\5"\r
+            + "\26\f\2\u0178\u0170\3\2\2\2\u0178\u0171\3\2\2\2\u0178\u0172\3\2\2\2\u0178"\r
+            + "\u0173\3\2\2\2\u0178\u0174\3\2\2\2\u0178\u0175\3\2\2\2\u0178\u0176\3\2"\r
+            + "\2\2\u0178\u0177\3\2\2\2\u0179\u017c\3\2\2\2\u017a\u0178\3\2\2\2\u017a"\r
+            + "\u017b\3\2\2\2\u017b\u017d\3\2\2\2\u017c\u017a\3\2\2\2\u017d\u017f\7\5"\r
+            + "\2\2\u017e\u016e\3\2\2\2\u017e\u016f\3\2\2\2\u017f\33\3\2\2\2\u0180\u0181"\r
+            + "\7\f\2\2\u0181\u018c\5\4\3\2\u0182\u018d\7\3\2\2\u0183\u0188\7\4\2\2\u0184"\r
+            + "\u0187\5\u00b2Z\2\u0185\u0187\5\u00b0Y\2\u0186\u0184\3\2\2\2\u0186\u0185"\r
+            + "\3\2\2\2\u0187\u018a\3\2\2\2\u0188\u0186\3\2\2\2\u0188\u0189\3\2\2\2\u0189"\r
+            + "\u018b\3\2\2\2\u018a\u0188\3\2\2\2\u018b\u018d\7\5\2\2\u018c\u0182\3\2"\r
+            + "\2\2\u018c\u0183\3\2\2\2\u018d\35\3\2\2\2\u018e\u018f\7H\2\2\u018f\u0190"\r
+            + "\5\4\3\2\u0190\u0199\7\4\2\2\u0191\u019a\5\6\4\2\u0192\u019a\5\34\17\2"\r
+            + "\u0193\u019a\5\u009aN\2\u0194\u019a\5j\66\2\u0195\u019a\5\u00b2Z\2\u0196"\r
+            + "\u019a\5\u00b0Y\2\u0197\u019a\5\u00c4c\2\u0198\u019a\58\35\2\u0199\u0191"\r
+            + "\3\2\2\2\u0199\u0192\3\2\2\2\u0199\u0193\3\2\2\2\u0199\u0194\3\2\2\2\u0199"\r
+            + "\u0195\3\2\2\2\u0199\u0196\3\2\2\2\u0199\u0197\3\2\2\2\u0199\u0198\3\2"\r
+            + "\2\2\u019a\u019b\3\2\2\2\u019b\u0199\3\2\2\2\u019b\u019c\3\2\2\2\u019c"\r
+            + "\u019d\3\2\2\2\u019d\u019e\7\5\2\2\u019e\37\3\2\2\2\u019f\u01a0\7H\2\2"\r
+            + "\u01a0\u01a1\5\4\3\2\u01a1\u01aa\7\4\2\2\u01a2\u01ab\5\6\4\2\u01a3\u01ab"\r
+            + "\5\34\17\2\u01a4\u01ab\5\u009aN\2\u01a5\u01ab\5j\66\2\u01a6\u01ab\5\u00b2"\r
+            + "Z\2\u01a7\u01ab\5\u00b0Y\2\u01a8\u01ab\5\u00c4c\2\u01a9\u01ab\58\35\2"\r
+            + "\u01aa\u01a2\3\2\2\2\u01aa\u01a3\3\2\2\2\u01aa\u01a4\3\2\2\2\u01aa\u01a5"\r
+            + "\3\2\2\2\u01aa\u01a6\3\2\2\2\u01aa\u01a7\3\2\2\2\u01aa\u01a8\3\2\2\2\u01aa"\r
+            + "\u01a9\3\2\2\2\u01ab\u01ac\3\2\2\2\u01ac\u01aa\3\2\2\2\u01ac\u01ad\3\2"\r
+            + "\2\2\u01ad\u01ae\3\2\2\2\u01ae\u01af\7\5\2\2\u01af!\3\2\2\2\u01b0\u01b6"\r
+            + "\5X-\2\u01b1\u01b6\5f\64\2\u01b2\u01b6\5b\62\2\u01b3\u01b6\5\u00b2Z\2"\r
+            + "\u01b4\u01b6\5\u00b0Y\2\u01b5\u01b0\3\2\2\2\u01b5\u01b1\3\2\2\2\u01b5"\r
+            + "\u01b2\3\2\2\2\u01b5\u01b3\3\2\2\2\u01b5\u01b4\3\2\2\2\u01b6\u01b9\3\2"\r
+            + "\2\2\u01b7\u01b5\3\2\2\2\u01b7\u01b8\3\2\2\2\u01b8#\3\2\2\2\u01b9\u01b7"\r
+            + "\3\2\2\2\u01ba\u01bd\5\u00b2Z\2\u01bb\u01bd\5\u00b0Y\2\u01bc\u01ba\3\2"\r
+            + "\2\2\u01bc\u01bb\3\2\2\2\u01bd\u01c0\3\2\2\2\u01be\u01bc\3\2\2\2\u01be"\r
+            + "\u01bf\3\2\2\2\u01bf%\3\2\2\2\u01c0\u01be\3\2\2\2\u01c1\u01c7\5\u0084"\r
+            + "C\2\u01c2\u01c7\5f\64\2\u01c3\u01c7\5b\62\2\u01c4\u01c7\5\u00b2Z\2\u01c5"\r
+            + "\u01c7\5\u00b0Y\2\u01c6\u01c1\3\2\2\2\u01c6\u01c2\3\2\2\2\u01c6\u01c3"\r
+            + "\3\2\2\2\u01c6\u01c4\3\2\2\2\u01c6\u01c5\3\2\2\2\u01c7\u01ca\3\2\2\2\u01c8"\r
+            + "\u01c6\3\2\2\2\u01c8\u01c9\3\2\2\2\u01c9\'\3\2\2\2\u01ca\u01c8\3\2\2\2"\r
+            + "\u01cb\u01d2\5X-\2\u01cc\u01d2\5f\64\2\u01cd\u01d2\5R*\2\u01ce\u01d2\5"\r
+            + "P)\2\u01cf\u01d2\5\u00b2Z\2\u01d0\u01d2\5\u00b0Y\2\u01d1\u01cb\3\2\2\2"\r
+            + "\u01d1\u01cc\3\2\2\2\u01d1\u01cd\3\2\2\2\u01d1\u01ce\3\2\2\2\u01d1\u01cf"\r
+            + "\3\2\2\2\u01d1\u01d0\3\2\2\2\u01d2\u01d5\3\2\2\2\u01d3\u01d1\3\2\2\2\u01d3"\r
+            + "\u01d4\3\2\2\2\u01d4)\3\2\2\2\u01d5\u01d3\3\2\2\2\u01d6\u01dd\5X-\2\u01d7"\r
+            + "\u01dd\5f\64\2\u01d8\u01dd\5R*\2\u01d9\u01dd\5P)\2\u01da\u01dd\5\u00b2"\r
+            + "Z\2\u01db\u01dd\5\u00b0Y\2\u01dc\u01d6\3\2\2\2\u01dc\u01d7\3\2\2\2\u01dc"\r
+            + "\u01d8\3\2\2\2\u01dc\u01d9\3\2\2\2\u01dc\u01da\3\2\2\2\u01dc\u01db\3\2"\r
+            + "\2\2\u01dd\u01e0\3\2\2\2\u01de\u01dc\3\2\2\2\u01de\u01df\3\2\2\2\u01df"\r
+            + "+\3\2\2\2\u01e0\u01de\3\2\2\2\u01e1\u01e8\5X-\2\u01e2\u01e8\5\u0084C\2"\r
+            + "\u01e3\u01e8\5f\64\2\u01e4\u01e8\5b\62\2\u01e5\u01e8\5\u00b2Z\2\u01e6"\r
+            + "\u01e8\5\u00b0Y\2\u01e7\u01e1\3\2\2\2\u01e7\u01e2\3\2\2\2\u01e7\u01e3"\r
+            + "\3\2\2\2\u01e7\u01e4\3\2\2\2\u01e7\u01e5\3\2\2\2\u01e7\u01e6\3\2\2\2\u01e8"\r
+            + "\u01eb\3\2\2\2\u01e9\u01e7\3\2\2\2\u01e9\u01ea\3\2\2\2\u01ea-\3\2\2\2"\r
+            + "\u01eb\u01e9\3\2\2\2\u01ec\u01f2\5X-\2\u01ed\u01f2\5^\60\2\u01ee\u01f2"\r
+            + "\5f\64\2\u01ef\u01f2\5\u00b2Z\2\u01f0\u01f2\5\u00b0Y\2\u01f1\u01ec\3\2"\r
+            + "\2\2\u01f1\u01ed\3\2\2\2\u01f1\u01ee\3\2\2\2\u01f1\u01ef\3\2\2\2\u01f1"\r
+            + "\u01f0\3\2\2\2\u01f2\u01f5\3\2\2\2\u01f3\u01f1\3\2\2\2\u01f3\u01f4\3\2"\r
+            + "\2\2\u01f4/\3\2\2\2\u01f5\u01f3\3\2\2\2\u01f6\u01fe\5.\30\2\u01f7\u01fe"\r
+            + "\5,\27\2\u01f8\u01fe\5*\26\2\u01f9\u01fe\5(\25\2\u01fa\u01fe\5&\24\2\u01fb"\r
+            + "\u01fe\5$\23\2\u01fc\u01fe\5\"\22\2\u01fd\u01f6\3\2\2\2\u01fd\u01f7\3"\r
+            + "\2\2\2\u01fd\u01f8\3\2\2\2\u01fd\u01f9\3\2\2\2\u01fd\u01fa\3\2\2\2\u01fd"\r
+            + "\u01fb\3\2\2\2\u01fd\u01fc\3\2\2\2\u01fe\61\3\2\2\2\u01ff\u0200\7\31\2"\r
+            + "\2\u0200\u020a\5\4\3\2\u0201\u020b\7\3\2\2\u0202\u0204\7\4\2\2\u0203\u0205"\r
+            + "\5\60\31\2\u0204\u0203\3\2\2\2\u0205\u0206\3\2\2\2\u0206\u0204\3\2\2\2"\r
+            + "\u0206\u0207\3\2\2\2\u0207\u0208\3\2\2\2\u0208\u0209\7\5\2\2\u0209\u020b"\r
+            + "\3\2\2\2\u020a\u0201\3\2\2\2\u020a\u0202\3\2\2\2\u020b\63\3\2\2\2\u020c"\r
+            + "\u020d\7\16\2\2\u020d\u021e\5\4\3\2\u020e\u021f\7\3\2\2\u020f\u021a\7"\r
+            + "\4\2\2\u0210\u0219\5\6\4\2\u0211\u0219\5\34\17\2\u0212\u0219\5\u009aN"\r
+            + "\2\u0213\u0219\5j\66\2\u0214\u0219\5\u00b2Z\2\u0215\u0219\5\u00b0Y\2\u0216"\r
+            + "\u0219\5\62\32\2\u0217\u0219\5 \21\2\u0218\u0210\3\2\2\2\u0218\u0211\3"\r
+            + "\2\2\2\u0218\u0212\3\2\2\2\u0218\u0213\3\2\2\2\u0218\u0214\3\2\2\2\u0218"\r
+            + "\u0215\3\2\2\2\u0218\u0216\3\2\2\2\u0218\u0217\3\2\2\2\u0219\u021c\3\2"\r
+            + "\2\2\u021a\u0218\3\2\2\2\u021a\u021b\3\2\2\2\u021b\u021d\3\2\2\2\u021c"\r
+            + "\u021a\3\2\2\2\u021d\u021f\7\5\2\2\u021e\u020e\3\2\2\2\u021e\u020f\3\2"\r
+            + "\2\2\u021f\65\3\2\2\2\u0220\u0221\7J\2\2\u0221\u0233\5\4\3\2\u0222\u0234"\r
+            + "\7\3\2\2\u0223\u022f\7\4\2\2\u0224\u022e\5\6\4\2\u0225\u022e\5\34\17\2"\r
+            + "\u0226\u022e\5\u009aN\2\u0227\u022e\5X-\2\u0228\u022e\5f\64\2\u0229\u022e"\r
+            + "\5b\62\2\u022a\u022e\5j\66\2\u022b\u022e\5\u00b2Z\2\u022c\u022e\5\u00b0"\r
+            + "Y\2\u022d\u0224\3\2\2\2\u022d\u0225\3\2\2\2\u022d\u0226\3\2\2\2\u022d"\r
+            + "\u0227\3\2\2\2\u022d\u0228\3\2\2\2\u022d\u0229\3\2\2\2\u022d\u022a\3\2"\r
+            + "\2\2\u022d\u022b\3\2\2\2\u022d\u022c\3\2\2\2\u022e\u0231\3\2\2\2\u022f"\r
+            + "\u022d\3\2\2\2\u022f\u0230\3\2\2\2\u0230\u0232\3\2\2\2\u0231\u022f\3\2"\r
+            + "\2\2\u0232\u0234\7\5\2\2\u0233\u0222\3\2\2\2\u0233\u0223\3\2\2\2\u0234"\r
+            + "\67\3\2\2\2\u0235\u0236\7D\2\2\u0236\u0246\5\4\3\2\u0237\u0247\7\3\2\2"\r
+            + "\u0238\u0242\7\4\2\2\u0239\u0241\5\6\4\2\u023a\u0241\5\34\17\2\u023b\u0241"\r
+            + "\5\u009aN\2\u023c\u0241\5j\66\2\u023d\u0241\5\u00b2Z\2\u023e\u0241\5\u00b0"\r
+            + "Y\2\u023f\u0241\5\u00c4c\2\u0240\u0239\3\2\2\2\u0240\u023a\3\2\2\2\u0240"\r
+            + "\u023b\3\2\2\2\u0240\u023c\3\2\2\2\u0240\u023d\3\2\2\2\u0240\u023e\3\2"\r
+            + "\2\2\u0240\u023f\3\2\2\2\u0241\u0244\3\2\2\2\u0242\u0240\3\2\2\2\u0242"\r
+            + "\u0243\3\2\2\2\u0243\u0245\3\2\2\2\u0244\u0242\3\2\2\2\u0245\u0247\7\5"\r
+            + "\2\2\u0246\u0237\3\2\2\2\u0246\u0238\3\2\2\2\u02479\3\2\2\2\u0248\u024e"\r
+            + "\5H%\2\u0249\u024e\5F$\2\u024a\u024e\5D#\2\u024b\u024e\5B\"\2\u024c\u024e"\r
+            + "\5\66\34\2\u024d\u0248\3\2\2\2\u024d\u0249\3\2\2\2\u024d\u024a\3\2\2\2"\r
+            + "\u024d\u024b\3\2\2\2\u024d\u024c\3\2\2\2\u024e;\3\2\2\2\u024f\u0250\7"\r
+            + "C\2\2\u0250\u0264\5\4\3\2\u0251\u0265\7\3\2\2\u0252\u0260\7\4\2\2\u0253"\r
+            + "\u025f\5\6\4\2\u0254\u025f\5\34\17\2\u0255\u025f\5\u009aN\2\u0256\u025f"\r
+            + "\5\u0084C\2\u0257\u025f\5f\64\2\u0258\u025f\5b\62\2\u0259\u025f\5j\66"\r
+            + "\2\u025a\u025f\5\u00b2Z\2\u025b\u025f\5\u00b0Y\2\u025c\u025f\5:\36\2\u025d"\r
+            + "\u025f\58\35\2\u025e\u0253\3\2\2\2\u025e\u0254\3\2\2\2\u025e\u0255\3\2"\r
+            + "\2\2\u025e\u0256\3\2\2\2\u025e\u0257\3\2\2\2\u025e\u0258\3\2\2\2\u025e"\r
+            + "\u0259\3\2\2\2\u025e\u025a\3\2\2\2\u025e\u025b\3\2\2\2\u025e\u025c\3\2"\r
+            + "\2\2\u025e\u025d\3\2\2\2\u025f\u0262\3\2\2\2\u0260\u025e\3\2\2\2\u0260"\r
+            + "\u0261\3\2\2\2\u0261\u0263\3\2\2\2\u0262\u0260\3\2\2\2\u0263\u0265\7\5"\r
+            + "\2\2\u0264\u0251\3\2\2\2\u0264\u0252\3\2\2\2\u0265=\3\2\2\2\u0266\u0267"\r
+            + "\7\20\2\2\u0267\u0268\5\4\3\2\u0268\u0269\5\b\5\2\u0269?\3\2\2\2\u026a"\r
+            + "\u026b\7/\2\2\u026b\u026c\5\4\3\2\u026c\u026d\5\b\5\2\u026dA\3\2\2\2\u026e"\r
+            + "\u026f\7+\2\2\u026f\u0270\5\4\3\2\u0270\u0281\7\4\2\2\u0271\u0282\5\6"\r
+            + "\4\2\u0272\u0282\5\34\17\2\u0273\u0282\5\u009aN\2\u0274\u0282\5X-\2\u0275"\r
+            + "\u0282\5@!\2\u0276\u0282\5> \2\u0277\u0282\5f\64\2\u0278\u0282\5R*\2\u0279"\r
+            + "\u0282\5P)\2\u027a\u0282\5\\/\2\u027b\u0282\5j\66\2\u027c\u0282\5\u00b2"\r
+            + "Z\2\u027d\u0282\5\u00b0Y\2\u027e\u0282\5\u0098M\2\u027f\u0282\5J&\2\u0280"\r
+            + "\u0282\5\u00c4c\2\u0281\u0271\3\2\2\2\u0281\u0272\3\2\2\2\u0281\u0273"\r
+            + "\3\2\2\2\u0281\u0274\3\2\2\2\u0281\u0275\3\2\2\2\u0281\u0276\3\2\2\2\u0281"\r
+            + "\u0277\3\2\2\2\u0281\u0278\3\2\2\2\u0281\u0279\3\2\2\2\u0281\u027a\3\2"\r
+            + "\2\2\u0281\u027b\3\2\2\2\u0281\u027c\3\2\2\2\u0281\u027d\3\2\2\2\u0281"\r
+            + "\u027e\3\2\2\2\u0281\u027f\3\2\2\2\u0281\u0280\3\2\2\2\u0282\u0283\3\2"\r
+            + "\2\2\u0283\u0281\3\2\2\2\u0283\u0284\3\2\2\2\u0284\u0285\3\2\2\2\u0285"\r
+            + "\u0286\7\5\2\2\u0286C\3\2\2\2\u0287\u0288\7-\2\2\u0288\u0289\5\4\3\2\u0289"\r
+            + "\u0299\7\4\2\2\u028a\u0298\5\6\4\2\u028b\u0298\5\34\17\2\u028c\u0298\5"\r
+            + "\u009aN\2\u028d\u0298\5\u0096L\2\u028e\u0298\5\u00aeX\2\u028f\u0298\5"\r
+            + "X-\2\u0290\u0298\5f\64\2\u0291\u0298\5R*\2\u0292\u0298\5P)\2\u0293\u0298"\r
+            + "\5\\/\2\u0294\u0298\5j\66\2\u0295\u0298\5\u00b2Z\2\u0296\u0298\5\u00b0"\r
+            + "Y\2\u0297\u028a\3\2\2\2\u0297\u028b\3\2\2\2\u0297\u028c\3\2\2\2\u0297"\r
+            + "\u028d\3\2\2\2\u0297\u028e\3\2\2\2\u0297\u028f\3\2\2\2\u0297\u0290\3\2"\r
+            + "\2\2\u0297\u0291\3\2\2\2\u0297\u0292\3\2\2\2\u0297\u0293\3\2\2\2\u0297"\r
+            + "\u0294\3\2\2\2\u0297\u0295\3\2\2\2\u0297\u0296\3\2\2\2\u0298\u029b\3\2"\r
+            + "\2\2\u0299\u0297\3\2\2\2\u0299\u029a\3\2\2\2\u029a\u029c\3\2\2\2\u029b"\r
+            + "\u0299\3\2\2\2\u029c\u029d\7\5\2\2\u029dE\3\2\2\2\u029e\u029f\7.\2\2\u029f"\r
+            + "\u02a0\5\4\3\2\u02a0\u02af\7\4\2\2\u02a1\u02ae\5\6\4\2\u02a2\u02ae\5\34"\r
+            + "\17\2\u02a3\u02ae\5\u009aN\2\u02a4\u02ae\5\u0096L\2\u02a5\u02ae\5\u00ae"\r
+            + "X\2\u02a6\u02ae\5X-\2\u02a7\u02ae\5\u0084C\2\u02a8\u02ae\5f\64\2\u02a9"\r
+            + "\u02ae\5b\62\2\u02aa\u02ae\5j\66\2\u02ab\u02ae\5\u00b2Z\2\u02ac\u02ae"\r
+            + "\5\u00b0Y\2\u02ad\u02a1\3\2\2\2\u02ad\u02a2\3\2\2\2\u02ad\u02a3\3\2\2"\r
+            + "\2\u02ad\u02a4\3\2\2\2\u02ad\u02a5\3\2\2\2\u02ad\u02a6\3\2\2\2\u02ad\u02a7"\r
+            + "\3\2\2\2\u02ad\u02a8\3\2\2\2\u02ad\u02a9\3\2\2\2\u02ad\u02aa\3\2\2\2\u02ad"\r
+            + "\u02ab\3\2\2\2\u02ad\u02ac\3\2\2\2\u02ae\u02b1\3\2\2\2\u02af\u02ad\3\2"\r
+            + "\2\2\u02af\u02b0\3\2\2\2\u02b0\u02b2\3\2\2\2\u02b1\u02af\3\2\2\2\u02b2"\r
+            + "\u02b3\7\5\2\2\u02b3G\3\2\2\2\u02b4\u02b5\7@\2\2\u02b5\u02ca\5\4\3\2\u02b6"\r
+            + "\u02cb\7\3\2\2\u02b7\u02c6\7\4\2\2\u02b8\u02c5\5\6\4\2\u02b9\u02c5\5\34"\r
+            + "\17\2\u02ba\u02c5\5\u009aN\2\u02bb\u02c5\5X-\2\u02bc\u02c5\5^\60\2\u02bd"\r
+            + "\u02c5\5f\64\2\u02be\u02c5\5j\66\2\u02bf\u02c5\5\u00b2Z\2\u02c0\u02c5"\r
+            + "\5\u00b0Y\2\u02c1\u02c5\5\u0098M\2\u02c2\u02c5\5J&\2\u02c3\u02c5\5\u00c4"\r
+            + "c\2\u02c4\u02b8\3\2\2\2\u02c4\u02b9\3\2\2\2\u02c4\u02ba\3\2\2\2\u02c4"\r
+            + "\u02bb\3\2\2\2\u02c4\u02bc\3\2\2\2\u02c4\u02bd\3\2\2\2\u02c4\u02be\3\2"\r
+            + "\2\2\u02c4\u02bf\3\2\2\2\u02c4\u02c0\3\2\2\2\u02c4\u02c1\3\2\2\2\u02c4"\r
+            + "\u02c2\3\2\2\2\u02c4\u02c3\3\2\2\2\u02c5\u02c8\3\2\2\2\u02c6\u02c4\3\2"\r
+            + "\2\2\u02c6\u02c7\3\2\2\2\u02c7\u02c9\3\2\2\2\u02c8\u02c6\3\2\2\2\u02c9"\r
+            + "\u02cb\7\5\2\2\u02ca\u02b6\3\2\2\2\u02ca\u02b7\3\2\2\2\u02cbI\3\2\2\2"\r
+            + "\u02cc\u02cd\7\65\2\2\u02cd\u02dd\5\4\3\2\u02ce\u02de\7\3\2\2\u02cf\u02d9"\r
+            + "\7\4\2\2\u02d0\u02d8\5\6\4\2\u02d1\u02d8\5j\66\2\u02d2\u02d8\5\u00b2Z"\r
+            + "\2\u02d3\u02d8\5\u00b0Y\2\u02d4\u02d8\5\u0098M\2\u02d5\u02d8\5J&\2\u02d6"\r
+            + "\u02d8\5\u00c4c\2\u02d7\u02d0\3\2\2\2\u02d7\u02d1\3\2\2\2\u02d7\u02d2"\r
+            + "\3\2\2\2\u02d7\u02d3\3\2\2\2\u02d7\u02d4\3\2\2\2\u02d7\u02d5\3\2\2\2\u02d7"\r
+            + "\u02d6\3\2\2\2\u02d8\u02db\3\2\2\2\u02d9\u02d7\3\2\2\2\u02d9\u02da\3\2"\r
+            + "\2\2\u02da\u02dc\3\2\2\2\u02db\u02d9\3\2\2\2\u02dc\u02de\7\5\2\2\u02dd"\r
+            + "\u02ce\3\2\2\2\u02dd\u02cf\3\2\2\2\u02deK\3\2\2\2\u02df\u02e0\7\r\2\2"\r
+            + "\u02e0\u02e1\5\4\3\2\u02e1\u02e2\5\b\5\2\u02e2M\3\2\2\2\u02e3\u02e4\5"\r
+            + "\4\3\2\u02e4O\3\2\2\2\u02e5\u02e6\7)\2\2\u02e6\u02e7\5N(\2\u02e7\u02e8"\r
+            + "\5\b\5\2\u02e8Q\3\2\2\2\u02e9\u02ea\7(\2\2\u02ea\u02eb\5\4\3\2\u02eb\u02ec"\r
+            + "\5\b\5\2\u02ecS\3\2\2\2\u02ed\u02ee\7<\2\2\u02ee\u02ef\5\4\3\2\u02ef\u02f0"\r
+            + "\5\b\5\2\u02f0U\3\2\2\2\u02f1\u02f2\7;\2\2\u02f2\u02f3\5\4\3\2\u02f3\u02f4"\r
+            + "\5\b\5\2\u02f4W\3\2\2\2\u02f5\u02f6\7&\2\2\u02f6\u0304\5\4\3\2\u02f7\u0305"\r
+            + "\7\3\2\2\u02f8\u0300\7\4\2\2\u02f9\u02ff\5\6\4\2\u02fa\u02ff\5V,\2\u02fb"\r
+            + "\u02ff\5T+\2\u02fc\u02ff\5\u00b2Z\2\u02fd\u02ff\5\u00b0Y\2\u02fe\u02f9"\r
+            + "\3\2\2\2\u02fe\u02fa\3\2\2\2\u02fe\u02fb\3\2\2\2\u02fe\u02fc\3\2\2\2\u02fe"\r
+            + "\u02fd\3\2\2\2\u02ff\u0302\3\2\2\2\u0300\u02fe\3\2\2\2\u0300\u0301\3\2"\r
+            + "\2\2\u0301\u0303\3\2\2\2\u0302\u0300\3\2\2\2\u0303\u0305\7\5\2\2\u0304"\r
+            + "\u02f7\3\2\2\2\u0304\u02f8\3\2\2\2\u0305Y\3\2\2\2\u0306\u0307\5\4\3\2"\r
+            + "\u0307[\3\2\2\2\u0308\u0309\7#\2\2\u0309\u030a\5Z.\2\u030a\u030b\5\b\5"\r
+            + "\2\u030b]\3\2\2\2\u030c\u030d\7\34\2\2\u030d\u030e\5\4\3\2\u030e\u030f"\r
+            + "\5\b\5\2\u030f_\3\2\2\2\u0310\u0311\5\4\3\2\u0311a\3\2\2\2\u0312\u0313"\r
+            + "\7*\2\2\u0313\u0314\5`\61\2\u0314\u0315\5\b\5\2\u0315c\3\2\2\2\u0316\u0317"\r
+            + "\5\4\3\2\u0317e\3\2\2\2\u0318\u0319\7B\2\2\u0319\u031a\5d\63\2\u031a\u031b"\r
+            + "\5\b\5\2\u031bg\3\2\2\2\u031c\u031d\5\4\3\2\u031di\3\2\2\2\u031e\u031f"\r
+            + "\7\24\2\2\u031f\u0320\5h\65\2\u0320\u0321\5\b\5\2\u0321k\3\2\2\2\u0322"\r
+            + "\u0323\7\36\2\2\u0323\u0324\5\4\3\2\u0324\u0325\5\b\5\2\u0325m\3\2\2\2"\r
+            + "\u0326\u0327\7E\2\2\u0327\u0335\5\4\3\2\u0328\u0336\7\3\2\2\u0329\u0331"\r
+            + "\7\4\2\2\u032a\u0330\5\6\4\2\u032b\u0330\5l\67\2\u032c\u0330\5j\66\2\u032d"\r
+            + "\u0330\5\u00b2Z\2\u032e\u0330\5\u00b0Y\2\u032f\u032a\3\2\2\2\u032f\u032b"\r
+            + "\3\2\2\2\u032f\u032c\3\2\2\2\u032f\u032d\3\2\2\2\u032f\u032e\3\2\2\2\u0330"\r
+            + "\u0333\3\2\2\2\u0331\u032f\3\2\2\2\u0331\u0332\3\2\2\2\u0332\u0334\3\2"\r
+            + "\2\2\u0333\u0331\3\2\2\2\u0334\u0336\7\5\2\2\u0335\u0328\3\2\2\2\u0335"\r
+            + "\u0329\3\2\2\2\u0336o\3\2\2\2\u0337\u0339\5n8\2\u0338\u0337\3\2\2\2\u0339"\r
+            + "\u033a\3\2\2\2\u033a\u0338\3\2\2\2\u033a\u033b\3\2\2\2\u033bq\3\2\2\2"\r
+            + "\u033c\u033e\5\u0096L\2\u033d\u033c\3\2\2\2\u033e\u033f\3\2\2\2\u033f"\r
+            + "\u033d\3\2\2\2\u033f\u0340\3\2\2\2\u0340s\3\2\2\2\u0341\u0342\5\u009e"\r
+            + "P\2\u0342u\3\2\2\2\u0343\u0345\5z>\2\u0344\u0343\3\2\2\2\u0344\u0345\3"\r
+            + "\2\2\2\u0345w\3\2\2\2\u0346\u0347\5\4\3\2\u0347y\3\2\2\2\u0348\u0349\7"\r
+            + "\30\2\2\u0349\u034a\5x=\2\u034a\u034b\5\b\5\2\u034b{\3\2\2\2\u034c\u034d"\r
+            + "\7 \2\2\u034d\u034e\5\4\3\2\u034e\u034f\5\b\5\2\u034f}\3\2\2\2\u0350\u0351"\r
+            + "\5|?\2\u0351\177\3\2\2\2\u0352\u0353\7=\2\2\u0353\u0361\5\4\3\2\u0354"\r
+            + "\u0362\7\3\2\2\u0355\u035d\7\4\2\2\u0356\u035c\5\6\4\2\u0357\u035c\5L"\r
+            + "\'\2\u0358\u035c\5j\66\2\u0359\u035c\5\u00b2Z\2\u035a\u035c\5\u00b0Y\2"\r
+            + "\u035b\u0356\3\2\2\2\u035b\u0357\3\2\2\2\u035b\u0358\3\2\2\2\u035b\u0359"\r
+            + "\3\2\2\2\u035b\u035a\3\2\2\2\u035c\u035f\3\2\2\2\u035d\u035b\3\2\2\2\u035d"\r
+            + "\u035e\3\2\2\2\u035e\u0360\3\2\2\2\u035f\u035d\3\2\2\2\u0360\u0362\7\5"\r
+            + "\2\2\u0361\u0354\3\2\2\2\u0361\u0355\3\2\2\2\u0362\u0081\3\2\2\2\u0363"\r
+            + "\u0365\5\u0080A\2\u0364\u0363\3\2\2\2\u0365\u0366\3\2\2\2\u0366\u0364"\r
+            + "\3\2\2\2\u0366\u0367\3\2\2\2\u0367\u0083\3\2\2\2\u0368\u0369\7?\2\2\u0369"\r
+            + "\u036a\5\4\3\2\u036a\u036b\5\b\5\2\u036b\u0085\3\2\2\2\u036c\u036d\7\37"\r
+            + "\2\2\u036d\u037b\5\4\3\2\u036e\u037c\7\3\2\2\u036f\u0377\7\4\2\2\u0370"\r
+            + "\u0376\5\6\4\2\u0371\u0376\5V,\2\u0372\u0376\5T+\2\u0373\u0376\5\u00b2"\r
+            + "Z\2\u0374\u0376\5\u00b0Y\2\u0375\u0370\3\2\2\2\u0375\u0371\3\2\2\2\u0375"\r
+            + "\u0372\3\2\2\2\u0375\u0373\3\2\2\2\u0375\u0374\3\2\2\2\u0376\u0379\3\2"\r
+            + "\2\2\u0377\u0375\3\2\2\2\u0377\u0378\3\2\2\2\u0378\u037a\3\2\2\2\u0379"\r
+            + "\u0377\3\2\2\2\u037a\u037c\7\5\2\2\u037b\u036e\3\2\2\2\u037b\u036f\3\2"\r
+            + "\2\2\u037c\u0087\3\2\2\2\u037d\u037e\7,\2\2\u037e\u038c\5\4\3\2\u037f"\r
+            + "\u038d\7\3\2\2\u0380\u0388\7\4\2\2\u0381\u0387\5\6\4\2\u0382\u0387\5V"\r
+            + ",\2\u0383\u0387\5T+\2\u0384\u0387\5\u00b2Z\2\u0385\u0387\5\u00b0Y\2\u0386"\r
+            + "\u0381\3\2\2\2\u0386\u0382\3\2\2\2\u0386\u0383\3\2\2\2\u0386\u0384\3\2"\r
+            + "\2\2\u0386\u0385\3\2\2\2\u0387\u038a\3\2\2\2\u0388\u0386\3\2\2\2\u0388"\r
+            + "\u0389\3\2\2\2\u0389\u038b\3\2\2\2\u038a\u0388\3\2\2\2\u038b\u038d\7\5"\r
+            + "\2\2\u038c\u037f\3\2\2\2\u038c\u0380\3\2\2\2\u038d\u0089\3\2\2\2\u038e"\r
+            + "\u0391\5\u0088E\2\u038f\u0391\5\u0086D\2\u0390\u038e\3\2\2\2\u0390\u038f"\r
+            + "\3\2\2\2\u0391\u0394\3\2\2\2\u0392\u0390\3\2\2\2\u0392\u0393\3\2\2\2\u0393"\r
+            + "\u008b\3\2\2\2\u0394\u0392\3\2\2\2\u0395\u0396\7\66\2\2\u0396\u0397\5"\r
+            + "\4\3\2\u0397\u0398\5\b\5\2\u0398\u008d\3\2\2\2\u0399\u039b\5\u0092J\2"\r
+            + "\u039a\u0399\3\2\2\2\u039a\u039b\3\2\2\2\u039b\u039c\3\2\2\2\u039c\u03a2"\r
+            + "\5\u008cG\2\u039d\u039f\5\u008cG\2\u039e\u03a0\5\u0092J\2\u039f\u039e"\r
+            + "\3\2\2\2\u039f\u03a0\3\2\2\2\u03a0\u03a2\3\2\2\2\u03a1\u039a\3\2\2\2\u03a1"\r
+            + "\u039d\3\2\2\2\u03a2\u008f\3\2\2\2\u03a3\u03a4\7\33\2\2\u03a4\u03b2\5"\r
+            + "\4\3\2\u03a5\u03b3\7\3\2\2\u03a6\u03ae\7\4\2\2\u03a7\u03ad\5\6\4\2\u03a8"\r
+            + "\u03ad\5V,\2\u03a9\u03ad\5T+\2\u03aa\u03ad\5\u00b2Z\2\u03ab\u03ad\5\u00b0"\r
+            + "Y\2\u03ac\u03a7\3\2\2\2\u03ac\u03a8\3\2\2\2\u03ac\u03a9\3\2\2\2\u03ac"\r
+            + "\u03aa\3\2\2\2\u03ac\u03ab\3\2\2\2\u03ad\u03b0\3\2\2\2\u03ae\u03ac\3\2"\r
+            + "\2\2\u03ae\u03af\3\2\2\2\u03af\u03b1\3\2\2\2\u03b0\u03ae\3\2\2\2\u03b1"\r
+            + "\u03b3\7\5\2\2\u03b2\u03a5\3\2\2\2\u03b2\u03a6\3\2\2\2\u03b3\u0091\3\2"\r
+            + "\2\2\u03b4\u03b5\5\u0090I\2\u03b5\u0093\3\2\2\2\u03b6\u03c0\5\u0092J\2"\r
+            + "\u03b7\u03c0\5\u008eH\2\u03b8\u03c0\5\u008aF\2\u03b9\u03c0\5\u0082B\2"\r
+            + "\u03ba\u03c0\5~@\2\u03bb\u03c0\5t;\2\u03bc\u03c0\5v<\2\u03bd\u03c0\5p"\r
+            + "9\2\u03be\u03c0\5r:\2\u03bf\u03b6\3\2\2\2\u03bf\u03b7\3\2\2\2\u03bf\u03b8"\r
+            + "\3\2\2\2\u03bf\u03b9\3\2\2\2\u03bf\u03ba\3\2\2\2\u03bf\u03bb\3\2\2\2\u03bf"\r
+            + "\u03bc\3\2\2\2\u03bf\u03bd\3\2\2\2\u03bf\u03be\3\2\2\2\u03c0\u0095\3\2"\r
+            + "\2\2\u03c1\u03c2\7\22\2\2\u03c2\u03c8\5\4\3\2\u03c3\u03c9\7\3\2\2\u03c4"\r
+            + "\u03c5\7\4\2\2\u03c5\u03c6\5\u0094K\2\u03c6\u03c7\7\5\2\2\u03c7\u03c9"\r
+            + "\3\2\2\2\u03c8\u03c3\3\2\2\2\u03c8\u03c4\3\2\2\2\u03c9\u0097\3\2\2\2\u03ca"\r
+            + "\u03cb\7\21\2\2\u03cb\u03cc\5\4\3\2\u03cc\u03d3\7\4\2\2\u03cd\u03d4\5"\r
+            + "\u0096L\2\u03ce\u03d4\5\u00aeX\2\u03cf\u03d4\5\u0084C\2\u03d0\u03d4\5"\r
+            + "j\66\2\u03d1\u03d4\5\u00b2Z\2\u03d2\u03d4\5\u00b0Y\2\u03d3\u03cd\3\2\2"\r
+            + "\2\u03d3\u03ce\3\2\2\2\u03d3\u03cf\3\2\2\2\u03d3\u03d0\3\2\2\2\u03d3\u03d1"\r
+            + "\3\2\2\2\u03d3\u03d2\3\2\2\2\u03d4\u03d5\3\2\2\2\u03d5\u03d3\3\2\2\2\u03d5"\r
+            + "\u03d6\3\2\2\2\u03d6\u03d7\3\2\2\2\u03d7\u03d8\7\5\2\2\u03d8\u0099\3\2"\r
+            + "\2\2\u03d9\u03da\7\63\2\2\u03da\u03db\5\4\3\2\u03db\u03dc\5\b\5\2\u03dc"\r
+            + "\u009b\3\2\2\2\u03dd\u03de\7\67\2\2\u03de\u03eb\5\4\3\2\u03df\u03ec\7"\r
+            + "\3\2\2\u03e0\u03e7\7\4\2\2\u03e1\u03e6\5\u009aN\2\u03e2\u03e6\5j\66\2"\r
+            + "\u03e3\u03e6\5\u00b2Z\2\u03e4\u03e6\5\u00b0Y\2\u03e5\u03e1\3\2\2\2\u03e5"\r
+            + "\u03e2\3\2\2\2\u03e5\u03e3\3\2\2\2\u03e5\u03e4\3\2\2\2\u03e6\u03e9\3\2"\r
+            + "\2\2\u03e7\u03e5\3\2\2\2\u03e7\u03e8\3\2\2\2\u03e8\u03ea\3\2\2\2\u03e9"\r
+            + "\u03e7\3\2\2\2\u03ea\u03ec\7\5\2\2\u03eb\u03df\3\2\2\2\u03eb\u03e0\3\2"\r
+            + "\2\2\u03ec\u009d\3\2\2\2\u03ed\u03ee\7G\2\2\u03ee\u03ef\5\4\3\2\u03ef"\r
+            + "\u03f0\5\b\5\2\u03f0\u009f\3\2\2\2\u03f1\u03f2\7\64\2\2\u03f2\u03ff\5"\r
+            + "\4\3\2\u03f3\u0400\7\3\2\2\u03f4\u03fb\7\4\2\2\u03f5\u03fa\5\u009eP\2"\r
+            + "\u03f6\u03fa\5j\66\2\u03f7\u03fa\5\u00b2Z\2\u03f8\u03fa\5\u00b0Y\2\u03f9"\r
+            + "\u03f5\3\2\2\2\u03f9\u03f6\3\2\2\2\u03f9\u03f7\3\2\2\2\u03f9\u03f8\3\2"\r
+            + "\2\2\u03fa\u03fd\3\2\2\2\u03fb\u03f9\3\2\2\2\u03fb\u03fc\3\2\2\2\u03fc"\r
+            + "\u03fe\3\2\2\2\u03fd\u03fb\3\2\2\2\u03fe\u0400\7\5\2\2\u03ff\u03f3\3\2"\r
+            + "\2\2\u03ff\u03f4\3\2\2\2\u0400\u00a1\3\2\2\2\u0401\u0402\5\4\3\2\u0402"\r
+            + "\u00a3\3\2\2\2\u0403\u0404\7\n\2\2\u0404\u0405\5\u00a2R\2\u0405\u0406"\r
+            + "\5\b\5\2\u0406\u00a5\3\2\2\2\u0407\u0408\7I\2\2\u0408\u040f\5\4\3\2\u0409"\r
+            + "\u0410\7\3\2\2\u040a\u040c\7\4\2\2\u040b\u040d\5\u00a4S\2\u040c\u040b"\r
+            + "\3\2\2\2\u040c\u040d\3\2\2\2\u040d\u040e\3\2\2\2\u040e\u0410\7\5\2\2\u040f"\r
+            + "\u0409\3\2\2\2\u040f\u040a\3\2\2\2\u0410\u00a7\3\2\2\2\u0411\u0412\7:"\r
+            + "\2\2\u0412\u041f\5\4\3\2\u0413\u0420\7\3\2\2\u0414\u041b\7\4\2\2\u0415"\r
+            + "\u041a\5\u00a6T\2\u0416\u041a\5j\66\2\u0417\u041a\5\u00b2Z\2\u0418\u041a"\r
+            + "\5\u00b0Y\2\u0419\u0415\3\2\2\2\u0419\u0416\3\2\2\2\u0419\u0417\3\2\2"\r
+            + "\2\u0419\u0418\3\2\2\2\u041a\u041d\3\2\2\2\u041b\u0419\3\2\2\2\u041b\u041c"\r
+            + "\3\2\2\2\u041c\u041e\3\2\2\2\u041d\u041b\3\2\2\2\u041e\u0420\7\5\2\2\u041f"\r
+            + "\u0413\3\2\2\2\u041f\u0414\3\2\2\2\u0420\u00a9\3\2\2\2\u0421\u0422\7\26"\r
+            + "\2\2\u0422\u0423\5\4\3\2\u0423\u0424\5\b\5\2\u0424\u00ab\3\2\2\2\u0425"\r
+            + "\u0426\7\27\2\2\u0426\u0430\5\4\3\2\u0427\u0431\7\3\2\2\u0428\u042a\7"\r
+            + "\4\2\2\u0429\u042b\5\u00b2Z\2\u042a\u0429\3\2\2\2\u042a\u042b\3\2\2\2"\r
+            + "\u042b\u042d\3\2\2\2\u042c\u042e\5\u00b0Y\2\u042d\u042c\3\2\2\2\u042d"\r
+            + "\u042e\3\2\2\2\u042e\u042f\3\2\2\2\u042f\u0431\7\5\2\2\u0430\u0427\3\2"\r
+            + "\2\2\u0430\u0428\3\2\2\2\u0431\u00ad\3\2\2\2\u0432\u0433\7\17\2\2\u0433"\r
+            + "\u0434\5\4\3\2\u0434\u0435\5\b\5\2\u0435\u00af\3\2\2\2\u0436\u0437\7\32"\r
+            + "\2\2\u0437\u0438\5\4\3\2\u0438\u0439\5\b\5\2\u0439\u00b1\3\2\2\2\u043a"\r
+            + "\u043b\7>\2\2\u043b\u043c\5\4\3\2\u043c\u043d\5\b\5\2\u043d\u00b3\3\2"\r
+            + "\2\2\u043e\u043f\7A\2\2\u043f\u0440\5\4\3\2\u0440\u0441\5\b\5\2\u0441"\r
+            + "\u00b5\3\2\2\2\u0442\u0443\7\"\2\2\u0443\u0444\5\4\3\2\u0444\u0445\5\b"\r
+            + "\5\2\u0445\u00b7\3\2\2\2\u0446\u0447\7F\2\2\u0447\u0448\5\4\3\2\u0448"\r
+            + "\u0449\7\4\2\2\u0449\u044a\5\u00ba^\2\u044a\u044b\7\5\2\2\u044b\u00b9"\r
+            + "\3\2\2\2\u044c\u044d\7\35\2\2\u044d\u044e\5\4\3\2\u044e\u044f\5\b\5\2"\r
+            + "\u044f\u00bb\3\2\2\2\u0450\u0451\7%\2\2\u0451\u0452\5\4\3\2\u0452\u0453"\r
+            + "\5\b\5\2\u0453\u00bd\3\2\2\2\u0454\u0455\7\61\2\2\u0455\u045c\5\4\3\2"\r
+            + "\u0456\u045d\7\3\2\2\u0457\u0459\7\4\2\2\u0458\u045a\5\u00aaV\2\u0459"\r
+            + "\u0458\3\2\2\2\u0459\u045a\3\2\2\2\u045a\u045b\3\2\2\2\u045b\u045d\7\5"\r
+            + "\2\2\u045c\u0456\3\2\2\2\u045c\u0457\3\2\2\2\u045d\u00bf\3\2\2\2\u045e"\r
+            + "\u045f\7\62\2\2\u045f\u0460\5\4\3\2\u0460\u0461\7\4\2\2\u0461\u0463\5"\r
+            + "\u00ba^\2\u0462\u0464\5\u00aaV\2\u0463\u0462\3\2\2\2\u0463\u0464\3\2\2"\r
+            + "\2\u0464\u0465\3\2\2\2\u0465\u0466\7\5\2\2\u0466\u00c1\3\2\2\2\u0467\u0468"\r
+            + "\7\13\2\2\u0468\u0469\5\4\3\2\u0469\u046a\5\b\5\2\u046a\u00c3\3\2\2\2"\r
+            + "\u046b\u0473\5H%\2\u046c\u0473\5F$\2\u046d\u0473\5D#\2\u046e\u0473\5B"\r
+            + "\"\2\u046f\u0473\5<\37\2\u0470\u0473\5\66\34\2\u0471\u0473\5\64\33\2\u0472"\r
+            + "\u046b\3\2\2\2\u0472\u046c\3\2\2\2\u0472\u046d\3\2\2\2\u0472\u046e\3\2"\r
+            + "\2\2\u0472\u046f\3\2\2\2\u0472\u0470\3\2\2\2\u0472\u0471\3\2\2\2\u0473"\r
+            + "\u00c5\3\2\2\2\u0474\u047f\5\u00a8U\2\u0475\u047f\5\u009cO\2\u0476\u047f"\r
+            + "\5\u00a0Q\2\u0477\u047f\5\u0098M\2\u0478\u047f\5J&\2\u0479\u047f\5\u00c4"\r
+            + "c\2\u047a\u047f\5\36\20\2\u047b\u047f\5\32\16\2\u047c\u047f\5\24\13\2"\r
+            + "\u047d\u047f\5\22\n\2\u047e\u0474\3\2\2\2\u047e\u0475\3\2\2\2\u047e\u0476"\r
+            + "\3\2\2\2\u047e\u0477\3\2\2\2\u047e\u0478\3\2\2\2\u047e\u0479\3\2\2\2\u047e"\r
+            + "\u047a\3\2\2\2\u047e\u047b\3\2\2\2\u047e\u047c\3\2\2\2\u047e\u047d\3\2"\r
+            + "\2\2\u047f\u0481\3\2\2\2\u0480\u047e\3\2\2\2\u0481\u0484\3\2\2\2\u0482"\r
+            + "\u0480\3\2\2\2\u0482\u0483\3\2\2\2\u0483\u00c7\3\2\2\2\u0484\u0482\3\2"\r
+            + "\2\2\u0485\u0487\5\u00acW\2\u0486\u0485\3\2\2\2\u0487\u048a\3\2\2\2\u0488"\r
+            + "\u0486\3\2\2\2\u0488\u0489\3\2\2\2\u0489\u00c9\3\2\2\2\u048a\u0488\3\2"\r
+            + "\2\2\u048b\u048e\5\u00c0a\2\u048c\u048e\5\u00be`\2\u048d\u048b\3\2\2\2"\r
+            + "\u048d\u048c\3\2\2\2\u048e\u0491\3\2\2\2\u048f\u048d\3\2\2\2\u048f\u0490"\r
+            + "\3\2\2\2\u0490\u00cb\3\2\2\2\u0491\u048f\3\2\2\2\u0492\u0497\5\u00b6\\"\r
+            + "\2\u0493\u0497\5\u00b4[\2\u0494\u0497\5\u00b2Z\2\u0495\u0497\5\u00b0Y"\r
+            + "\2\u0496\u0492\3\2\2\2\u0496\u0493\3\2\2\2\u0496\u0494\3\2\2\2\u0496\u0495"\r
+            + "\3\2\2\2\u0497\u049a\3\2\2\2\u0498\u0496\3\2\2\2\u0498\u0499\3\2\2\2\u0499"\r
+            + "\u00cd\3\2\2\2\u049a\u0498\3\2\2\2\u049b\u049e\5\u00c2b\2\u049c\u049e"\r
+            + "\5\u00b8]\2\u049d\u049b\3\2\2\2\u049d\u049c\3\2\2\2\u049e\u049f\3\2\2"\r
+            + "\2\u049f\u049d\3\2\2\2\u049f\u04a0\3\2\2\2\u04a0\u00cf\3\2\2\2\u04a1\u04a5"\r
+            + "\5\u00c2b\2\u04a2\u04a5\5\u00bc_\2\u04a3\u04a5\5\u00ba^\2\u04a4\u04a1"\r
+            + "\3\2\2\2\u04a4\u04a2\3\2\2\2\u04a4\u04a3\3\2\2\2\u04a5\u04a6\3\2\2\2\u04a6"\r
+            + "\u04a4\3\2\2\2\u04a6\u04a7\3\2\2\2\u04a7\u00d1\3\2\2\2\u04a8\u04a9\7\23"\r
+            + "\2\2\u04a9\u04aa\5\4\3\2\u04aa\u04ab\7\4\2\2\u04ab\u04ac\5\u00ceh\2\u04ac"\r
+            + "\u04ad\5\u00caf\2\u04ad\u04ae\5\u00ccg\2\u04ae\u04af\5\u00c8e\2\u04af"\r
+            + "\u04b0\5\u00c6d\2\u04b0\u04b1\7\5\2\2\u04b1\u00d3\3\2\2\2\u04b2\u04b3"\r
+            + "\7\'\2\2\u04b3\u04b4\5\4\3\2\u04b4\u04b5\7\4\2\2\u04b5\u04b6\5\u00d0i"\r
+            + "\2\u04b6\u04b7\5\u00caf\2\u04b7\u04b8\5\u00ccg\2\u04b8\u04b9\5\u00c8e"\r
+            + "\2\u04b9\u04ba\5\u00c6d\2\u04ba\u04bb\7\5\2\2\u04bb\u00d5\3\2\2\2\u008c"\r
+            + "\u00d8\u00df\u00e4\u00ea\u00ee\u00f1\u00fe\u0100\u0104\u010e\u0110\u0114"\r
+            + "\u0122\u0124\u0128\u012f\u0132\u013d\u013f\u014e\u0150\u0154\u015b\u015d"\r
+            + "\u0166\u0168\u0178\u017a\u017e\u0186\u0188\u018c\u0199\u019b\u01aa\u01ac"\r
+            + "\u01b5\u01b7\u01bc\u01be\u01c6\u01c8\u01d1\u01d3\u01dc\u01de\u01e7\u01e9"\r
+            + "\u01f1\u01f3\u01fd\u0206\u020a\u0218\u021a\u021e\u022d\u022f\u0233\u0240"\r
+            + "\u0242\u0246\u024d\u025e\u0260\u0264\u0281\u0283\u0297\u0299\u02ad\u02af"\r
+            + "\u02c4\u02c6\u02ca\u02d7\u02d9\u02dd\u02fe\u0300\u0304\u032f\u0331\u0335"\r
+            + "\u033a\u033f\u0344\u035b\u035d\u0361\u0366\u0375\u0377\u037b\u0386\u0388"\r
+            + "\u038c\u0390\u0392\u039a\u039f\u03a1\u03ac\u03ae\u03b2\u03bf\u03c8\u03d3"\r
+            + "\u03d5\u03e5\u03e7\u03eb\u03f9\u03fb\u03ff\u040c\u040f\u0419\u041b\u041f"\r
+            + "\u042a\u042d\u0430\u0459\u045c\u0463\u0472\u047e\u0482\u0488\u048d\u048f"\r
+            + "\u0496\u0498\u049d\u049f\u04a4\u04a6";\r
+    public static final ATN _ATN = ATNSimulator.deserialize(_serializedATN\r
+            .toCharArray());\r
+    static {\r
+        _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];\r
+    }\r
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParserBaseListener.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParserBaseListener.java
new file mode 100644 (file)
index 0000000..524201a
--- /dev/null
@@ -0,0 +1,916 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.antlrv4.code.gen;\r
+\r
+import org.antlr.v4.runtime.ParserRuleContext;\r
+import org.antlr.v4.runtime.tree.ErrorNode;\r
+import org.antlr.v4.runtime.tree.TerminalNode;\r
+\r
+public class YangParserBaseListener implements YangParserListener {\r
+    @Override\r
+    public void enterEnum_specification(YangParser.Enum_specificationContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitEnum_specification(YangParser.Enum_specificationContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRefine_leaf_list_stmts(\r
+            YangParser.Refine_leaf_list_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRefine_leaf_list_stmts(\r
+            YangParser.Refine_leaf_list_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterPosition_stmt(YangParser.Position_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitPosition_stmt(YangParser.Position_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterArgument_stmt(YangParser.Argument_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitArgument_stmt(YangParser.Argument_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterLeafref_specification(\r
+            YangParser.Leafref_specificationContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitLeafref_specification(\r
+            YangParser.Leafref_specificationContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterError_app_tag_stmt(YangParser.Error_app_tag_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitError_app_tag_stmt(YangParser.Error_app_tag_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterData_def_stmt(YangParser.Data_def_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitData_def_stmt(YangParser.Data_def_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterIdentity_stmt(YangParser.Identity_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitIdentity_stmt(YangParser.Identity_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterDeviate_not_supported_stmt(\r
+            YangParser.Deviate_not_supported_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitDeviate_not_supported_stmt(\r
+            YangParser.Deviate_not_supported_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterPrefix_stmt(YangParser.Prefix_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitPrefix_stmt(YangParser.Prefix_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterMeta_stmts(YangParser.Meta_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitMeta_stmts(YangParser.Meta_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterLinkage_stmts(YangParser.Linkage_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitLinkage_stmts(YangParser.Linkage_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterGrouping_stmt(YangParser.Grouping_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitGrouping_stmt(YangParser.Grouping_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterFeature_stmt(YangParser.Feature_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitFeature_stmt(YangParser.Feature_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterYang(YangParser.YangContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitYang(YangParser.YangContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterIdentityref_specification(\r
+            YangParser.Identityref_specificationContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitIdentityref_specification(\r
+            YangParser.Identityref_specificationContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterNumerical_restrictions(\r
+            YangParser.Numerical_restrictionsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitNumerical_restrictions(\r
+            YangParser.Numerical_restrictionsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterModule_header_stmts(\r
+            YangParser.Module_header_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitModule_header_stmts(\r
+            YangParser.Module_header_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRequire_instance_stmt(\r
+            YangParser.Require_instance_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRequire_instance_stmt(\r
+            YangParser.Require_instance_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterBit_stmt(YangParser.Bit_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitBit_stmt(YangParser.Bit_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterType_stmt(YangParser.Type_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitType_stmt(YangParser.Type_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterPattern_stmt(YangParser.Pattern_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitPattern_stmt(YangParser.Pattern_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterDeviation_stmt(YangParser.Deviation_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitDeviation_stmt(YangParser.Deviation_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterDeviate_replace_stmt(\r
+            YangParser.Deviate_replace_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitDeviate_replace_stmt(\r
+            YangParser.Deviate_replace_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterKey_stmt(YangParser.Key_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitKey_stmt(YangParser.Key_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRequire_instance_arg(\r
+            YangParser.Require_instance_argContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRequire_instance_arg(\r
+            YangParser.Require_instance_argContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterLeaf_list_stmt(YangParser.Leaf_list_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitLeaf_list_stmt(YangParser.Leaf_list_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterAugment_stmt(YangParser.Augment_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitAugment_stmt(YangParser.Augment_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterDeviate_delete_stmt(\r
+            YangParser.Deviate_delete_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitDeviate_delete_stmt(\r
+            YangParser.Deviate_delete_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterTypedef_stmt(YangParser.Typedef_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitTypedef_stmt(YangParser.Typedef_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterContainer_stmt(YangParser.Container_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitContainer_stmt(YangParser.Container_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterBelongs_to_stmt(YangParser.Belongs_to_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitBelongs_to_stmt(YangParser.Belongs_to_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterBase_stmt(YangParser.Base_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitBase_stmt(YangParser.Base_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterYang_version_stmt(YangParser.Yang_version_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitYang_version_stmt(YangParser.Yang_version_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterReference_stmt(YangParser.Reference_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitReference_stmt(YangParser.Reference_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterYin_element_stmt(YangParser.Yin_element_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitYin_element_stmt(YangParser.Yin_element_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterLeaf_stmt(YangParser.Leaf_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitLeaf_stmt(YangParser.Leaf_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterCase_stmt(YangParser.Case_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitCase_stmt(YangParser.Case_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterModule_stmt(YangParser.Module_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitModule_stmt(YangParser.Module_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRpc_stmt(YangParser.Rpc_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRpc_stmt(YangParser.Rpc_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterType_body_stmts(YangParser.Type_body_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitType_body_stmts(YangParser.Type_body_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterExtension_stmt(YangParser.Extension_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitExtension_stmt(YangParser.Extension_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterSubmodule_header_stmts(\r
+            YangParser.Submodule_header_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitSubmodule_header_stmts(\r
+            YangParser.Submodule_header_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRefine_container_stmts(\r
+            YangParser.Refine_container_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRefine_container_stmts(\r
+            YangParser.Refine_container_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterValue_stmt(YangParser.Value_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitValue_stmt(YangParser.Value_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRefine_list_stmts(YangParser.Refine_list_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRefine_list_stmts(YangParser.Refine_list_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterDefault_stmt(YangParser.Default_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitDefault_stmt(YangParser.Default_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRevision_stmts(YangParser.Revision_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRevision_stmts(YangParser.Revision_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterAnyxml_stmt(YangParser.Anyxml_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitAnyxml_stmt(YangParser.Anyxml_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterStatus_stmt(YangParser.Status_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitStatus_stmt(YangParser.Status_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterContact_stmt(YangParser.Contact_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitContact_stmt(YangParser.Contact_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterString(YangParser.StringContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitString(YangParser.StringContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRefine_choice_stmts(\r
+            YangParser.Refine_choice_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRefine_choice_stmts(\r
+            YangParser.Refine_choice_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterMandatory_arg(YangParser.Mandatory_argContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitMandatory_arg(YangParser.Mandatory_argContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRefine_stmt(YangParser.Refine_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRefine_stmt(YangParser.Refine_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterInstance_identifier_specification(\r
+            YangParser.Instance_identifier_specificationContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitInstance_identifier_specification(\r
+            YangParser.Instance_identifier_specificationContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterBits_specification(YangParser.Bits_specificationContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitBits_specification(YangParser.Bits_specificationContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterWhen_stmt(YangParser.When_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitWhen_stmt(YangParser.When_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterString_restrictions(\r
+            YangParser.String_restrictionsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitString_restrictions(\r
+            YangParser.String_restrictionsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRefine_leaf_stmts(YangParser.Refine_leaf_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRefine_leaf_stmts(YangParser.Refine_leaf_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterMandatory_stmt(YangParser.Mandatory_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitMandatory_stmt(YangParser.Mandatory_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterOrdered_by_arg(YangParser.Ordered_by_argContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitOrdered_by_arg(YangParser.Ordered_by_argContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterMin_elements_stmt(YangParser.Min_elements_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitMin_elements_stmt(YangParser.Min_elements_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterStmtend(YangParser.StmtendContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitStmtend(YangParser.StmtendContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRefine_anyxml_stmts(\r
+            YangParser.Refine_anyxml_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRefine_anyxml_stmts(\r
+            YangParser.Refine_anyxml_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterDescription_stmt(YangParser.Description_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitDescription_stmt(YangParser.Description_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterPath_stmt(YangParser.Path_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitPath_stmt(YangParser.Path_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterInclude_stmt(YangParser.Include_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitInclude_stmt(YangParser.Include_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterUnits_stmt(YangParser.Units_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitUnits_stmt(YangParser.Units_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterUses_stmt(YangParser.Uses_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitUses_stmt(YangParser.Uses_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterOrdered_by_stmt(YangParser.Ordered_by_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitOrdered_by_stmt(YangParser.Ordered_by_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRange_stmt(YangParser.Range_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRange_stmt(YangParser.Range_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterNamespace_stmt(YangParser.Namespace_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitNamespace_stmt(YangParser.Namespace_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterDeviate_add_stmt(YangParser.Deviate_add_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitDeviate_add_stmt(YangParser.Deviate_add_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterShort_case_stmt(YangParser.Short_case_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitShort_case_stmt(YangParser.Short_case_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterConfig_stmt(YangParser.Config_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitConfig_stmt(YangParser.Config_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterEnum_stmt(YangParser.Enum_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitEnum_stmt(YangParser.Enum_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterYin_element_arg(YangParser.Yin_element_argContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitYin_element_arg(YangParser.Yin_element_argContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterOrganization_stmt(YangParser.Organization_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitOrganization_stmt(YangParser.Organization_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterUnion_specification(\r
+            YangParser.Union_specificationContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitUnion_specification(\r
+            YangParser.Union_specificationContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterMax_value_arg(YangParser.Max_value_argContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitMax_value_arg(YangParser.Max_value_argContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterSubmodule_stmt(YangParser.Submodule_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitSubmodule_stmt(YangParser.Submodule_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterStatus_arg(YangParser.Status_argContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitStatus_arg(YangParser.Status_argContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterList_stmt(YangParser.List_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitList_stmt(YangParser.List_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterMax_elements_stmt(YangParser.Max_elements_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitMax_elements_stmt(YangParser.Max_elements_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterImport_stmt(YangParser.Import_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitImport_stmt(YangParser.Import_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterConfig_arg(YangParser.Config_argContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitConfig_arg(YangParser.Config_argContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRevision_date_stmt(YangParser.Revision_date_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRevision_date_stmt(YangParser.Revision_date_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRefune_pom(YangParser.Refune_pomContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRefune_pom(YangParser.Refune_pomContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterPresence_stmt(YangParser.Presence_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitPresence_stmt(YangParser.Presence_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterFraction_digits_stmt(\r
+            YangParser.Fraction_digits_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitFraction_digits_stmt(\r
+            YangParser.Fraction_digits_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterNotification_stmt(YangParser.Notification_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitNotification_stmt(YangParser.Notification_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterInput_stmt(YangParser.Input_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitInput_stmt(YangParser.Input_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRefine_case_stmts(YangParser.Refine_case_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRefine_case_stmts(YangParser.Refine_case_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterDecimal64_specification(\r
+            YangParser.Decimal64_specificationContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitDecimal64_specification(\r
+            YangParser.Decimal64_specificationContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterIf_feature_stmt(YangParser.If_feature_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitIf_feature_stmt(YangParser.If_feature_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterRevision_stmt(YangParser.Revision_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitRevision_stmt(YangParser.Revision_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterLength_stmt(YangParser.Length_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitLength_stmt(YangParser.Length_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterMust_stmt(YangParser.Must_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitMust_stmt(YangParser.Must_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterBody_stmts(YangParser.Body_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitBody_stmts(YangParser.Body_stmtsContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterError_message_stmt(YangParser.Error_message_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitError_message_stmt(YangParser.Error_message_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterUnique_stmt(YangParser.Unique_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitUnique_stmt(YangParser.Unique_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterChoice_stmt(YangParser.Choice_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitChoice_stmt(YangParser.Choice_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterOutput_stmt(YangParser.Output_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitOutput_stmt(YangParser.Output_stmtContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void enterEveryRule(ParserRuleContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void exitEveryRule(ParserRuleContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void visitTerminal(TerminalNode node) {\r
+    }\r
+\r
+    @Override\r
+    public void visitErrorNode(ErrorNode node) {\r
+    }\r
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParserBaseVisitor.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParserBaseVisitor.java
new file mode 100644 (file)
index 0000000..4839edb
--- /dev/null
@@ -0,0 +1,556 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.antlrv4.code.gen;\r
+\r
+import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;\r
+\r
+public class YangParserBaseVisitor<T> extends AbstractParseTreeVisitor<T>\r
+        implements YangParserVisitor<T> {\r
+    @Override\r
+    public T visitEnum_specification(YangParser.Enum_specificationContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRefine_leaf_list_stmts(\r
+            YangParser.Refine_leaf_list_stmtsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitPosition_stmt(YangParser.Position_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitArgument_stmt(YangParser.Argument_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitLeafref_specification(\r
+            YangParser.Leafref_specificationContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitError_app_tag_stmt(YangParser.Error_app_tag_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitData_def_stmt(YangParser.Data_def_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitIdentity_stmt(YangParser.Identity_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitDeviate_not_supported_stmt(\r
+            YangParser.Deviate_not_supported_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitPrefix_stmt(YangParser.Prefix_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitMeta_stmts(YangParser.Meta_stmtsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitLinkage_stmts(YangParser.Linkage_stmtsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitGrouping_stmt(YangParser.Grouping_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitFeature_stmt(YangParser.Feature_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitYang(YangParser.YangContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitIdentityref_specification(\r
+            YangParser.Identityref_specificationContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitNumerical_restrictions(\r
+            YangParser.Numerical_restrictionsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitModule_header_stmts(YangParser.Module_header_stmtsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRequire_instance_stmt(\r
+            YangParser.Require_instance_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitBit_stmt(YangParser.Bit_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitType_stmt(YangParser.Type_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitPattern_stmt(YangParser.Pattern_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitDeviation_stmt(YangParser.Deviation_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitDeviate_replace_stmt(\r
+            YangParser.Deviate_replace_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitKey_stmt(YangParser.Key_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRequire_instance_arg(\r
+            YangParser.Require_instance_argContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitLeaf_list_stmt(YangParser.Leaf_list_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitAugment_stmt(YangParser.Augment_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitDeviate_delete_stmt(YangParser.Deviate_delete_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitTypedef_stmt(YangParser.Typedef_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitContainer_stmt(YangParser.Container_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitBelongs_to_stmt(YangParser.Belongs_to_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitBase_stmt(YangParser.Base_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitYang_version_stmt(YangParser.Yang_version_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitReference_stmt(YangParser.Reference_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitYin_element_stmt(YangParser.Yin_element_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitLeaf_stmt(YangParser.Leaf_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitCase_stmt(YangParser.Case_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitModule_stmt(YangParser.Module_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRpc_stmt(YangParser.Rpc_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitType_body_stmts(YangParser.Type_body_stmtsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitExtension_stmt(YangParser.Extension_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitSubmodule_header_stmts(\r
+            YangParser.Submodule_header_stmtsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRefine_container_stmts(\r
+            YangParser.Refine_container_stmtsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitValue_stmt(YangParser.Value_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRefine_list_stmts(YangParser.Refine_list_stmtsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitDefault_stmt(YangParser.Default_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRevision_stmts(YangParser.Revision_stmtsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitAnyxml_stmt(YangParser.Anyxml_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitStatus_stmt(YangParser.Status_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitContact_stmt(YangParser.Contact_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitString(YangParser.StringContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRefine_choice_stmts(YangParser.Refine_choice_stmtsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitMandatory_arg(YangParser.Mandatory_argContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRefine_stmt(YangParser.Refine_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitInstance_identifier_specification(\r
+            YangParser.Instance_identifier_specificationContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitBits_specification(YangParser.Bits_specificationContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitWhen_stmt(YangParser.When_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitString_restrictions(YangParser.String_restrictionsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRefine_leaf_stmts(YangParser.Refine_leaf_stmtsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitMandatory_stmt(YangParser.Mandatory_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitOrdered_by_arg(YangParser.Ordered_by_argContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitMin_elements_stmt(YangParser.Min_elements_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitStmtend(YangParser.StmtendContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRefine_anyxml_stmts(YangParser.Refine_anyxml_stmtsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitDescription_stmt(YangParser.Description_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitPath_stmt(YangParser.Path_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitInclude_stmt(YangParser.Include_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitUnits_stmt(YangParser.Units_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitUses_stmt(YangParser.Uses_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitOrdered_by_stmt(YangParser.Ordered_by_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRange_stmt(YangParser.Range_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitNamespace_stmt(YangParser.Namespace_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitDeviate_add_stmt(YangParser.Deviate_add_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitShort_case_stmt(YangParser.Short_case_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitConfig_stmt(YangParser.Config_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitEnum_stmt(YangParser.Enum_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitYin_element_arg(YangParser.Yin_element_argContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitOrganization_stmt(YangParser.Organization_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitUnion_specification(YangParser.Union_specificationContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitMax_value_arg(YangParser.Max_value_argContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitSubmodule_stmt(YangParser.Submodule_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitStatus_arg(YangParser.Status_argContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitList_stmt(YangParser.List_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitMax_elements_stmt(YangParser.Max_elements_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitImport_stmt(YangParser.Import_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitConfig_arg(YangParser.Config_argContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRevision_date_stmt(YangParser.Revision_date_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRefune_pom(YangParser.Refune_pomContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitPresence_stmt(YangParser.Presence_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitFraction_digits_stmt(\r
+            YangParser.Fraction_digits_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitNotification_stmt(YangParser.Notification_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitInput_stmt(YangParser.Input_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRefine_case_stmts(YangParser.Refine_case_stmtsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitDecimal64_specification(\r
+            YangParser.Decimal64_specificationContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitIf_feature_stmt(YangParser.If_feature_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitRevision_stmt(YangParser.Revision_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitLength_stmt(YangParser.Length_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitMust_stmt(YangParser.Must_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitBody_stmts(YangParser.Body_stmtsContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitError_message_stmt(YangParser.Error_message_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitUnique_stmt(YangParser.Unique_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitChoice_stmt(YangParser.Choice_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+\r
+    @Override\r
+    public T visitOutput_stmt(YangParser.Output_stmtContext ctx) {\r
+        return visitChildren(ctx);\r
+    }\r
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParserListener.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParserListener.java
new file mode 100644 (file)
index 0000000..09734ae
--- /dev/null
@@ -0,0 +1,448 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.antlrv4.code.gen;\r
+\r
+import org.antlr.v4.runtime.tree.ParseTreeListener;\r
+\r
+public interface YangParserListener extends ParseTreeListener {\r
+    void enterEnum_specification(YangParser.Enum_specificationContext ctx);\r
+\r
+    void exitEnum_specification(YangParser.Enum_specificationContext ctx);\r
+\r
+    void enterRefine_leaf_list_stmts(\r
+            YangParser.Refine_leaf_list_stmtsContext ctx);\r
+\r
+    void exitRefine_leaf_list_stmts(YangParser.Refine_leaf_list_stmtsContext ctx);\r
+\r
+    void enterPosition_stmt(YangParser.Position_stmtContext ctx);\r
+\r
+    void exitPosition_stmt(YangParser.Position_stmtContext ctx);\r
+\r
+    void enterArgument_stmt(YangParser.Argument_stmtContext ctx);\r
+\r
+    void exitArgument_stmt(YangParser.Argument_stmtContext ctx);\r
+\r
+    void enterLeafref_specification(YangParser.Leafref_specificationContext ctx);\r
+\r
+    void exitLeafref_specification(YangParser.Leafref_specificationContext ctx);\r
+\r
+    void enterError_app_tag_stmt(YangParser.Error_app_tag_stmtContext ctx);\r
+\r
+    void exitError_app_tag_stmt(YangParser.Error_app_tag_stmtContext ctx);\r
+\r
+    void enterData_def_stmt(YangParser.Data_def_stmtContext ctx);\r
+\r
+    void exitData_def_stmt(YangParser.Data_def_stmtContext ctx);\r
+\r
+    void enterIdentity_stmt(YangParser.Identity_stmtContext ctx);\r
+\r
+    void exitIdentity_stmt(YangParser.Identity_stmtContext ctx);\r
+\r
+    void enterDeviate_not_supported_stmt(\r
+            YangParser.Deviate_not_supported_stmtContext ctx);\r
+\r
+    void exitDeviate_not_supported_stmt(\r
+            YangParser.Deviate_not_supported_stmtContext ctx);\r
+\r
+    void enterPrefix_stmt(YangParser.Prefix_stmtContext ctx);\r
+\r
+    void exitPrefix_stmt(YangParser.Prefix_stmtContext ctx);\r
+\r
+    void enterMeta_stmts(YangParser.Meta_stmtsContext ctx);\r
+\r
+    void exitMeta_stmts(YangParser.Meta_stmtsContext ctx);\r
+\r
+    void enterLinkage_stmts(YangParser.Linkage_stmtsContext ctx);\r
+\r
+    void exitLinkage_stmts(YangParser.Linkage_stmtsContext ctx);\r
+\r
+    void enterGrouping_stmt(YangParser.Grouping_stmtContext ctx);\r
+\r
+    void exitGrouping_stmt(YangParser.Grouping_stmtContext ctx);\r
+\r
+    void enterFeature_stmt(YangParser.Feature_stmtContext ctx);\r
+\r
+    void exitFeature_stmt(YangParser.Feature_stmtContext ctx);\r
+\r
+    void enterYang(YangParser.YangContext ctx);\r
+\r
+    void exitYang(YangParser.YangContext ctx);\r
+\r
+    void enterIdentityref_specification(\r
+            YangParser.Identityref_specificationContext ctx);\r
+\r
+    void exitIdentityref_specification(\r
+            YangParser.Identityref_specificationContext ctx);\r
+\r
+    void enterNumerical_restrictions(\r
+            YangParser.Numerical_restrictionsContext ctx);\r
+\r
+    void exitNumerical_restrictions(YangParser.Numerical_restrictionsContext ctx);\r
+\r
+    void enterModule_header_stmts(YangParser.Module_header_stmtsContext ctx);\r
+\r
+    void exitModule_header_stmts(YangParser.Module_header_stmtsContext ctx);\r
+\r
+    void enterRequire_instance_stmt(YangParser.Require_instance_stmtContext ctx);\r
+\r
+    void exitRequire_instance_stmt(YangParser.Require_instance_stmtContext ctx);\r
+\r
+    void enterBit_stmt(YangParser.Bit_stmtContext ctx);\r
+\r
+    void exitBit_stmt(YangParser.Bit_stmtContext ctx);\r
+\r
+    void enterType_stmt(YangParser.Type_stmtContext ctx);\r
+\r
+    void exitType_stmt(YangParser.Type_stmtContext ctx);\r
+\r
+    void enterPattern_stmt(YangParser.Pattern_stmtContext ctx);\r
+\r
+    void exitPattern_stmt(YangParser.Pattern_stmtContext ctx);\r
+\r
+    void enterDeviation_stmt(YangParser.Deviation_stmtContext ctx);\r
+\r
+    void exitDeviation_stmt(YangParser.Deviation_stmtContext ctx);\r
+\r
+    void enterDeviate_replace_stmt(YangParser.Deviate_replace_stmtContext ctx);\r
+\r
+    void exitDeviate_replace_stmt(YangParser.Deviate_replace_stmtContext ctx);\r
+\r
+    void enterKey_stmt(YangParser.Key_stmtContext ctx);\r
+\r
+    void exitKey_stmt(YangParser.Key_stmtContext ctx);\r
+\r
+    void enterRequire_instance_arg(YangParser.Require_instance_argContext ctx);\r
+\r
+    void exitRequire_instance_arg(YangParser.Require_instance_argContext ctx);\r
+\r
+    void enterLeaf_list_stmt(YangParser.Leaf_list_stmtContext ctx);\r
+\r
+    void exitLeaf_list_stmt(YangParser.Leaf_list_stmtContext ctx);\r
+\r
+    void enterAugment_stmt(YangParser.Augment_stmtContext ctx);\r
+\r
+    void exitAugment_stmt(YangParser.Augment_stmtContext ctx);\r
+\r
+    void enterDeviate_delete_stmt(YangParser.Deviate_delete_stmtContext ctx);\r
+\r
+    void exitDeviate_delete_stmt(YangParser.Deviate_delete_stmtContext ctx);\r
+\r
+    void enterTypedef_stmt(YangParser.Typedef_stmtContext ctx);\r
+\r
+    void exitTypedef_stmt(YangParser.Typedef_stmtContext ctx);\r
+\r
+    void enterContainer_stmt(YangParser.Container_stmtContext ctx);\r
+\r
+    void exitContainer_stmt(YangParser.Container_stmtContext ctx);\r
+\r
+    void enterBelongs_to_stmt(YangParser.Belongs_to_stmtContext ctx);\r
+\r
+    void exitBelongs_to_stmt(YangParser.Belongs_to_stmtContext ctx);\r
+\r
+    void enterBase_stmt(YangParser.Base_stmtContext ctx);\r
+\r
+    void exitBase_stmt(YangParser.Base_stmtContext ctx);\r
+\r
+    void enterYang_version_stmt(YangParser.Yang_version_stmtContext ctx);\r
+\r
+    void exitYang_version_stmt(YangParser.Yang_version_stmtContext ctx);\r
+\r
+    void enterReference_stmt(YangParser.Reference_stmtContext ctx);\r
+\r
+    void exitReference_stmt(YangParser.Reference_stmtContext ctx);\r
+\r
+    void enterYin_element_stmt(YangParser.Yin_element_stmtContext ctx);\r
+\r
+    void exitYin_element_stmt(YangParser.Yin_element_stmtContext ctx);\r
+\r
+    void enterLeaf_stmt(YangParser.Leaf_stmtContext ctx);\r
+\r
+    void exitLeaf_stmt(YangParser.Leaf_stmtContext ctx);\r
+\r
+    void enterCase_stmt(YangParser.Case_stmtContext ctx);\r
+\r
+    void exitCase_stmt(YangParser.Case_stmtContext ctx);\r
+\r
+    void enterModule_stmt(YangParser.Module_stmtContext ctx);\r
+\r
+    void exitModule_stmt(YangParser.Module_stmtContext ctx);\r
+\r
+    void enterRpc_stmt(YangParser.Rpc_stmtContext ctx);\r
+\r
+    void exitRpc_stmt(YangParser.Rpc_stmtContext ctx);\r
+\r
+    void enterType_body_stmts(YangParser.Type_body_stmtsContext ctx);\r
+\r
+    void exitType_body_stmts(YangParser.Type_body_stmtsContext ctx);\r
+\r
+    void enterExtension_stmt(YangParser.Extension_stmtContext ctx);\r
+\r
+    void exitExtension_stmt(YangParser.Extension_stmtContext ctx);\r
+\r
+    void enterSubmodule_header_stmts(\r
+            YangParser.Submodule_header_stmtsContext ctx);\r
+\r
+    void exitSubmodule_header_stmts(YangParser.Submodule_header_stmtsContext ctx);\r
+\r
+    void enterRefine_container_stmts(\r
+            YangParser.Refine_container_stmtsContext ctx);\r
+\r
+    void exitRefine_container_stmts(YangParser.Refine_container_stmtsContext ctx);\r
+\r
+    void enterValue_stmt(YangParser.Value_stmtContext ctx);\r
+\r
+    void exitValue_stmt(YangParser.Value_stmtContext ctx);\r
+\r
+    void enterRefine_list_stmts(YangParser.Refine_list_stmtsContext ctx);\r
+\r
+    void exitRefine_list_stmts(YangParser.Refine_list_stmtsContext ctx);\r
+\r
+    void enterDefault_stmt(YangParser.Default_stmtContext ctx);\r
+\r
+    void exitDefault_stmt(YangParser.Default_stmtContext ctx);\r
+\r
+    void enterRevision_stmts(YangParser.Revision_stmtsContext ctx);\r
+\r
+    void exitRevision_stmts(YangParser.Revision_stmtsContext ctx);\r
+\r
+    void enterAnyxml_stmt(YangParser.Anyxml_stmtContext ctx);\r
+\r
+    void exitAnyxml_stmt(YangParser.Anyxml_stmtContext ctx);\r
+\r
+    void enterStatus_stmt(YangParser.Status_stmtContext ctx);\r
+\r
+    void exitStatus_stmt(YangParser.Status_stmtContext ctx);\r
+\r
+    void enterContact_stmt(YangParser.Contact_stmtContext ctx);\r
+\r
+    void exitContact_stmt(YangParser.Contact_stmtContext ctx);\r
+\r
+    void enterIdentifier_stmt(YangParser.Identifier_stmtContext ctx);\r
+\r
+    void exitIdentifier_stmt(YangParser.Identifier_stmtContext ctx);\r
+\r
+    void enterString(YangParser.StringContext ctx);\r
+\r
+    void exitString(YangParser.StringContext ctx);\r
+\r
+    void enterRefine_choice_stmts(YangParser.Refine_choice_stmtsContext ctx);\r
+\r
+    void exitRefine_choice_stmts(YangParser.Refine_choice_stmtsContext ctx);\r
+\r
+    void enterMandatory_arg(YangParser.Mandatory_argContext ctx);\r
+\r
+    void exitMandatory_arg(YangParser.Mandatory_argContext ctx);\r
+\r
+    void enterRefine_stmt(YangParser.Refine_stmtContext ctx);\r
+\r
+    void exitRefine_stmt(YangParser.Refine_stmtContext ctx);\r
+\r
+    void enterInstance_identifier_specification(\r
+            YangParser.Instance_identifier_specificationContext ctx);\r
+\r
+    void exitInstance_identifier_specification(\r
+            YangParser.Instance_identifier_specificationContext ctx);\r
+\r
+    void enterBits_specification(YangParser.Bits_specificationContext ctx);\r
+\r
+    void exitBits_specification(YangParser.Bits_specificationContext ctx);\r
+\r
+    void enterWhen_stmt(YangParser.When_stmtContext ctx);\r
+\r
+    void exitWhen_stmt(YangParser.When_stmtContext ctx);\r
+\r
+    void enterString_restrictions(YangParser.String_restrictionsContext ctx);\r
+\r
+    void exitString_restrictions(YangParser.String_restrictionsContext ctx);\r
+\r
+    void enterRefine_leaf_stmts(YangParser.Refine_leaf_stmtsContext ctx);\r
+\r
+    void exitRefine_leaf_stmts(YangParser.Refine_leaf_stmtsContext ctx);\r
+\r
+    void enterMandatory_stmt(YangParser.Mandatory_stmtContext ctx);\r
+\r
+    void exitMandatory_stmt(YangParser.Mandatory_stmtContext ctx);\r
+\r
+    void enterOrdered_by_arg(YangParser.Ordered_by_argContext ctx);\r
+\r
+    void exitOrdered_by_arg(YangParser.Ordered_by_argContext ctx);\r
+\r
+    void enterMin_elements_stmt(YangParser.Min_elements_stmtContext ctx);\r
+\r
+    void exitMin_elements_stmt(YangParser.Min_elements_stmtContext ctx);\r
+\r
+    void enterStmtend(YangParser.StmtendContext ctx);\r
+\r
+    void exitStmtend(YangParser.StmtendContext ctx);\r
+\r
+    void enterRefine_anyxml_stmts(YangParser.Refine_anyxml_stmtsContext ctx);\r
+\r
+    void exitRefine_anyxml_stmts(YangParser.Refine_anyxml_stmtsContext ctx);\r
+\r
+    void enterDescription_stmt(YangParser.Description_stmtContext ctx);\r
+\r
+    void exitDescription_stmt(YangParser.Description_stmtContext ctx);\r
+\r
+    void enterPath_stmt(YangParser.Path_stmtContext ctx);\r
+\r
+    void exitPath_stmt(YangParser.Path_stmtContext ctx);\r
+\r
+    void enterInclude_stmt(YangParser.Include_stmtContext ctx);\r
+\r
+    void exitInclude_stmt(YangParser.Include_stmtContext ctx);\r
+\r
+    void enterUnits_stmt(YangParser.Units_stmtContext ctx);\r
+\r
+    void exitUnits_stmt(YangParser.Units_stmtContext ctx);\r
+\r
+    void enterUses_stmt(YangParser.Uses_stmtContext ctx);\r
+\r
+    void exitUses_stmt(YangParser.Uses_stmtContext ctx);\r
+\r
+    void enterOrdered_by_stmt(YangParser.Ordered_by_stmtContext ctx);\r
+\r
+    void exitOrdered_by_stmt(YangParser.Ordered_by_stmtContext ctx);\r
+\r
+    void enterRange_stmt(YangParser.Range_stmtContext ctx);\r
+\r
+    void exitRange_stmt(YangParser.Range_stmtContext ctx);\r
+\r
+    void enterNamespace_stmt(YangParser.Namespace_stmtContext ctx);\r
+\r
+    void exitNamespace_stmt(YangParser.Namespace_stmtContext ctx);\r
+\r
+    void enterDeviate_add_stmt(YangParser.Deviate_add_stmtContext ctx);\r
+\r
+    void exitDeviate_add_stmt(YangParser.Deviate_add_stmtContext ctx);\r
+\r
+    void enterShort_case_stmt(YangParser.Short_case_stmtContext ctx);\r
+\r
+    void exitShort_case_stmt(YangParser.Short_case_stmtContext ctx);\r
+\r
+    void enterConfig_stmt(YangParser.Config_stmtContext ctx);\r
+\r
+    void exitConfig_stmt(YangParser.Config_stmtContext ctx);\r
+\r
+    void enterEnum_stmt(YangParser.Enum_stmtContext ctx);\r
+\r
+    void exitEnum_stmt(YangParser.Enum_stmtContext ctx);\r
+\r
+    void enterYin_element_arg(YangParser.Yin_element_argContext ctx);\r
+\r
+    void exitYin_element_arg(YangParser.Yin_element_argContext ctx);\r
+\r
+    void enterOrganization_stmt(YangParser.Organization_stmtContext ctx);\r
+\r
+    void exitOrganization_stmt(YangParser.Organization_stmtContext ctx);\r
+\r
+    void enterUnion_specification(YangParser.Union_specificationContext ctx);\r
+\r
+    void exitUnion_specification(YangParser.Union_specificationContext ctx);\r
+\r
+    void enterMax_value_arg(YangParser.Max_value_argContext ctx);\r
+\r
+    void exitMax_value_arg(YangParser.Max_value_argContext ctx);\r
+\r
+    void enterSubmodule_stmt(YangParser.Submodule_stmtContext ctx);\r
+\r
+    void exitSubmodule_stmt(YangParser.Submodule_stmtContext ctx);\r
+\r
+    void enterStatus_arg(YangParser.Status_argContext ctx);\r
+\r
+    void exitStatus_arg(YangParser.Status_argContext ctx);\r
+\r
+    void enterList_stmt(YangParser.List_stmtContext ctx);\r
+\r
+    void exitList_stmt(YangParser.List_stmtContext ctx);\r
+\r
+    void enterMax_elements_stmt(YangParser.Max_elements_stmtContext ctx);\r
+\r
+    void exitMax_elements_stmt(YangParser.Max_elements_stmtContext ctx);\r
+\r
+    void enterImport_stmt(YangParser.Import_stmtContext ctx);\r
+\r
+    void exitImport_stmt(YangParser.Import_stmtContext ctx);\r
+\r
+    void enterConfig_arg(YangParser.Config_argContext ctx);\r
+\r
+    void exitConfig_arg(YangParser.Config_argContext ctx);\r
+\r
+    void enterRevision_date_stmt(YangParser.Revision_date_stmtContext ctx);\r
+\r
+    void exitRevision_date_stmt(YangParser.Revision_date_stmtContext ctx);\r
+\r
+    void enterRefune_pom(YangParser.Refune_pomContext ctx);\r
+\r
+    void exitRefune_pom(YangParser.Refune_pomContext ctx);\r
+\r
+    void enterPresence_stmt(YangParser.Presence_stmtContext ctx);\r
+\r
+    void exitPresence_stmt(YangParser.Presence_stmtContext ctx);\r
+\r
+    void enterFraction_digits_stmt(YangParser.Fraction_digits_stmtContext ctx);\r
+\r
+    void exitFraction_digits_stmt(YangParser.Fraction_digits_stmtContext ctx);\r
+\r
+    void enterNotification_stmt(YangParser.Notification_stmtContext ctx);\r
+\r
+    void exitNotification_stmt(YangParser.Notification_stmtContext ctx);\r
+\r
+    void enterInput_stmt(YangParser.Input_stmtContext ctx);\r
+\r
+    void exitInput_stmt(YangParser.Input_stmtContext ctx);\r
+\r
+    void enterUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx);\r
+\r
+    void exitUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx);\r
+\r
+    void enterRefine_case_stmts(YangParser.Refine_case_stmtsContext ctx);\r
+\r
+    void exitRefine_case_stmts(YangParser.Refine_case_stmtsContext ctx);\r
+\r
+    void enterDecimal64_specification(\r
+            YangParser.Decimal64_specificationContext ctx);\r
+\r
+    void exitDecimal64_specification(\r
+            YangParser.Decimal64_specificationContext ctx);\r
+\r
+    void enterIf_feature_stmt(YangParser.If_feature_stmtContext ctx);\r
+\r
+    void exitIf_feature_stmt(YangParser.If_feature_stmtContext ctx);\r
+\r
+    void enterRevision_stmt(YangParser.Revision_stmtContext ctx);\r
+\r
+    void exitRevision_stmt(YangParser.Revision_stmtContext ctx);\r
+\r
+    void enterLength_stmt(YangParser.Length_stmtContext ctx);\r
+\r
+    void exitLength_stmt(YangParser.Length_stmtContext ctx);\r
+\r
+    void enterMust_stmt(YangParser.Must_stmtContext ctx);\r
+\r
+    void exitMust_stmt(YangParser.Must_stmtContext ctx);\r
+\r
+    void enterBody_stmts(YangParser.Body_stmtsContext ctx);\r
+\r
+    void exitBody_stmts(YangParser.Body_stmtsContext ctx);\r
+\r
+    void enterError_message_stmt(YangParser.Error_message_stmtContext ctx);\r
+\r
+    void exitError_message_stmt(YangParser.Error_message_stmtContext ctx);\r
+\r
+    void enterUnique_stmt(YangParser.Unique_stmtContext ctx);\r
+\r
+    void exitUnique_stmt(YangParser.Unique_stmtContext ctx);\r
+\r
+    void enterChoice_stmt(YangParser.Choice_stmtContext ctx);\r
+\r
+    void exitChoice_stmt(YangParser.Choice_stmtContext ctx);\r
+\r
+    void enterOutput_stmt(YangParser.Output_stmtContext ctx);\r
+\r
+    void exitOutput_stmt(YangParser.Output_stmtContext ctx);\r
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParserVisitor.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/antlrv4/code/gen/YangParserVisitor.java
new file mode 100644 (file)
index 0000000..38d6dfb
--- /dev/null
@@ -0,0 +1,227 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.antlrv4.code.gen;\r
+\r
+import org.antlr.v4.runtime.tree.ParseTreeVisitor;\r
+\r
+public interface YangParserVisitor<T> extends ParseTreeVisitor<T> {\r
+    T visitEnum_specification(YangParser.Enum_specificationContext ctx);\r
+\r
+    T visitRefine_leaf_list_stmts(YangParser.Refine_leaf_list_stmtsContext ctx);\r
+\r
+    T visitPosition_stmt(YangParser.Position_stmtContext ctx);\r
+\r
+    T visitArgument_stmt(YangParser.Argument_stmtContext ctx);\r
+\r
+    T visitLeafref_specification(YangParser.Leafref_specificationContext ctx);\r
+\r
+    T visitError_app_tag_stmt(YangParser.Error_app_tag_stmtContext ctx);\r
+\r
+    T visitData_def_stmt(YangParser.Data_def_stmtContext ctx);\r
+\r
+    T visitIdentity_stmt(YangParser.Identity_stmtContext ctx);\r
+\r
+    T visitDeviate_not_supported_stmt(\r
+            YangParser.Deviate_not_supported_stmtContext ctx);\r
+\r
+    T visitPrefix_stmt(YangParser.Prefix_stmtContext ctx);\r
+\r
+    T visitMeta_stmts(YangParser.Meta_stmtsContext ctx);\r
+\r
+    T visitLinkage_stmts(YangParser.Linkage_stmtsContext ctx);\r
+\r
+    T visitGrouping_stmt(YangParser.Grouping_stmtContext ctx);\r
+\r
+    T visitFeature_stmt(YangParser.Feature_stmtContext ctx);\r
+\r
+    T visitYang(YangParser.YangContext ctx);\r
+\r
+    T visitIdentityref_specification(\r
+            YangParser.Identityref_specificationContext ctx);\r
+\r
+    T visitNumerical_restrictions(YangParser.Numerical_restrictionsContext ctx);\r
+\r
+    T visitModule_header_stmts(YangParser.Module_header_stmtsContext ctx);\r
+\r
+    T visitRequire_instance_stmt(YangParser.Require_instance_stmtContext ctx);\r
+\r
+    T visitBit_stmt(YangParser.Bit_stmtContext ctx);\r
+\r
+    T visitType_stmt(YangParser.Type_stmtContext ctx);\r
+\r
+    T visitPattern_stmt(YangParser.Pattern_stmtContext ctx);\r
+\r
+    T visitDeviation_stmt(YangParser.Deviation_stmtContext ctx);\r
+\r
+    T visitDeviate_replace_stmt(YangParser.Deviate_replace_stmtContext ctx);\r
+\r
+    T visitKey_stmt(YangParser.Key_stmtContext ctx);\r
+\r
+    T visitRequire_instance_arg(YangParser.Require_instance_argContext ctx);\r
+\r
+    T visitLeaf_list_stmt(YangParser.Leaf_list_stmtContext ctx);\r
+\r
+    T visitAugment_stmt(YangParser.Augment_stmtContext ctx);\r
+\r
+    T visitDeviate_delete_stmt(YangParser.Deviate_delete_stmtContext ctx);\r
+\r
+    T visitTypedef_stmt(YangParser.Typedef_stmtContext ctx);\r
+\r
+    T visitContainer_stmt(YangParser.Container_stmtContext ctx);\r
+\r
+    T visitBelongs_to_stmt(YangParser.Belongs_to_stmtContext ctx);\r
+\r
+    T visitBase_stmt(YangParser.Base_stmtContext ctx);\r
+\r
+    T visitYang_version_stmt(YangParser.Yang_version_stmtContext ctx);\r
+\r
+    T visitReference_stmt(YangParser.Reference_stmtContext ctx);\r
+\r
+    T visitYin_element_stmt(YangParser.Yin_element_stmtContext ctx);\r
+\r
+    T visitLeaf_stmt(YangParser.Leaf_stmtContext ctx);\r
+\r
+    T visitCase_stmt(YangParser.Case_stmtContext ctx);\r
+\r
+    T visitModule_stmt(YangParser.Module_stmtContext ctx);\r
+\r
+    T visitRpc_stmt(YangParser.Rpc_stmtContext ctx);\r
+\r
+    T visitType_body_stmts(YangParser.Type_body_stmtsContext ctx);\r
+\r
+    T visitExtension_stmt(YangParser.Extension_stmtContext ctx);\r
+\r
+    T visitSubmodule_header_stmts(YangParser.Submodule_header_stmtsContext ctx);\r
+\r
+    T visitRefine_container_stmts(YangParser.Refine_container_stmtsContext ctx);\r
+\r
+    T visitValue_stmt(YangParser.Value_stmtContext ctx);\r
+\r
+    T visitRefine_list_stmts(YangParser.Refine_list_stmtsContext ctx);\r
+\r
+    T visitDefault_stmt(YangParser.Default_stmtContext ctx);\r
+\r
+    T visitRevision_stmts(YangParser.Revision_stmtsContext ctx);\r
+\r
+    T visitAnyxml_stmt(YangParser.Anyxml_stmtContext ctx);\r
+\r
+    T visitStatus_stmt(YangParser.Status_stmtContext ctx);\r
+\r
+    T visitContact_stmt(YangParser.Contact_stmtContext ctx);\r
+\r
+    T visitIdentifier_stmt(YangParser.Identifier_stmtContext ctx);\r
+\r
+    T visitString(YangParser.StringContext ctx);\r
+\r
+    T visitRefine_choice_stmts(YangParser.Refine_choice_stmtsContext ctx);\r
+\r
+    T visitMandatory_arg(YangParser.Mandatory_argContext ctx);\r
+\r
+    T visitRefine_stmt(YangParser.Refine_stmtContext ctx);\r
+\r
+    T visitInstance_identifier_specification(\r
+            YangParser.Instance_identifier_specificationContext ctx);\r
+\r
+    T visitBits_specification(YangParser.Bits_specificationContext ctx);\r
+\r
+    T visitWhen_stmt(YangParser.When_stmtContext ctx);\r
+\r
+    T visitString_restrictions(YangParser.String_restrictionsContext ctx);\r
+\r
+    T visitRefine_leaf_stmts(YangParser.Refine_leaf_stmtsContext ctx);\r
+\r
+    T visitMandatory_stmt(YangParser.Mandatory_stmtContext ctx);\r
+\r
+    T visitOrdered_by_arg(YangParser.Ordered_by_argContext ctx);\r
+\r
+    T visitMin_elements_stmt(YangParser.Min_elements_stmtContext ctx);\r
+\r
+    T visitStmtend(YangParser.StmtendContext ctx);\r
+\r
+    T visitRefine_anyxml_stmts(YangParser.Refine_anyxml_stmtsContext ctx);\r
+\r
+    T visitDescription_stmt(YangParser.Description_stmtContext ctx);\r
+\r
+    T visitPath_stmt(YangParser.Path_stmtContext ctx);\r
+\r
+    T visitInclude_stmt(YangParser.Include_stmtContext ctx);\r
+\r
+    T visitUnits_stmt(YangParser.Units_stmtContext ctx);\r
+\r
+    T visitUses_stmt(YangParser.Uses_stmtContext ctx);\r
+\r
+    T visitOrdered_by_stmt(YangParser.Ordered_by_stmtContext ctx);\r
+\r
+    T visitRange_stmt(YangParser.Range_stmtContext ctx);\r
+\r
+    T visitNamespace_stmt(YangParser.Namespace_stmtContext ctx);\r
+\r
+    T visitDeviate_add_stmt(YangParser.Deviate_add_stmtContext ctx);\r
+\r
+    T visitShort_case_stmt(YangParser.Short_case_stmtContext ctx);\r
+\r
+    T visitConfig_stmt(YangParser.Config_stmtContext ctx);\r
+\r
+    T visitEnum_stmt(YangParser.Enum_stmtContext ctx);\r
+\r
+    T visitYin_element_arg(YangParser.Yin_element_argContext ctx);\r
+\r
+    T visitOrganization_stmt(YangParser.Organization_stmtContext ctx);\r
+\r
+    T visitUnion_specification(YangParser.Union_specificationContext ctx);\r
+\r
+    T visitMax_value_arg(YangParser.Max_value_argContext ctx);\r
+\r
+    T visitSubmodule_stmt(YangParser.Submodule_stmtContext ctx);\r
+\r
+    T visitStatus_arg(YangParser.Status_argContext ctx);\r
+\r
+    T visitList_stmt(YangParser.List_stmtContext ctx);\r
+\r
+    T visitMax_elements_stmt(YangParser.Max_elements_stmtContext ctx);\r
+\r
+    T visitImport_stmt(YangParser.Import_stmtContext ctx);\r
+\r
+    T visitConfig_arg(YangParser.Config_argContext ctx);\r
+\r
+    T visitRevision_date_stmt(YangParser.Revision_date_stmtContext ctx);\r
+\r
+    T visitRefune_pom(YangParser.Refune_pomContext ctx);\r
+\r
+    T visitPresence_stmt(YangParser.Presence_stmtContext ctx);\r
+\r
+    T visitFraction_digits_stmt(YangParser.Fraction_digits_stmtContext ctx);\r
+\r
+    T visitNotification_stmt(YangParser.Notification_stmtContext ctx);\r
+\r
+    T visitInput_stmt(YangParser.Input_stmtContext ctx);\r
+\r
+    T visitUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx);\r
+\r
+    T visitRefine_case_stmts(YangParser.Refine_case_stmtsContext ctx);\r
+\r
+    T visitDecimal64_specification(YangParser.Decimal64_specificationContext ctx);\r
+\r
+    T visitIf_feature_stmt(YangParser.If_feature_stmtContext ctx);\r
+\r
+    T visitRevision_stmt(YangParser.Revision_stmtContext ctx);\r
+\r
+    T visitLength_stmt(YangParser.Length_stmtContext ctx);\r
+\r
+    T visitMust_stmt(YangParser.Must_stmtContext ctx);\r
+\r
+    T visitBody_stmts(YangParser.Body_stmtsContext ctx);\r
+\r
+    T visitError_message_stmt(YangParser.Error_message_stmtContext ctx);\r
+\r
+    T visitUnique_stmt(YangParser.Unique_stmtContext ctx);\r
+\r
+    T visitChoice_stmt(YangParser.Choice_stmtContext ctx);\r
+\r
+    T visitOutput_stmt(YangParser.Output_stmtContext ctx);\r
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/AbstractChildNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/AbstractChildNodeBuilder.java
new file mode 100644 (file)
index 0000000..cc950ec
--- /dev/null
@@ -0,0 +1,40 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.api;\r
+\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+public abstract class AbstractChildNodeBuilder implements ChildNodeBuilder {\r
+\r
+    private final QName qname;\r
+    protected final Set<DataSchemaNodeBuilder> childNodes = new HashSet<DataSchemaNodeBuilder>();\r
+    protected final Set<GroupingBuilder> groupings = new HashSet<GroupingBuilder>();\r
+\r
+    protected AbstractChildNodeBuilder(QName qname) {\r
+        this.qname = qname;\r
+    }\r
+\r
+    @Override\r
+    public QName getQName() {\r
+        return qname;\r
+    }\r
+\r
+    @Override\r
+    public void addChildNode(DataSchemaNodeBuilder childNode) {\r
+        childNodes.add(childNode);\r
+    }\r
+\r
+    @Override\r
+    public void addGrouping(GroupingBuilder grouping) {\r
+        groupings.add(grouping);\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/AugmentationSchemaBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/AugmentationSchemaBuilder.java
new file mode 100644 (file)
index 0000000..fe2fc0e
--- /dev/null
@@ -0,0 +1,26 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.api;\r
+\r
+import org.opendaylight.controller.yang.model.api.AugmentationSchema;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+/**\r
+ * Interface for builders of 'augment' statement.\r
+ */\r
+public interface AugmentationSchemaBuilder extends ChildNodeBuilder, TypeDefinitionAwareBuilder {\r
+\r
+       void setDescription(String description);\r
+       void setReference(String reference);\r
+       void setStatus(Status status);\r
+\r
+       AugmentationSchema build();\r
+       SchemaPath getTargetPath();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/AugmentationTargetBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/AugmentationTargetBuilder.java
new file mode 100644 (file)
index 0000000..bd71a8a
--- /dev/null
@@ -0,0 +1,23 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.api;\r
+\r
+import org.opendaylight.controller.yang.model.api.AugmentationSchema;\r
+\r
+/**\r
+ * Interface for builders of those nodes, which can be augmentation targets.\r
+ */\r
+public interface AugmentationTargetBuilder {\r
+\r
+       /**\r
+        * Add augment, which points to this node.\r
+        * @param augment augment which points to this node\r
+        */\r
+       void addAugmentation(AugmentationSchema augment);\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/Builder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/Builder.java
new file mode 100644 (file)
index 0000000..fede31f
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.model.parser.api;
+
+/**
+ * Parent interface for all builder interfaces.
+ */
+public interface Builder {
+
+       Object build();
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/ChildNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/ChildNodeBuilder.java
new file mode 100644 (file)
index 0000000..0f60154
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.api;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+/**\r
+ * Interface for all yang data-node containers [augment, case, container, grouping, list, module, notification].\r
+ */\r
+public interface ChildNodeBuilder extends Builder {\r
+\r
+       QName getQName();\r
+       void addChildNode(DataSchemaNodeBuilder childNode);\r
+       void addGrouping(GroupingBuilder groupingBuilder);\r
+       void addUsesNode(UsesNodeBuilder usesBuilder);\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/DataSchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/DataSchemaNodeBuilder.java
new file mode 100644 (file)
index 0000000..1eaf1af
--- /dev/null
@@ -0,0 +1,21 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.api;\r
+\r
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;\r
+\r
+/**\r
+ * Interface for all yang data-schema nodes [anyxml, case, container, grouping, list, module, notification].\r
+ */\r
+public interface DataSchemaNodeBuilder extends SchemaNodeBuilder {\r
+\r
+       DataSchemaNode build();\r
+       void setAugmenting(boolean augmenting);\r
+       void setConfiguration(boolean configuration);\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/GroupingBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/GroupingBuilder.java
new file mode 100644 (file)
index 0000000..22632ab
--- /dev/null
@@ -0,0 +1,19 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.api;\r
+\r
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;\r
+\r
+/**\r
+ * Interface for builders of 'grouping' statement.\r
+ */\r
+public interface GroupingBuilder extends ChildNodeBuilder, SchemaNodeBuilder, TypeDefinitionAwareBuilder {\r
+\r
+       GroupingDefinition build();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/SchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/SchemaNodeBuilder.java
new file mode 100644 (file)
index 0000000..c63104e
--- /dev/null
@@ -0,0 +1,26 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.api;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+\r
+/**\r
+ * Interface for all builders of SchemaNode nodes.\r
+ */\r
+public interface SchemaNodeBuilder extends Builder {\r
+\r
+       QName getQName();\r
+       void setPath(SchemaPath schemaPath);\r
+       void setDescription(String description);\r
+       void setReference(String reference);\r
+       void setStatus(Status status);\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/TypeAwareBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/TypeAwareBuilder.java
new file mode 100644 (file)
index 0000000..64ccb11
--- /dev/null
@@ -0,0 +1,21 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.api;\r
+\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+/**\r
+ * Builders of all nodes, which can have 'type' statement must implement this interface.\r
+ * [typedef, type, leaf, leaf-list, deviate]\r
+ */\r
+public interface TypeAwareBuilder {\r
+\r
+       TypeDefinition<?> getType();\r
+       void setType(TypeDefinition<?> type);\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/TypeDefinitionAwareBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/TypeDefinitionAwareBuilder.java
new file mode 100644 (file)
index 0000000..bfa9a10
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.model.parser.api;
+
+/**
+ * Builders of all nodes, which can have 'typedef' statement must implement this interface.
+ * [module, submodule, container, list, grouping, rpc, input, output, notification]
+ */
+public interface TypeDefinitionAwareBuilder {
+
+       void addTypedef(TypeDefinitionBuilder typedefBuilder);
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/TypeDefinitionBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/TypeDefinitionBuilder.java
new file mode 100644 (file)
index 0000000..9a7b97e
--- /dev/null
@@ -0,0 +1,23 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.api;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+\r
+/**\r
+ * Interface for builders of 'typedef' statement.\r
+ */\r
+public interface TypeDefinitionBuilder {\r
+\r
+       QName getQName();\r
+       TypeDefinition<?> getBaseType();\r
+       TypeDefinition<?> build();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/UsesNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/api/UsesNodeBuilder.java
new file mode 100644 (file)
index 0000000..13ecd15
--- /dev/null
@@ -0,0 +1,21 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.api;\r
+\r
+import org.opendaylight.controller.yang.model.api.UsesNode;\r
+\r
+/**\r
+ * Interface for builders of 'uses' statement.\r
+ */\r
+public interface UsesNodeBuilder {\r
+\r
+    void addAugment(AugmentationSchemaBuilder builder);\r
+\r
+    UsesNode build();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/AugmentationSchemaBuilderImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/AugmentationSchemaBuilderImpl.java
new file mode 100644 (file)
index 0000000..2ece5a0
--- /dev/null
@@ -0,0 +1,306 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.model.parser.api.AugmentationSchemaBuilder;\r
+import org.opendaylight.controller.model.parser.api.DataSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.GroupingBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeDefinitionBuilder;\r
+import org.opendaylight.controller.model.parser.api.UsesNodeBuilder;\r
+import org.opendaylight.controller.model.parser.util.YangModelBuilderHelper;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.AugmentationSchema;\r
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+import org.opendaylight.controller.yang.model.api.UsesNode;\r
+\r
+\r
+public class AugmentationSchemaBuilderImpl implements AugmentationSchemaBuilder {\r
+\r
+       private final AugmentationSchemaImpl instance;\r
+       private final SchemaPath augmentTarget;\r
+       final Set<DataSchemaNodeBuilder> childNodes = new HashSet<DataSchemaNodeBuilder>();\r
+       final Set<GroupingBuilder> groupings = new HashSet<GroupingBuilder>();\r
+       private final Set<UsesNodeBuilder> usesNodes = new HashSet<UsesNodeBuilder>();\r
+\r
+       AugmentationSchemaBuilderImpl(String augmentPath) {\r
+               SchemaPath targetPath = YangModelBuilderHelper.parsePath(augmentPath);\r
+               augmentTarget = targetPath;\r
+               instance = new AugmentationSchemaImpl(targetPath);\r
+       }\r
+\r
+       @Override\r
+       public void addChildNode(DataSchemaNodeBuilder childNode) {\r
+               childNodes.add(childNode);\r
+       }\r
+\r
+       @Override\r
+       public void addGrouping(GroupingBuilder grouping) {\r
+               groupings.add(grouping);\r
+       }\r
+\r
+       /**\r
+        * Always returns null.\r
+        */\r
+       @Override\r
+       public QName getQName() {\r
+               return null;\r
+       }\r
+\r
+       @Override\r
+       public AugmentationSchema build() {\r
+\r
+               // CHILD NODES\r
+               Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();\r
+               for(DataSchemaNodeBuilder node : childNodes) {\r
+                       childs.put(node.getQName(), node.build());\r
+               }\r
+               instance.setChildNodes(childs);\r
+\r
+               // GROUPINGS\r
+               Set<GroupingDefinition> groupingDefinitions = new HashSet<GroupingDefinition>();\r
+               for(GroupingBuilder builder : groupings) {\r
+                       groupingDefinitions.add(builder.build());\r
+               }\r
+               instance.setGroupings(groupingDefinitions);\r
+\r
+               // USES\r
+               Set<UsesNode> usesNodeDefinitions = new HashSet<UsesNode>();\r
+               for(UsesNodeBuilder builder : usesNodes) {\r
+                       usesNodeDefinitions.add(builder.build());\r
+               }\r
+               instance.setUses(usesNodeDefinitions);\r
+\r
+               return instance;\r
+       }\r
+\r
+       @Override\r
+       public void addUsesNode(UsesNodeBuilder usesBuilder) {\r
+               usesNodes.add(usesBuilder);\r
+       }\r
+\r
+       @Override\r
+       public void addTypedef(TypeDefinitionBuilder type) {\r
+               throw new UnsupportedOperationException("Augmentation can not contains type definitions");\r
+       }\r
+\r
+       @Override\r
+       public void setDescription(String description) {\r
+               instance.setDescription(description);\r
+       }\r
+\r
+       @Override\r
+       public void setReference(String reference) {\r
+               instance.setReference(reference);\r
+       }\r
+\r
+       @Override\r
+       public void setStatus(Status status) {\r
+               instance.setStatus(status);\r
+       }\r
+\r
+       @Override\r
+       public SchemaPath getTargetPath() {\r
+               return augmentTarget;\r
+       }\r
+\r
+\r
+       private static class AugmentationSchemaImpl implements AugmentationSchema {\r
+\r
+               private final SchemaPath targetPath;\r
+               private Map<QName, DataSchemaNode> childNodes;\r
+               private Set<GroupingDefinition> groupings;\r
+               private Set<UsesNode> uses;\r
+\r
+               private String description;\r
+               private String reference;\r
+               private Status status;\r
+\r
+               private AugmentationSchemaImpl(SchemaPath targetPath) {\r
+                       this.targetPath = targetPath;\r
+               }\r
+\r
+\r
+               @Override\r
+               public SchemaPath getTargetPath() {\r
+                       return targetPath;\r
+               }\r
+\r
+               @Override\r
+               public Set<DataSchemaNode> getChildNodes() {\r
+                       return new HashSet<DataSchemaNode>(childNodes.values());\r
+               }\r
+               private void setChildNodes(Map<QName, DataSchemaNode> childNodes) {\r
+                       this.childNodes = childNodes;\r
+               }\r
+\r
+               @Override\r
+               public Set<GroupingDefinition> getGroupings() {\r
+                       return groupings;\r
+               }\r
+               private void setGroupings(Set<GroupingDefinition> groupings) {\r
+                       this.groupings = groupings;\r
+               }\r
+\r
+               @Override\r
+               public Set<UsesNode> getUses() {\r
+                       return uses;\r
+               }\r
+               private void setUses(Set<UsesNode> uses) {\r
+                       this.uses = uses;\r
+               }\r
+\r
+               /**\r
+                * This method always returns null, because augmentation can not contains type definitions.\r
+                */\r
+               @Override\r
+               public Set<TypeDefinition<?>> getTypeDefinitions() {\r
+                       return null;\r
+               }\r
+\r
+               @Override\r
+               public String getDescription() {\r
+                       return description;\r
+               }\r
+               private void setDescription(String description) {\r
+                       this.description = description;\r
+               }\r
+\r
+               @Override\r
+               public String getReference() {\r
+                       return reference;\r
+               }\r
+               private void setReference(String reference) {\r
+                       this.reference = reference;\r
+               }\r
+\r
+               @Override\r
+               public Status getStatus() {\r
+                       return status;\r
+               }\r
+               private void setStatus(Status status) {\r
+                       this.status = status;\r
+               }\r
+\r
+               @Override\r
+               public DataSchemaNode getDataChildByName(QName name) {\r
+                       return childNodes.get(name);\r
+               }\r
+\r
+               @Override\r
+               public DataSchemaNode getDataChildByName(String name) {\r
+                       DataSchemaNode result = null;\r
+                       for(Map.Entry<QName, DataSchemaNode> entry : childNodes.entrySet()) {\r
+                               if(entry.getKey().getLocalName().equals(name)) {\r
+                                       result = entry.getValue();\r
+                                       break;\r
+                               }\r
+                       }\r
+                       return result;\r
+               }\r
+\r
+               @Override\r
+               public int hashCode() {\r
+                       final int prime = 17;\r
+            int result = 1;\r
+            result = prime * result + ((targetPath == null) ? 0 : targetPath.hashCode());\r
+            result = prime * result + ((childNodes == null) ? 0 : childNodes.hashCode());\r
+            result = prime * result + ((groupings == null) ? 0 : groupings.hashCode());\r
+            result = prime * result + ((uses == null) ? 0 : uses.hashCode());\r
+            result = prime * result + ((description == null) ? 0 : description.hashCode());\r
+            result = prime * result + ((reference == null) ? 0 : reference.hashCode());\r
+            result = prime * result + ((status == null) ? 0 : status.hashCode());\r
+            return result;\r
+               }\r
+\r
+               @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj) {\r
+                return true;\r
+            }\r
+            if (obj == null) {\r
+                return false;\r
+            }\r
+            if (getClass() != obj.getClass()) {\r
+                return false;\r
+            }\r
+            AugmentationSchemaImpl other = (AugmentationSchemaImpl) obj;\r
+            if (targetPath == null) {\r
+                if (other.targetPath != null) {\r
+                    return false;\r
+                }\r
+            } else if (!targetPath.equals(other.targetPath)) {\r
+                return false;\r
+            }\r
+            if (childNodes == null) {\r
+                if (other.childNodes != null) {\r
+                    return false;\r
+                }\r
+            } else if (!childNodes.equals(other.childNodes)) {\r
+                return false;\r
+            }\r
+            if (groupings == null) {\r
+                if (other.groupings != null) {\r
+                    return false;\r
+                }\r
+            } else if (!groupings.equals(other.groupings)) {\r
+                return false;\r
+            }\r
+            if (uses == null) {\r
+                if (other.uses != null) {\r
+                    return false;\r
+                }\r
+            } else if (!uses.equals(other.uses)) {\r
+                return false;\r
+            }\r
+            if (description == null) {\r
+                if (other.description != null) {\r
+                    return false;\r
+                }\r
+            } else if (!description.equals(other.description)) {\r
+                return false;\r
+            }\r
+            if (reference == null) {\r
+                if (other.reference != null) {\r
+                    return false;\r
+                }\r
+            } else if (!reference.equals(other.reference)) {\r
+                return false;\r
+            }\r
+            if (status == null) {\r
+                if (other.status != null) {\r
+                    return false;\r
+                }\r
+            } else if (!status.equals(other.status)) {\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
+\r
+               @Override\r
+               public String toString() {\r
+                       StringBuilder sb = new StringBuilder(AugmentationSchemaImpl.class.getSimpleName());\r
+                       sb.append("[");\r
+                       sb.append("targetPath="+ targetPath);\r
+                       sb.append(", childNodes="+ childNodes.values());\r
+                       sb.append(", groupings="+ groupings);\r
+                       sb.append(", uses="+ uses);\r
+                       sb.append("]");\r
+                       return sb.toString();\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/ContainerSchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/ContainerSchemaNodeBuilder.java
new file mode 100644 (file)
index 0000000..1651bfc
--- /dev/null
@@ -0,0 +1,468 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.model.parser.api.AbstractChildNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.AugmentationTargetBuilder;\r
+import org.opendaylight.controller.model.parser.api.DataSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.GroupingBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeDefinitionAwareBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeDefinitionBuilder;\r
+import org.opendaylight.controller.model.parser.api.UsesNodeBuilder;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.AugmentationSchema;\r
+import org.opendaylight.controller.yang.model.api.ConstraintDefinition;\r
+import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;\r
+import org.opendaylight.controller.yang.model.api.MustDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+import org.opendaylight.controller.yang.model.api.UsesNode;\r
+\r
+\r
+public class ContainerSchemaNodeBuilder extends AbstractChildNodeBuilder implements TypeDefinitionAwareBuilder, MustAwareBuilder, AugmentationTargetBuilder, DataSchemaNodeBuilder {\r
+\r
+       private final ContainerSchemaNodeImpl instance;\r
+\r
+       private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();\r
+       private final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();\r
+       private final Set<UsesNodeBuilder> addedUsesNodes = new HashSet<UsesNodeBuilder>();\r
+       private MustDefinitionBuilder mustDefinitionBuilder;\r
+\r
+       ContainerSchemaNodeBuilder(QName qname) {\r
+               super(qname);\r
+               instance = new ContainerSchemaNodeImpl(qname);\r
+       }\r
+\r
+       @Override\r
+       public ContainerSchemaNode build() {\r
+               // CHILD NODES\r
+               Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();\r
+               for (DataSchemaNodeBuilder node : childNodes) {\r
+                       childs.put(node.getQName(), node.build());\r
+               }\r
+               instance.setChildNodes(childs);\r
+\r
+               // GROUPINGS\r
+               Set<GroupingDefinition> groupingDefinitions = new HashSet<GroupingDefinition>();\r
+               for (GroupingBuilder builder : groupings) {\r
+                       groupingDefinitions.add(builder.build());\r
+               }\r
+               instance.setGroupings(groupingDefinitions);\r
+\r
+               // TYPEDEFS\r
+               Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();\r
+               for(TypeDefinitionBuilder entry : addedTypedefs) {\r
+                       typedefs.add(entry.build());\r
+               }\r
+               instance.setTypeDefinitions(typedefs);\r
+\r
+               // USES\r
+               Set<UsesNode> uses = new HashSet<UsesNode>();\r
+               for (UsesNodeBuilder builder : addedUsesNodes) {\r
+                       uses.add(builder.build());\r
+               }\r
+               instance.setUses(uses);\r
+\r
+               // MUST definition\r
+               if(mustDefinitionBuilder != null) {\r
+                       MustDefinition md = mustDefinitionBuilder.build();\r
+                       instance.setMustStatement(md);\r
+               }\r
+\r
+               instance.setAvailableAugmentations(augmentations);\r
+\r
+               return instance;\r
+       }\r
+\r
+\r
+       @Override\r
+       public void addTypedef(TypeDefinitionBuilder type) {\r
+               addedTypedefs.add(type);\r
+       }\r
+\r
+       @Override\r
+       public void addAugmentation(AugmentationSchema augment) {\r
+               augmentations.add(augment);\r
+       }\r
+\r
+       @Override\r
+       public void setPath(SchemaPath schemaPath) {\r
+               instance.setPath(schemaPath);\r
+       }\r
+\r
+       @Override\r
+       public void setDescription(String description) {\r
+               instance.setDescription(description);\r
+       }\r
+\r
+       @Override\r
+       public void setReference(String reference) {\r
+               instance.setReference(reference);\r
+       }\r
+\r
+       @Override\r
+       public void setStatus(Status status) {\r
+               instance.setStatus(status);\r
+       }\r
+\r
+       @Override\r
+       public void setAugmenting(boolean augmenting) {\r
+               instance.setAugmenting(augmenting);\r
+       }\r
+\r
+       @Override\r
+       public void setConfiguration(boolean configuration) {\r
+               instance.setConfiguration(configuration);\r
+       }\r
+\r
+       public void setConstraints(ConstraintDefinition constraints) {\r
+               instance.setConstraints(constraints);\r
+       }\r
+\r
+       @Override\r
+       public void addUsesNode(UsesNodeBuilder usesNodeBuilder) {\r
+               addedUsesNodes.add(usesNodeBuilder);\r
+       }\r
+\r
+       public void setPresenceContainer(boolean presence) {\r
+               instance.setPresenceContainer(presence);\r
+       }\r
+\r
+       @Override\r
+       public void setMustDefinitionBuilder(MustDefinitionBuilder mustDefinitionBuilder) {\r
+               this.mustDefinitionBuilder = mustDefinitionBuilder;\r
+       }\r
+\r
+\r
+       private class ContainerSchemaNodeImpl implements ContainerSchemaNode {\r
+\r
+               private final QName qname;\r
+               private SchemaPath path;\r
+               private String description;\r
+               private String reference;\r
+               private Status status = Status.CURRENT;\r
+\r
+               private boolean augmenting;\r
+               private boolean configuration;\r
+               private ConstraintDefinition constraints;\r
+\r
+               private Set<AugmentationSchema> augmentations;\r
+\r
+               private Map<QName, DataSchemaNode> childNodes;\r
+               private Set<GroupingDefinition> groupings;\r
+               private Set<TypeDefinition<?>> typeDefinitions;\r
+\r
+               private Set<UsesNode> uses;\r
+               private boolean presence;\r
+\r
+               private MustDefinition mustDefinition;\r
+\r
+               private ContainerSchemaNodeImpl(QName qname) {\r
+                       this.qname = qname;\r
+               }\r
+\r
+               @Override\r
+               public QName getQName() {\r
+                       return qname;\r
+               }\r
+\r
+               @Override\r
+               public SchemaPath getPath() {\r
+                       return path;\r
+               }\r
+               private void setPath(SchemaPath path) {\r
+                       this.path = path;\r
+               }\r
+\r
+               @Override\r
+               public String getDescription() {\r
+                       return description;\r
+               }\r
+               private void setDescription(String description) {\r
+                       this.description = description;\r
+               }\r
+\r
+               @Override\r
+               public String getReference() {\r
+                       return reference;\r
+               }\r
+               private void setReference(String reference) {\r
+                       this.reference = reference;\r
+               }\r
+\r
+               @Override\r
+               public Status getStatus() {\r
+                       return status;\r
+               }\r
+               private void setStatus(Status status) {\r
+                       this.status = status;\r
+               }\r
+\r
+               @Override\r
+               public boolean isAugmenting() {\r
+                       return augmenting;\r
+               }\r
+               private void setAugmenting(boolean augmenting) {\r
+                       this.augmenting = augmenting;\r
+               }\r
+\r
+               @Override\r
+               public boolean isConfiguration() {\r
+                       return configuration;\r
+               }\r
+               private void setConfiguration(boolean configuration) {\r
+                       this.configuration = configuration;\r
+               }\r
+\r
+               @Override\r
+               public ConstraintDefinition getConstraints() {\r
+                       return constraints;\r
+               }\r
+               private void setConstraints(ConstraintDefinition constraints) {\r
+                       this.constraints = constraints;\r
+               }\r
+\r
+               @Override\r
+               public Set<AugmentationSchema> getAvailableAugmentations() {\r
+                       return augmentations;\r
+               }\r
+               private void setAvailableAugmentations(\r
+                               Set<AugmentationSchema> augmentations) {\r
+                       this.augmentations = augmentations;\r
+               }\r
+\r
+               @Override\r
+               public Set<DataSchemaNode> getChildNodes() {\r
+                       return new HashSet<DataSchemaNode>(childNodes.values());\r
+               }\r
+               private void setChildNodes(Map<QName, DataSchemaNode> childNodes) {\r
+                       this.childNodes = childNodes;\r
+               }\r
+\r
+               @Override\r
+               public Set<GroupingDefinition> getGroupings() {\r
+                       return groupings;\r
+               }\r
+               private void setGroupings(Set<GroupingDefinition> groupings) {\r
+                       this.groupings = groupings;\r
+               }\r
+\r
+               @Override\r
+               public DataSchemaNode getDataChildByName(QName name) {\r
+                       return childNodes.get(name);\r
+               }\r
+\r
+               @Override\r
+               public DataSchemaNode getDataChildByName(String name) {\r
+                       DataSchemaNode result = null;\r
+                       for (Map.Entry<QName, DataSchemaNode> entry : childNodes.entrySet()) {\r
+                               if (entry.getKey().getLocalName().equals(name)) {\r
+                                       result = entry.getValue();\r
+                                       break;\r
+                               }\r
+                       }\r
+                       return result;\r
+               }\r
+\r
+               @Override\r
+               public Set<UsesNode> getUses() {\r
+                       return uses;\r
+               }\r
+\r
+               private void setUses(Set<UsesNode> uses) {\r
+                       this.uses = uses;\r
+               }\r
+\r
+               @Override\r
+               public boolean isPresenceContainer() {\r
+                       return presence;\r
+               }\r
+\r
+               private void setPresenceContainer(boolean presence) {\r
+                       this.presence = presence;\r
+               }\r
+\r
+               @Override\r
+               public MustDefinition getMustDefinition() {\r
+                       return mustDefinition;\r
+               }\r
+               private void setMustStatement(MustDefinition mustDefinition) {\r
+                       this.mustDefinition = mustDefinition;\r
+               }\r
+\r
+               @Override\r
+               public Set<TypeDefinition<?>> getTypeDefinitions() {\r
+                       return typeDefinitions;\r
+               }\r
+               private void setTypeDefinitions(Set<TypeDefinition<?>> typeDefinitions) {\r
+                       this.typeDefinitions = typeDefinitions;\r
+               }\r
+\r
+               @Override\r
+               public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+                       // TODO Auto-generated method stub\r
+                       return null;\r
+               }\r
+\r
+\r
+               @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result + ((qname == null) ? 0 : qname.hashCode());\r
+            result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+            result = prime * result + ((description == null) ? 0 : description.hashCode());\r
+            result = prime * result + ((reference == null) ? 0 : reference.hashCode());\r
+            result = prime * result + ((status == null) ? 0 : status.hashCode());\r
+            result = prime * result + (augmenting ? 1231 : 1237);\r
+            result = prime * result + (configuration ? 1231 : 1237);\r
+            result = prime * result + ((constraints == null) ? 0 : constraints.hashCode());\r
+            result = prime * result + ((augmentations == null) ? 0 : augmentations.hashCode());\r
+            result = prime * result + ((childNodes == null) ? 0 : childNodes.hashCode());\r
+            result = prime * result + ((groupings == null) ? 0 : groupings.hashCode());\r
+            result = prime * result + ((uses == null) ? 0 : uses.hashCode());\r
+            result = prime * result + (presence ? 1231 : 1237);\r
+            result = prime * result + ((mustDefinition == null) ? 0 : mustDefinition.hashCode());\r
+            return result;\r
+        }\r
+\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj) {\r
+                return true;\r
+            }\r
+            if (obj == null) {\r
+                return false;\r
+            }\r
+            if (getClass() != obj.getClass()) {\r
+                return false;\r
+            }\r
+            ContainerSchemaNodeImpl other = (ContainerSchemaNodeImpl) obj;\r
+            if (qname == null) {\r
+                if (other.qname != null) {\r
+                    return false;\r
+                }\r
+            } else if (!qname.equals(other.qname)) {\r
+                return false;\r
+            }\r
+            if (path == null) {\r
+                if (other.path != null) {\r
+                    return false;\r
+                }\r
+            } else if (!path.equals(other.path)) {\r
+                return false;\r
+            }\r
+            if (description == null) {\r
+                if (other.description != null) {\r
+                    return false;\r
+                }\r
+            } else if (!description.equals(other.description)) {\r
+                return false;\r
+            }\r
+            if (reference == null) {\r
+                if (other.reference != null) {\r
+                    return false;\r
+                }\r
+            } else if (!reference.equals(other.reference)) {\r
+                return false;\r
+            }\r
+            if (status == null) {\r
+                if (other.status != null) {\r
+                    return false;\r
+                }\r
+            } else if (!status.equals(other.status)) {\r
+                return false;\r
+            }\r
+            if(augmenting != other.augmenting) {\r
+               return false;\r
+            }\r
+            if(configuration != other.configuration) {\r
+               return false;\r
+            }\r
+            if (constraints == null) {\r
+                if (other.constraints != null) {\r
+                    return false;\r
+                }\r
+            } else if (!constraints.equals(other.constraints)) {\r
+                return false;\r
+            }\r
+            if (augmentations == null) {\r
+                if (other.augmentations != null) {\r
+                    return false;\r
+                }\r
+            } else if (!augmentations.equals(other.augmentations)) {\r
+                return false;\r
+            }\r
+            if (childNodes == null) {\r
+                if (other.childNodes != null) {\r
+                    return false;\r
+                }\r
+            } else if (!childNodes.equals(other.childNodes)) {\r
+                return false;\r
+            }\r
+            if (groupings == null) {\r
+                if (other.groupings != null) {\r
+                    return false;\r
+                }\r
+            } else if (!groupings.equals(other.groupings)) {\r
+                return false;\r
+            }\r
+            if (uses == null) {\r
+                if (other.uses != null) {\r
+                    return false;\r
+                }\r
+            } else if (!uses.equals(other.uses)) {\r
+                return false;\r
+            }\r
+               if(presence != other.presence) {\r
+               return false;\r
+            }\r
+               if (mustDefinition == null) {\r
+                if (other.mustDefinition != null) {\r
+                    return false;\r
+                }\r
+            } else if (!mustDefinition.equals(other.mustDefinition)) {\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
+\r
+               @Override\r
+               public String toString() {\r
+                       StringBuilder sb = new StringBuilder(\r
+                                       ContainerSchemaNodeImpl.class.getSimpleName());\r
+                       sb.append("[");\r
+                       sb.append("qname=" + qname);\r
+                       sb.append(", path=" + path);\r
+                       sb.append(", description=" + description);\r
+                       sb.append(", reference=" + reference);\r
+                       sb.append(", status=" + status);\r
+                       sb.append(", augmenting=" + augmenting);\r
+                       sb.append(", constraints=" + constraints);\r
+                       sb.append(", augmentations=" + augmentations);\r
+                       sb.append(", childNodes=" + childNodes.values());\r
+                       sb.append(", groupings=" + groupings);\r
+                       sb.append(", uses=" + uses);\r
+                       sb.append(", presence=" + presence);\r
+                       sb.append(", mustDefinition="+ mustDefinition);\r
+                       sb.append("]");\r
+                       return sb.toString();\r
+               }\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/DeviationBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/DeviationBuilder.java
new file mode 100644 (file)
index 0000000..abc6198
--- /dev/null
@@ -0,0 +1,108 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import org.opendaylight.controller.model.parser.api.Builder;\r
+import org.opendaylight.controller.model.parser.util.YangModelBuilderHelper;\r
+import org.opendaylight.controller.yang.model.api.Deviation;\r
+import org.opendaylight.controller.yang.model.api.MustDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Deviation.Deviate;\r
+\r
+\r
+public class DeviationBuilder implements MustAwareBuilder, Builder {\r
+\r
+       private final DeviationImpl instance;\r
+       private MustDefinitionBuilder mustDefinitionBuilder;\r
+\r
+       DeviationBuilder(String targetPathStr) {\r
+               SchemaPath targetPath = YangModelBuilderHelper.parsePath(targetPathStr);\r
+               instance = new DeviationImpl(targetPath);\r
+       }\r
+\r
+       @Override\r
+       public Deviation build() {\r
+               // MUST definition\r
+               if(mustDefinitionBuilder != null) {\r
+                       MustDefinition md = mustDefinitionBuilder.build();\r
+                       instance.setMustDefinition(md);\r
+               }\r
+               return instance;\r
+       }\r
+\r
+       public void setDeviate(String deviate) {\r
+               if(deviate.equals("not-supported")) {\r
+                       instance.setDeviate(Deviate.NOT_SUPPORTED);\r
+               } else if(deviate.equals("add")) {\r
+                       instance.setDeviate(Deviate.ADD);\r
+               } else if(deviate.equals("replace")) {\r
+                       instance.setDeviate(Deviate.REPLACE);\r
+               } else if(deviate.equals("delete")) {\r
+                       instance.setDeviate(Deviate.DELETE);\r
+               } else {\r
+                       throw new IllegalArgumentException("Unsupported type of 'deviate' statement: "+ deviate);\r
+               }\r
+       }\r
+\r
+       public void setReference(String reference) {\r
+               instance.setReference(reference);\r
+       }\r
+\r
+       @Override\r
+       public void setMustDefinitionBuilder(MustDefinitionBuilder mustDefinitionBuilder) {\r
+               this.mustDefinitionBuilder = mustDefinitionBuilder;\r
+       }\r
+\r
+       private static class DeviationImpl implements Deviation {\r
+\r
+               private SchemaPath targetPath;\r
+               private Deviate deviate;\r
+               private String reference;\r
+               private MustDefinition mustDefinition;\r
+\r
+               private DeviationImpl(SchemaPath targetPath) {\r
+                       this.targetPath = targetPath;\r
+               }\r
+\r
+               @Override\r
+               public SchemaPath getTargetPath() {\r
+                       return targetPath;\r
+               }\r
+\r
+               @Override\r
+               public Deviate getDeviate() {\r
+                       return deviate;\r
+               }\r
+               private void setDeviate(Deviate deviate) {\r
+                       this.deviate = deviate;\r
+               }\r
+\r
+               @Override\r
+               public String getReference() {\r
+                       return reference;\r
+               }\r
+               private void setReference(String reference) {\r
+                       this.reference = reference;\r
+               }\r
+\r
+               @Override\r
+               public String toString() {\r
+                       return DeviationImpl.class.getSimpleName() +"[targetPath="+ targetPath +", deviate="+ deviate +", reference="+ reference +", mustDefinition="+ mustDefinition +"]";\r
+               }\r
+\r
+               @Override\r
+               public MustDefinition getMustDefinition() {\r
+                       return mustDefinition;\r
+               }\r
+               private void setMustDefinition(MustDefinition mustDefinition) {\r
+                       this.mustDefinition = mustDefinition;\r
+               }\r
+\r
+       }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/FeatureBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/FeatureBuilder.java
new file mode 100644 (file)
index 0000000..e91d2fb
--- /dev/null
@@ -0,0 +1,190 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.parser.api.SchemaNodeBuilder;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.FeatureDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaNode;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+\r
+public class FeatureBuilder implements SchemaNodeBuilder {\r
+\r
+       private final FeatureDefinitionImpl instance;\r
+       private final QName qname;\r
+\r
+       FeatureBuilder(QName qname) {\r
+               this.qname = qname;\r
+               instance = new FeatureDefinitionImpl(qname);\r
+       }\r
+\r
+       @Override\r
+       public SchemaNode build() {\r
+               return instance;\r
+       }\r
+\r
+       @Override\r
+       public QName getQName() {\r
+               return qname;\r
+       }\r
+\r
+       @Override\r
+       public void setPath(SchemaPath path) {\r
+               instance.setPath(path);\r
+       }\r
+\r
+       @Override\r
+       public void setDescription(String description) {\r
+               instance.setDescription(description);\r
+       }\r
+\r
+       @Override\r
+       public void setReference(String reference) {\r
+               instance.setReference(reference);\r
+       }\r
+\r
+       @Override\r
+       public void setStatus(Status status) {\r
+               instance.setStatus(status);\r
+       }\r
+\r
+       private static class FeatureDefinitionImpl implements FeatureDefinition {\r
+\r
+               private final QName qname;\r
+               private SchemaPath path;\r
+               private String description;\r
+               private String reference;\r
+               private Status status;\r
+\r
+               private FeatureDefinitionImpl(QName qname) {\r
+                       this.qname = qname;\r
+               }\r
+\r
+               @Override\r
+               public QName getQName() {\r
+                       return qname;\r
+               }\r
+\r
+               @Override\r
+               public SchemaPath getPath() {\r
+                       return path;\r
+               }\r
+               private void setPath(SchemaPath path) {\r
+                       this.path = path;;\r
+               }\r
+\r
+               @Override\r
+               public String getDescription() {\r
+                       return description;\r
+               }\r
+               private void setDescription(String description) {\r
+                       this.description = description;\r
+               }\r
+\r
+               @Override\r
+               public String getReference() {\r
+                       return reference;\r
+               }\r
+               private void setReference(String reference) {\r
+                       this.reference = reference;\r
+               }\r
+\r
+               @Override\r
+               public Status getStatus() {\r
+                       return status;\r
+               }\r
+               private void setStatus(Status status) {\r
+                       this.status = status;\r
+               }\r
+\r
+               @Override\r
+               public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+                       // TODO Auto-generated method stub\r
+                       return null;\r
+               }\r
+\r
+               @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result + ((qname == null) ? 0 : qname.hashCode());\r
+            result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+            result = prime * result + ((description == null) ? 0 : description.hashCode());\r
+            result = prime * result + ((reference == null) ? 0 : reference.hashCode());\r
+            result = prime * result + ((status == null) ? 0 : status.hashCode());\r
+            return result;\r
+        }\r
+\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj) {\r
+                return true;\r
+            }\r
+            if (obj == null) {\r
+                return false;\r
+            }\r
+            if (getClass() != obj.getClass()) {\r
+                return false;\r
+            }\r
+            FeatureDefinitionImpl other = (FeatureDefinitionImpl) obj;\r
+            if (qname == null) {\r
+                if (other.qname != null) {\r
+                    return false;\r
+                }\r
+            } else if (!qname.equals(other.qname)) {\r
+                return false;\r
+            }\r
+            if (path == null) {\r
+                if (other.path != null) {\r
+                    return false;\r
+                }\r
+            } else if (!path.equals(other.path)) {\r
+                return false;\r
+            }\r
+            if (description == null) {\r
+                if (other.description != null) {\r
+                    return false;\r
+                }\r
+            } else if (!description.equals(other.description)) {\r
+                return false;\r
+            }\r
+            if (reference == null) {\r
+                if (other.reference != null) {\r
+                    return false;\r
+                }\r
+            } else if (!reference.equals(other.reference)) {\r
+                return false;\r
+            }\r
+            if (status == null) {\r
+                if (other.status != null) {\r
+                    return false;\r
+                }\r
+            } else if (!status.equals(other.status)) {\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
+\r
+               @Override\r
+               public String toString() {\r
+                       StringBuilder sb = new StringBuilder(FeatureDefinitionImpl.class.getSimpleName());\r
+                       sb.append("[name="+ qname);\r
+                       sb.append(", path="+ path);\r
+                       sb.append(", description="+ description);\r
+                       sb.append(", reference="+ reference);\r
+                       sb.append(", status="+ status +"]");\r
+                       return sb.toString();\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/GroupingBuilderImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/GroupingBuilderImpl.java
new file mode 100644 (file)
index 0000000..5ffe307
--- /dev/null
@@ -0,0 +1,245 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.model.parser.api.DataSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.GroupingBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeDefinitionBuilder;\r
+import org.opendaylight.controller.model.parser.api.UsesNodeBuilder;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+import org.opendaylight.controller.yang.model.api.UsesNode;\r
+\r
+\r
+public class GroupingBuilderImpl implements GroupingBuilder {\r
+\r
+       private final GroupingDefinitionImpl instance;\r
+       private final Set<DataSchemaNodeBuilder> childNodes = new HashSet<DataSchemaNodeBuilder>();\r
+       private final Set<GroupingBuilder> groupings = new HashSet<GroupingBuilder>();\r
+       private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();\r
+       private final Set<UsesNodeBuilder> usesNodes = new HashSet<UsesNodeBuilder>();\r
+\r
+       GroupingBuilderImpl(QName qname) {\r
+               this.instance = new GroupingDefinitionImpl(qname);\r
+       }\r
+\r
+       @Override\r
+       public GroupingDefinition build() {\r
+               // CHILD NODES\r
+               Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();\r
+               for(DataSchemaNodeBuilder node : childNodes) {\r
+                       childs.put(node.getQName(), node.build());\r
+               }\r
+               instance.setChildNodes(childs);\r
+\r
+               // GROUPINGS\r
+               Set<GroupingDefinition> groupingDefinitions = new HashSet<GroupingDefinition>();\r
+               for(GroupingBuilder builder : groupings) {\r
+                       groupingDefinitions.add(builder.build());\r
+               }\r
+               instance.setGroupings(groupingDefinitions);\r
+\r
+               // TYPEDEFS\r
+               Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();\r
+               for (TypeDefinitionBuilder entry : addedTypedefs) {\r
+                       typedefs.add(entry.build());\r
+               }\r
+               instance.setTypeDefinitions(typedefs);\r
+\r
+               // USES\r
+               Set<UsesNode> usesNodeDefinitions = new HashSet<UsesNode>();\r
+               for(UsesNodeBuilder builder : usesNodes) {\r
+                       usesNodeDefinitions.add(builder.build());\r
+               }\r
+               instance.setUses(usesNodeDefinitions);\r
+\r
+               return instance;\r
+       }\r
+\r
+       @Override\r
+       public void addTypedef(TypeDefinitionBuilder type) {\r
+               addedTypedefs.add(type);\r
+       }\r
+       @Override\r
+       public void setPath(SchemaPath schemaPath) {\r
+               instance.setPath(schemaPath);\r
+       }\r
+       @Override\r
+       public void setDescription(String description) {\r
+               instance.setDescription(description);\r
+       }\r
+       @Override\r
+       public void setReference(String reference) {\r
+               instance.setReference(reference);\r
+       }\r
+       @Override\r
+       public void setStatus(Status status) {\r
+               instance.setStatus(status);\r
+       }\r
+\r
+       @Override\r
+       public void addChildNode(DataSchemaNodeBuilder childNode) {\r
+               childNodes.add(childNode);\r
+       }\r
+\r
+       @Override\r
+       public void addGrouping(GroupingBuilder grouping) {\r
+               groupings.add(grouping);\r
+       }\r
+\r
+       @Override\r
+       public void addUsesNode(UsesNodeBuilder usesBuilder) {\r
+               usesNodes.add(usesBuilder);\r
+       }\r
+\r
+\r
+\r
+       private static class GroupingDefinitionImpl implements GroupingDefinition {\r
+\r
+               private final QName qname;\r
+               private SchemaPath path;\r
+               private String description;\r
+               private String reference;\r
+               private Status status;\r
+\r
+               private Map<QName, DataSchemaNode> childNodes;\r
+               private Set<GroupingDefinition> groupings;\r
+               private Set<TypeDefinition<?>> typeDefinitions;\r
+               private Set<UsesNode> uses;\r
+\r
+               private GroupingDefinitionImpl(QName qname) {\r
+                       this.qname = qname;\r
+               }\r
+\r
+               @Override\r
+               public QName getQName() {\r
+                       return qname;\r
+               }\r
+\r
+               @Override\r
+               public SchemaPath getPath() {\r
+                       return path;\r
+               }\r
+               private void setPath(SchemaPath path) {\r
+                       this.path = path;\r
+               }\r
+\r
+               @Override\r
+               public String getDescription() {\r
+                       return description;\r
+               }\r
+               private void setDescription(String description) {\r
+                       this.description = description;\r
+               }\r
+\r
+               @Override\r
+               public String getReference() {\r
+                       return reference;\r
+               }\r
+               private void setReference(String reference) {\r
+                       this.reference = reference;\r
+               }\r
+\r
+               @Override\r
+               public Status getStatus() {\r
+                       return status;\r
+               }\r
+               private void setStatus(Status status) {\r
+                       this.status = status;\r
+               }\r
+\r
+               @Override\r
+               public Set<DataSchemaNode> getChildNodes() {\r
+                       return new HashSet<DataSchemaNode>(childNodes.values());\r
+               }\r
+               private void setChildNodes(Map<QName, DataSchemaNode> childNodes) {\r
+                       this.childNodes = childNodes;\r
+               }\r
+\r
+               @Override\r
+               public Set<GroupingDefinition> getGroupings() {\r
+                       return groupings;\r
+               }\r
+               private void setGroupings(Set<GroupingDefinition> groupings) {\r
+                       this.groupings = groupings;\r
+               }\r
+\r
+               @Override\r
+               public Set<UsesNode> getUses() {\r
+                       return uses;\r
+               }\r
+               private void setUses(Set<UsesNode> uses) {\r
+                       this.uses = uses;\r
+               }\r
+\r
+               @Override\r
+               public Set<TypeDefinition<?>> getTypeDefinitions() {\r
+                       return typeDefinitions;\r
+               }\r
+               private void setTypeDefinitions(Set<TypeDefinition<?>> typeDefinitions) {\r
+                       this.typeDefinitions = typeDefinitions;\r
+               }\r
+\r
+               @Override\r
+               public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+                       // TODO Auto-generated method stub\r
+                       return null;\r
+               }\r
+\r
+               @Override\r
+               public DataSchemaNode getDataChildByName(QName name) {\r
+                       return childNodes.get(name);\r
+               }\r
+\r
+               @Override\r
+               public DataSchemaNode getDataChildByName(String name) {\r
+                       DataSchemaNode result = null;\r
+                       for(Map.Entry<QName, DataSchemaNode> entry : childNodes.entrySet()) {\r
+                               if(entry.getKey().getLocalName().equals(name)) {\r
+                                       result = entry.getValue();\r
+                                       break;\r
+                               }\r
+                       }\r
+                       return result;\r
+               }\r
+\r
+               @Override\r
+               public String toString() {\r
+                       StringBuilder sb = new StringBuilder();\r
+                       sb.append(GroupingDefinitionImpl.class.getSimpleName() +"[\n");\r
+                       sb.append("qname="+ qname +", \n");\r
+                       sb.append("path="+ path +", \n");\r
+                       sb.append("description="+ description +", \n");\r
+                       sb.append("reference="+ reference +", \n");\r
+                       sb.append("status="+ status +", \n");\r
+                       sb.append("childNodes="+ childNodes.values() +", \n");\r
+                       sb.append("groupings="+ groupings +"]");\r
+                       return sb.toString();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Always returns null.\r
+        */\r
+       @Override\r
+       public QName getQName() {\r
+               return null;\r
+       }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/LeafListSchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/LeafListSchemaNodeBuilder.java
new file mode 100644 (file)
index 0000000..f2ea8ca
--- /dev/null
@@ -0,0 +1,221 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.parser.api.DataSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.SchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeAwareBuilder;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ConstraintDefinition;\r
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.MustDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+\r
+public class LeafListSchemaNodeBuilder implements SchemaNodeBuilder, TypeAwareBuilder, MustAwareBuilder, DataSchemaNodeBuilder {\r
+\r
+               private final LeafListSchemaNodeImpl instance;\r
+               private final QName qname;\r
+               private TypeDefinition<?> type;\r
+               private MustDefinitionBuilder mustDefinitionBuilder;\r
+\r
+               LeafListSchemaNodeBuilder(QName qname) {\r
+                       this.qname = qname;\r
+                       instance = new LeafListSchemaNodeImpl(qname);\r
+               }\r
+\r
+\r
+               @Override\r
+               public DataSchemaNode build() {\r
+                       if(mustDefinitionBuilder != null) {\r
+                               MustDefinition mustDefinition = mustDefinitionBuilder.build();\r
+                               instance.setMustDefinition(mustDefinition);\r
+                       }\r
+                       return instance;\r
+               }\r
+\r
+               @Override\r
+               public QName getQName() {\r
+                       return qname;\r
+               }\r
+\r
+               @Override\r
+               public void setPath(SchemaPath path) {\r
+                       instance.setPath(path);\r
+               }\r
+\r
+               @Override\r
+               public void setDescription(String description) {\r
+                       instance.setDescription(description);\r
+               }\r
+\r
+               @Override\r
+               public void setReference(String reference) {\r
+                       instance.setReference(reference);\r
+               }\r
+\r
+               @Override\r
+               public void setStatus(Status status) {\r
+                       instance.setStatus(status);\r
+               }\r
+\r
+               @Override\r
+               public TypeDefinition<?> getType() {\r
+                       return type;\r
+               }\r
+\r
+               @Override\r
+               public void setType(TypeDefinition<?> type) {\r
+                       this.type = type;\r
+                       instance.setType(type);\r
+               }\r
+\r
+               @Override\r
+               public void setMustDefinitionBuilder(MustDefinitionBuilder mustDefinitionBuilder) {\r
+                       this.mustDefinitionBuilder = mustDefinitionBuilder;\r
+               }\r
+\r
+               public void setAugmenting(boolean augmenting) {\r
+                       instance.setAugmenting(augmenting);\r
+               }\r
+               public void setConfiguration(boolean configuration) {\r
+                       instance.setConfiguration(configuration);\r
+               }\r
+               public void setConstraints(ConstraintDefinition constraints) {\r
+                       instance.setConstraints(constraints);\r
+               }\r
+               public void setUserOrdered(boolean userOrdered) {\r
+                       instance.setUserOrdered(userOrdered);\r
+               }\r
+\r
+\r
+               private class LeafListSchemaNodeImpl implements LeafListSchemaNode {\r
+                       private final QName qname;\r
+                       private SchemaPath path;\r
+                       private String description;\r
+                       private String reference;\r
+                       private Status status = Status.CURRENT;\r
+\r
+                       private boolean augmenting;\r
+                       private boolean configuration;\r
+                       private ConstraintDefinition constraints;\r
+\r
+                       private TypeDefinition<?> type;\r
+                       private boolean userOrdered;\r
+\r
+                       private MustDefinition mustDefinition;\r
+\r
+                       private LeafListSchemaNodeImpl(QName qname) {\r
+                               this.qname = qname;\r
+                       }\r
+\r
+\r
+                       @Override\r
+                       public QName getQName() {\r
+                               return qname;\r
+                       }\r
+\r
+                       @Override\r
+                       public SchemaPath getPath() {\r
+                               return path;\r
+                       }\r
+                       private void setPath(SchemaPath path) {\r
+                               this.path = path;;\r
+                       }\r
+\r
+                       @Override\r
+                       public String getDescription() {\r
+                               return description;\r
+                       }\r
+                       private void setDescription(String description) {\r
+                               this.description = description;\r
+                       }\r
+\r
+                       @Override\r
+                       public String getReference() {\r
+                               return reference;\r
+                       }\r
+                       private void setReference(String reference) {\r
+                               this.reference = reference;\r
+                       }\r
+\r
+                       @Override\r
+                       public Status getStatus() {\r
+                               return status;\r
+                       }\r
+                       private void setStatus(Status status) {\r
+                               this.status = status;\r
+                       }\r
+\r
+                       @Override\r
+                       public boolean isAugmenting() {\r
+                               return augmenting;\r
+                       }\r
+                       private void setAugmenting(boolean augmenting) {\r
+                               this.augmenting = augmenting;\r
+                       }\r
+\r
+                       @Override\r
+                       public boolean isConfiguration() {\r
+                               return configuration;\r
+                       }\r
+                       private void setConfiguration(boolean configuration) {\r
+                               this.configuration = configuration;\r
+                       }\r
+\r
+                       @Override\r
+                       public ConstraintDefinition getConstraints() {\r
+                               return constraints;\r
+                       }\r
+                       private void setConstraints(ConstraintDefinition constraints) {\r
+                               this.constraints = constraints;\r
+                       }\r
+\r
+                       @Override\r
+                       public TypeDefinition<?> getType() {\r
+                               return type;\r
+                       }\r
+                       public void setType(TypeDefinition<? extends TypeDefinition<?>> type) {\r
+                               this.type = type;\r
+                       }\r
+\r
+                       @Override\r
+                       public boolean isUserOrdered() {\r
+                               return userOrdered;\r
+                       }\r
+                       private void setUserOrdered(boolean userOrdered) {\r
+                               this.userOrdered = userOrdered;\r
+                       }\r
+\r
+                       @Override\r
+                       public MustDefinition getMustDefinition() {\r
+                               return mustDefinition;\r
+                       }\r
+                       private void setMustDefinition(MustDefinition mustDefinition) {\r
+                               this.mustDefinition = mustDefinition;\r
+                       }\r
+\r
+                       @Override\r
+                       public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+                               // TODO Auto-generated method stub\r
+                               return null;\r
+                       }\r
+\r
+                       @Override\r
+                       public String toString() {\r
+                               return LeafListSchemaNodeImpl.class.getSimpleName() +"[qname="+ qname +", type="+ type +"]";\r
+                       }\r
+               }\r
+\r
+       }
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/LeafSchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/LeafSchemaNodeBuilder.java
new file mode 100644 (file)
index 0000000..f50ac8a
--- /dev/null
@@ -0,0 +1,232 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.parser.api.DataSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.SchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeAwareBuilder;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ConstraintDefinition;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.LeafSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.MustDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+\r
+public class LeafSchemaNodeBuilder implements DataSchemaNodeBuilder,\r
+               SchemaNodeBuilder, TypeAwareBuilder, MustAwareBuilder {\r
+\r
+       private final QName qname;\r
+       private final LeafSchemaNodeImpl instance;\r
+       private TypeDefinition<?> type;\r
+       private MustDefinitionBuilder mustDefinitionBuilder;\r
+\r
+       LeafSchemaNodeBuilder(QName qname) {\r
+               this.qname = qname;\r
+               instance = new LeafSchemaNodeImpl(qname);\r
+       }\r
+\r
+       @Override\r
+       public LeafSchemaNode build() {\r
+               if (mustDefinitionBuilder != null) {\r
+                       MustDefinition mustDefinition = mustDefinitionBuilder.build();\r
+                       instance.setMustDefinition(mustDefinition);\r
+               }\r
+               return instance;\r
+       }\r
+\r
+       @Override\r
+       public QName getQName() {\r
+               return qname;\r
+       }\r
+\r
+       @Override\r
+       public void setPath(SchemaPath path) {\r
+               instance.setPath(path);\r
+       }\r
+\r
+       @Override\r
+       public void setDescription(String description) {\r
+               instance.setDescription(description);\r
+       }\r
+\r
+       @Override\r
+       public void setReference(String reference) {\r
+               instance.setReference(reference);\r
+       }\r
+\r
+       @Override\r
+       public void setStatus(Status status) {\r
+               instance.setStatus(status);\r
+       }\r
+\r
+       public void setAugmenting(boolean augmenting) {\r
+               instance.setAugmenting(augmenting);\r
+       }\r
+\r
+       public void setConfiguration(boolean configuration) {\r
+               instance.setConfiguration(configuration);\r
+       }\r
+\r
+       public void setConstraints(ConstraintDefinition constraints) {\r
+               instance.setConstraints(constraints);\r
+       }\r
+\r
+       @Override\r
+       public TypeDefinition<?> getType() {\r
+               return type;\r
+       }\r
+\r
+       @Override\r
+       public void setType(TypeDefinition<?> type) {\r
+               this.type = type;\r
+               instance.setType(type);\r
+       }\r
+\r
+       @Override\r
+       public void setMustDefinitionBuilder(\r
+                       MustDefinitionBuilder mustDefinitionBuilder) {\r
+               this.mustDefinitionBuilder = mustDefinitionBuilder;\r
+       }\r
+\r
+       private class LeafSchemaNodeImpl implements LeafSchemaNode {\r
+               private final QName qname;\r
+               private SchemaPath path;\r
+               private String description;\r
+               private String reference;\r
+               private Status status = Status.CURRENT;\r
+\r
+               private boolean augmenting;\r
+               private boolean configuration;\r
+               private ConstraintDefinition constraints;\r
+\r
+               private TypeDefinition<?> type;\r
+               private MustDefinition mustDefinition;\r
+\r
+               private LeafSchemaNodeImpl(QName qname) {\r
+                       this.qname = qname;\r
+               }\r
+\r
+               @Override\r
+               public QName getQName() {\r
+                       return qname;\r
+               }\r
+\r
+               @Override\r
+               public SchemaPath getPath() {\r
+                       return path;\r
+               }\r
+\r
+               private void setPath(SchemaPath path) {\r
+                       this.path = path;\r
+               }\r
+\r
+               @Override\r
+               public String getDescription() {\r
+                       return description;\r
+               }\r
+\r
+               private void setDescription(String description) {\r
+                       this.description = description;\r
+               }\r
+\r
+               @Override\r
+               public String getReference() {\r
+                       return reference;\r
+               }\r
+\r
+               private void setReference(String reference) {\r
+                       this.reference = reference;\r
+               }\r
+\r
+               @Override\r
+               public Status getStatus() {\r
+                       return status;\r
+               }\r
+\r
+               private void setStatus(Status status) {\r
+                       if (status != null) {\r
+                               this.status = status;\r
+                       }\r
+               }\r
+\r
+               @Override\r
+               public boolean isAugmenting() {\r
+                       return augmenting;\r
+               }\r
+\r
+               private void setAugmenting(boolean augmenting) {\r
+                       this.augmenting = augmenting;\r
+               }\r
+\r
+               @Override\r
+               public boolean isConfiguration() {\r
+                       return configuration;\r
+               }\r
+\r
+               private void setConfiguration(boolean configuration) {\r
+                       this.configuration = configuration;\r
+               }\r
+\r
+               @Override\r
+               public ConstraintDefinition getConstraints() {\r
+                       return constraints;\r
+               }\r
+\r
+               private void setConstraints(ConstraintDefinition constraints) {\r
+                       this.constraints = constraints;\r
+               }\r
+\r
+               @Override\r
+               public TypeDefinition<?> getType() {\r
+                       return type;\r
+               }\r
+\r
+               private void setType(TypeDefinition<? extends TypeDefinition<?>> type) {\r
+                       this.type = type;\r
+               }\r
+\r
+               @Override\r
+               public MustDefinition getMustDefinition() {\r
+                       return mustDefinition;\r
+               }\r
+\r
+               private void setMustDefinition(MustDefinition mustDefinition) {\r
+                       this.mustDefinition = mustDefinition;\r
+               }\r
+\r
+               @Override\r
+               public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+                       // TODO Auto-generated method stub\r
+                       return null;\r
+               }\r
+\r
+               @Override\r
+               public String toString() {\r
+                       StringBuilder sb = new StringBuilder(\r
+                                       LeafSchemaNodeImpl.class.getSimpleName());\r
+                       sb.append("[");\r
+                       sb.append("qname=" + qname);\r
+                       sb.append(", path=" + path);\r
+                       sb.append(", description=" + description);\r
+                       sb.append(", reference=" + reference);\r
+                       sb.append(", status=" + status);\r
+                       sb.append(", augmenting=" + augmenting);\r
+                       sb.append(", configuration=" + configuration);\r
+                       sb.append(", constraints=" + constraints);\r
+                       sb.append(", type=" + type);\r
+                       sb.append(", mustDefinition=" + mustDefinition);\r
+                       sb.append("]");\r
+                       return sb.toString();\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/ListSchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/ListSchemaNodeBuilder.java
new file mode 100644 (file)
index 0000000..3059ba9
--- /dev/null
@@ -0,0 +1,463 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.model.parser.api.AbstractChildNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.AugmentationTargetBuilder;\r
+import org.opendaylight.controller.model.parser.api.DataSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.GroupingBuilder;\r
+import org.opendaylight.controller.model.parser.api.SchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeDefinitionAwareBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeDefinitionBuilder;\r
+import org.opendaylight.controller.model.parser.api.UsesNodeBuilder;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.AugmentationSchema;\r
+import org.opendaylight.controller.yang.model.api.ConstraintDefinition;\r
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;\r
+import org.opendaylight.controller.yang.model.api.ListSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+import org.opendaylight.controller.yang.model.api.UsesNode;\r
+\r
+\r
+public class ListSchemaNodeBuilder extends AbstractChildNodeBuilder implements DataSchemaNodeBuilder, SchemaNodeBuilder, AugmentationTargetBuilder, TypeDefinitionAwareBuilder {\r
+\r
+               private final ListSchemaNodeImpl instance;\r
+\r
+               private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();\r
+               private final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();\r
+               private final Set<UsesNodeBuilder> usesNodes = new HashSet<UsesNodeBuilder>();\r
+\r
+               ListSchemaNodeBuilder(QName qname) {\r
+                       super(qname);\r
+                       instance = new ListSchemaNodeImpl(qname);\r
+               }\r
+\r
+               @Override\r
+               public ListSchemaNode build() {\r
+                       // CHILD NODES\r
+                       Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();\r
+                       for(DataSchemaNodeBuilder node : childNodes) {\r
+                               childs.put(node.getQName(), node.build());\r
+                       }\r
+                       instance.setChildNodes(childs);\r
+\r
+                       // TYPEDEFS\r
+                       Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();\r
+                       for (TypeDefinitionBuilder entry : addedTypedefs) {\r
+                               typedefs.add(entry.build());\r
+                       }\r
+                       instance.setTypeDefinitions(typedefs);\r
+\r
+                       // USES\r
+                       Set<UsesNode> usesNodeDefinitions = new HashSet<UsesNode>();\r
+                       for(UsesNodeBuilder builder : usesNodes) {\r
+                               usesNodeDefinitions.add(builder.build());\r
+                       }\r
+                       instance.setUses(usesNodeDefinitions);\r
+\r
+                       // GROUPINGS\r
+                       Set<GroupingDefinition> groupingDefinitions = new HashSet<GroupingDefinition>();\r
+                       for (GroupingBuilder builder : groupings) {\r
+                               groupingDefinitions.add(builder.build());\r
+                       }\r
+                       instance.setGroupings(groupingDefinitions);\r
+\r
+                       instance.setAvailableAugmentations(augmentations);\r
+\r
+                       return instance;\r
+               }\r
+\r
+\r
+               @Override\r
+               public void addTypedef(TypeDefinitionBuilder type) {\r
+                       addedTypedefs.add(type);\r
+               }\r
+\r
+               @Override\r
+               public void setPath(SchemaPath path) {\r
+                       instance.setPath(path);\r
+               }\r
+\r
+               @Override\r
+               public void setDescription(String description) {\r
+                       instance.setDescription(description);\r
+               }\r
+\r
+               @Override\r
+               public void setReference(String reference) {\r
+                       instance.setReference(reference);\r
+               }\r
+\r
+               @Override\r
+               public void setStatus(Status status) {\r
+                       instance.setStatus(status);\r
+               }\r
+\r
+               @Override\r
+               public void addUsesNode(UsesNodeBuilder usesBuilder) {\r
+                       usesNodes.add(usesBuilder);\r
+               }\r
+\r
+               @Override\r
+               public void addAugmentation(AugmentationSchema augmentationSchema) {\r
+                       augmentations.add(augmentationSchema);\r
+               }\r
+\r
+               public void setKeyDefinition(List<QName> keyDefinition) {\r
+                       instance.setKeyDefinition(keyDefinition);\r
+               }\r
+               public void setAugmenting(boolean augmenting) {\r
+                       instance.setAugmenting(augmenting);\r
+               }\r
+               public void setConfiguration(boolean configuration) {\r
+                       instance.setConfiguration(configuration);\r
+               }\r
+               public void setConstraints(ConstraintDefinition constraints) {\r
+                       instance.setConstraints(constraints);\r
+               }\r
+               public void setUserOrdered(boolean userOrdered) {\r
+                       instance.setUserOrdered(userOrdered);\r
+               }\r
+\r
+\r
+               private class ListSchemaNodeImpl implements ListSchemaNode {\r
+                       private final QName qname;\r
+                       private SchemaPath path;\r
+                       private String description;\r
+                       private String reference;\r
+                       private Status status = Status.CURRENT;\r
+\r
+                       private List<QName> keyDefinition;\r
+\r
+                       private boolean augmenting;\r
+                       private boolean configuration;\r
+                       private ConstraintDefinition constraints;\r
+\r
+                       private Set<AugmentationSchema> augmentations;\r
+\r
+                       private Map<QName, DataSchemaNode> childNodes;\r
+                       private Set<TypeDefinition<?>> typeDefinitions;\r
+                       private Set<GroupingDefinition> groupings;\r
+                       private Set<UsesNode> uses;\r
+\r
+                       private boolean userOrdered;\r
+\r
+                       private ListSchemaNodeImpl(QName qname) {\r
+                               this.qname = qname;\r
+                       }\r
+\r
+\r
+                       @Override\r
+                       public QName getQName() {\r
+                               return qname;\r
+                       }\r
+\r
+                       @Override\r
+                       public SchemaPath getPath() {\r
+                               return path;\r
+                       }\r
+                       private void setPath(SchemaPath path) {\r
+                               this.path = path;\r
+                       }\r
+\r
+                       @Override\r
+                       public String getDescription() {\r
+                               return description;\r
+                       }\r
+                       private void setDescription(String description) {\r
+                               this.description = description;\r
+                       }\r
+\r
+                       @Override\r
+                       public String getReference() {\r
+                               return reference;\r
+                       }\r
+                       private void setReference(String reference) {\r
+                               this.reference = reference;\r
+                       }\r
+\r
+                       @Override\r
+                       public Status getStatus() {\r
+                               return status;\r
+                       }\r
+                       private void setStatus(Status status) {\r
+                               this.status = status;\r
+                       }\r
+\r
+                       @Override\r
+                       public List<QName> getKeyDefinition() {\r
+                               return keyDefinition;\r
+                       }\r
+                       private void setKeyDefinition(List<QName> keyDefinition) {\r
+                               this.keyDefinition = keyDefinition;\r
+                       }\r
+\r
+                       @Override\r
+                       public boolean isAugmenting() {\r
+                               return augmenting;\r
+                       }\r
+                       private void setAugmenting(boolean augmenting) {\r
+                               this.augmenting = augmenting;\r
+                       }\r
+\r
+                       @Override\r
+                       public boolean isConfiguration() {\r
+                               return configuration;\r
+                       }\r
+                       private void setConfiguration(boolean configuration) {\r
+                               this.configuration = configuration;\r
+                       }\r
+\r
+                       @Override\r
+                       public ConstraintDefinition getConstraints() {\r
+                               return constraints;\r
+                       }\r
+                       private void setConstraints(ConstraintDefinition constraints) {\r
+                               this.constraints = constraints;\r
+                       }\r
+\r
+                       @Override\r
+                       public Set<AugmentationSchema> getAvailableAugmentations() {\r
+                               return augmentations;\r
+                       }\r
+                       private void setAvailableAugmentations(Set<AugmentationSchema> augmentations) {\r
+                               this.augmentations = augmentations;\r
+                       }\r
+\r
+                       @Override\r
+                       public Set<DataSchemaNode> getChildNodes() {\r
+                               return new HashSet<DataSchemaNode>(childNodes.values());\r
+                       }\r
+                       void setChildNodes(Map<QName, DataSchemaNode> childNodes) {\r
+                               this.childNodes = childNodes;\r
+                       }\r
+\r
+                       @Override\r
+                       public Set<GroupingDefinition> getGroupings() {\r
+                               return groupings;\r
+                       }\r
+                       private void setGroupings(Set<GroupingDefinition> groupings) {\r
+                               this.groupings = groupings;\r
+                       }\r
+\r
+                       @Override\r
+                       public Set<TypeDefinition<?>> getTypeDefinitions() {\r
+                               return typeDefinitions;\r
+                       }\r
+                       private void setTypeDefinitions(Set<TypeDefinition<?>> typeDefinitions) {\r
+                               this.typeDefinitions = typeDefinitions;\r
+                       }\r
+\r
+                       @Override\r
+                       public Set<UsesNode> getUses() {\r
+                               return uses;\r
+                       }\r
+                       private void setUses(Set<UsesNode> uses) {\r
+                               this.uses = uses;\r
+                       }\r
+\r
+                       @Override\r
+                       public DataSchemaNode getDataChildByName(QName name) {\r
+                               return childNodes.get(name);\r
+                       }\r
+\r
+                       @Override\r
+                       public DataSchemaNode getDataChildByName(String name) {\r
+                               DataSchemaNode result = null;\r
+                               for(Map.Entry<QName, DataSchemaNode> entry : childNodes.entrySet()) {\r
+                                       if(entry.getKey().getLocalName().equals(name)) {\r
+                                               result = entry.getValue();\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               return result;\r
+                       }\r
+\r
+                       @Override\r
+                       public boolean isUserOrdered() {\r
+                               return userOrdered;\r
+                       }\r
+                       private void setUserOrdered(boolean userOrdered) {\r
+                               this.userOrdered = userOrdered;\r
+                       }\r
+\r
+                       @Override\r
+                       public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+                               // TODO Auto-generated method stub\r
+                               return null;\r
+                       }\r
+\r
+                       @Override\r
+               public int hashCode() {\r
+                   final int prime = 31;\r
+                   int result = 1;\r
+                   result = prime * result + ((qname == null) ? 0 : qname.hashCode());\r
+                   result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+                   result = prime * result + ((description == null) ? 0 : description.hashCode());\r
+                   result = prime * result + ((reference == null) ? 0 : reference.hashCode());\r
+                   result = prime * result + ((status == null) ? 0 : status.hashCode());\r
+                   result = prime * result + ((keyDefinition == null) ? 0 : keyDefinition.hashCode());\r
+                   result = prime * result + (augmenting ? 1231 : 1237);\r
+                   result = prime * result + (configuration ? 1231 : 1237);\r
+                   result = prime * result + ((constraints == null) ? 0 : constraints.hashCode());\r
+                   result = prime * result + ((augmentations == null) ? 0 : augmentations.hashCode());\r
+                   result = prime * result + ((childNodes == null) ? 0 : childNodes.hashCode());\r
+                   result = prime * result + ((typeDefinitions == null) ? 0 : typeDefinitions.hashCode());\r
+                   result = prime * result + ((groupings == null) ? 0 : groupings.hashCode());\r
+                   result = prime * result + ((uses == null) ? 0 : uses.hashCode());\r
+                   result = prime * result + (userOrdered ? 1231 : 1237);\r
+                   return result;\r
+               }\r
+\r
+\r
+                       @Override\r
+               public boolean equals(Object obj) {\r
+                   if (this == obj) {\r
+                       return true;\r
+                   }\r
+                   if (obj == null) {\r
+                       return false;\r
+                   }\r
+                   if (getClass() != obj.getClass()) {\r
+                       return false;\r
+                   }\r
+                   ListSchemaNodeImpl other = (ListSchemaNodeImpl) obj;\r
+                   if (qname == null) {\r
+                       if (other.qname != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!qname.equals(other.qname)) {\r
+                       return false;\r
+                   }\r
+                   if (path == null) {\r
+                       if (other.path != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!path.equals(other.path)) {\r
+                       return false;\r
+                   }\r
+                   if (description == null) {\r
+                       if (other.description != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!description.equals(other.description)) {\r
+                       return false;\r
+                   }\r
+                   if (reference == null) {\r
+                       if (other.reference != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!reference.equals(other.reference)) {\r
+                       return false;\r
+                   }\r
+                   if (status == null) {\r
+                       if (other.status != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!status.equals(other.status)) {\r
+                       return false;\r
+                   }\r
+                   if (keyDefinition == null) {\r
+                       if (other.keyDefinition != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!keyDefinition.equals(other.keyDefinition)) {\r
+                       return false;\r
+                   }\r
+                   if(augmenting != other.augmenting) {\r
+                       return false;\r
+                   }\r
+                   if(configuration != other.configuration) {\r
+                       return false;\r
+                   }\r
+                   if (constraints == null) {\r
+                       if (other.constraints != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!constraints.equals(other.constraints)) {\r
+                       return false;\r
+                   }\r
+                   if (augmentations == null) {\r
+                       if (other.augmentations != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!augmentations.equals(other.augmentations)) {\r
+                       return false;\r
+                   }\r
+                   if (childNodes == null) {\r
+                       if (other.childNodes != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!childNodes.equals(other.childNodes)) {\r
+                       return false;\r
+                   }\r
+                   if (typeDefinitions == null) {\r
+                       if (other.typeDefinitions != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!typeDefinitions.equals(other.typeDefinitions)) {\r
+                       return false;\r
+                   }\r
+                   if (groupings == null) {\r
+                       if (other.groupings != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!groupings.equals(other.groupings)) {\r
+                       return false;\r
+                   }\r
+                   if (uses == null) {\r
+                       if (other.uses != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!uses.equals(other.uses)) {\r
+                       return false;\r
+                   }\r
+                       if(userOrdered != other.userOrdered) {\r
+                       return false;\r
+                   }\r
+                   return true;\r
+               }\r
+\r
+\r
+\r
+\r
+                       @Override\r
+                       public String toString() {\r
+                               StringBuilder sb = new StringBuilder(ListSchemaNodeImpl.class.getSimpleName());\r
+                               sb.append("[");\r
+                               sb.append("qname="+ qname);\r
+                               sb.append(", path="+ path);\r
+                               sb.append(", description="+ description);\r
+                               sb.append(", reference="+ reference);\r
+                               sb.append(", status="+ status);\r
+                               sb.append(", keyDefinition="+ keyDefinition);\r
+                               sb.append(", augmenting="+ augmenting);\r
+                               sb.append(", configuration="+ configuration);\r
+                               sb.append(", constraints="+ constraints);\r
+                               sb.append(", augmentations="+ augmentations);\r
+                               sb.append(", childNodes="+ childNodes.values());\r
+                               sb.append(", typedefinitions="+ typeDefinitions);\r
+                               sb.append(", groupings="+ groupings);\r
+                               sb.append(", uses="+ uses);\r
+                               sb.append(", userOrdered="+ userOrdered);\r
+                               sb.append("]");\r
+                               return sb.toString();\r
+                       }\r
+               }\r
+\r
+       }
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/ModuleBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/ModuleBuilder.java
new file mode 100644 (file)
index 0000000..98cfbb6
--- /dev/null
@@ -0,0 +1,824 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import java.net.URI;\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.Stack;\r
+\r
+import org.opendaylight.controller.model.parser.api.AugmentationSchemaBuilder;\r
+import org.opendaylight.controller.model.parser.api.Builder;\r
+import org.opendaylight.controller.model.parser.api.ChildNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.DataSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.GroupingBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeAwareBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeDefinitionAwareBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeDefinitionBuilder;\r
+import org.opendaylight.controller.model.parser.api.UsesNodeBuilder;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.AugmentationSchema;\r
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.Deviation;\r
+import org.opendaylight.controller.yang.model.api.FeatureDefinition;\r
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;\r
+import org.opendaylight.controller.yang.model.api.Module;\r
+import org.opendaylight.controller.yang.model.api.ModuleImport;\r
+import org.opendaylight.controller.yang.model.api.NotificationDefinition;\r
+import org.opendaylight.controller.yang.model.api.RpcDefinition;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+import org.opendaylight.controller.yang.model.api.UsesNode;\r
+\r
+\r
+/**\r
+ * This builder builds Module object. If this module is dependent on external\r
+ * module/modules, these dependencies must be resolved before module is built,\r
+ * otherwise result may not be valid.\r
+ */\r
+public class ModuleBuilder implements Builder {\r
+\r
+       private final ModuleImpl instance;\r
+       private final String name;\r
+       private String prefix;\r
+\r
+       private final Set<ModuleImport> imports = new HashSet<ModuleImport>();\r
+       private Set<AugmentationSchema> augmentations;\r
+\r
+       /**\r
+        * All nodes, that can contain other nodes\r
+        */\r
+       private final Map<List<String>, Builder> moduleNodes = new HashMap<List<String>, Builder>();\r
+\r
+       /**\r
+        * Holds all child (DataSchemaNode) nodes: anyxml, choice, container, list, leaf, leaf-list.\r
+        */\r
+       private final Map<List<String>, DataSchemaNodeBuilder> addedChilds = new HashMap<List<String>, DataSchemaNodeBuilder>();\r
+\r
+       private final Map<List<String>, GroupingBuilder> addedGroupings = new HashMap<List<String>, GroupingBuilder>();\r
+       private final Set<AugmentationSchemaBuilder> addedAugments = new HashSet<AugmentationSchemaBuilder>();\r
+       private final Map<List<String>, UsesNodeBuilder> addedUsesNodes = new HashMap<List<String>, UsesNodeBuilder>();\r
+       private final Map<List<String>, RpcDefinitionBuilder> addedRpcs = new HashMap<List<String>, RpcDefinitionBuilder>();\r
+       private final Set<NotificationBuilder> addedNotifications = new HashSet<NotificationBuilder>();\r
+       private final Map<List<String>, FeatureBuilder> addedFeatures = new HashMap<List<String>, FeatureBuilder>();\r
+       private final Map<String, DeviationBuilder> addedDeviations = new HashMap<String, DeviationBuilder>();\r
+       private final Map<List<String>, TypeDefinitionBuilder> addedTypedefs = new HashMap<List<String>, TypeDefinitionBuilder>();\r
+\r
+\r
+       private final Map<List<String>, TypeAwareBuilder> dirtyNodes = new HashMap<List<String>, TypeAwareBuilder>();\r
+\r
+\r
+       public ModuleBuilder(String name) {\r
+               this.name = name;\r
+               instance = new ModuleImpl(name);\r
+       }\r
+\r
+       /**\r
+        * Build new Module object based on this builder. Throws IllegalStateException if builder contains unresolved nodes.\r
+        */\r
+       public Module build() {\r
+               instance.setImports(imports);\r
+\r
+               // TYPEDEFS\r
+               Set<TypeDefinition<?>> typedefs = buildModuleTypedefs(addedTypedefs);\r
+               instance.setTypeDefinitions(typedefs);\r
+\r
+               // CHILD NODES\r
+               final Map<QName, DataSchemaNode> childNodes = buildModuleChildNodes(addedChilds);\r
+               instance.setChildNodes(childNodes);\r
+\r
+               // GROUPINGS\r
+               final Set<GroupingDefinition> groupings = buildModuleGroupings(addedGroupings);\r
+               instance.setGroupings(groupings);\r
+\r
+               // USES\r
+               final Set<UsesNode> usesNodeDefinitions = buildUsesNodes(addedUsesNodes);\r
+               instance.setUses(usesNodeDefinitions);\r
+\r
+               // FEATURES\r
+               Set<FeatureDefinition> features = buildModuleFeatures(addedFeatures);\r
+               instance.setFeatures(features);\r
+\r
+               // NOTIFICATIONS\r
+               final Set<NotificationDefinition> notifications = new HashSet<NotificationDefinition>();\r
+               for (NotificationBuilder entry : addedNotifications) {\r
+                       notifications.add((NotificationDefinition) entry.build());\r
+               }\r
+               instance.setNotifications(notifications);\r
+\r
+               // AUGMENTATIONS\r
+//             final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();\r
+//             for(AugmentationSchemaBuilder entry : addedAugments) {\r
+//                     augmentations.add(entry.build());\r
+//             }\r
+//             instance.setAugmentations(augmentations);\r
+               instance.setAugmentations(augmentations);\r
+\r
+               // RPCs\r
+               final Set<RpcDefinition> rpcs = buildModuleRpcs(addedRpcs);\r
+               instance.setRpcs(rpcs);\r
+\r
+               // DEVIATIONS\r
+               Set<Deviation> deviations = new HashSet<Deviation>();\r
+               for(Map.Entry<String, DeviationBuilder> entry : addedDeviations.entrySet()) {\r
+                       deviations.add(entry.getValue().build());\r
+               }\r
+               instance.setDeviations(deviations);\r
+\r
+               return instance;\r
+       }\r
+\r
+       Builder getNode(List<String> path) {\r
+               return moduleNodes.get(path);\r
+       }\r
+\r
+       Map<List<String>, TypeAwareBuilder> getDirtyNodes() {\r
+               return dirtyNodes;\r
+       }\r
+\r
+       String getName() {\r
+               return name;\r
+       }\r
+\r
+       String getPrefix() {\r
+               return prefix;\r
+       }\r
+\r
+       Set<AugmentationSchemaBuilder> getAddedAugments() {\r
+               return addedAugments;\r
+       }\r
+\r
+\r
+       public void addDirtyNode(Stack<String> path) {\r
+               List<String> dirtyNodePath = new ArrayList<String>(path);\r
+               TypeAwareBuilder nodeBuilder = (TypeAwareBuilder)moduleNodes.get(dirtyNodePath);\r
+               dirtyNodes.put(dirtyNodePath, nodeBuilder);\r
+       }\r
+\r
+       public void setNamespace(URI namespace) {\r
+               instance.setNamespace(namespace);\r
+       }\r
+\r
+       public void setRevision(Date revision) {\r
+               instance.setRevision(revision);\r
+       }\r
+\r
+       public void setPrefix(String prefix) {\r
+               this.prefix = prefix;\r
+               instance.setPrefix(prefix);\r
+       }\r
+\r
+       public void setYangVersion(String yangVersion) {\r
+               instance.setYangVersion(yangVersion);\r
+       }\r
+\r
+       public void setDescription(String description) {\r
+               instance.setDescription(description);\r
+       }\r
+       public void setReference(String reference) {\r
+               instance.setReference(reference);\r
+       }\r
+       public void setOrganization(String organization) {\r
+               instance.setOrganization(organization);\r
+       }\r
+       public void setContact(String contact) {\r
+               instance.setContact(contact);\r
+       }\r
+       public void setAugmentations(Set<AugmentationSchema> augmentations) {\r
+               this.augmentations = augmentations;\r
+       }\r
+\r
+       public boolean addModuleImport(final String moduleName, final Date revision, final String prefix) {\r
+               ModuleImport moduleImport = createModuleImport(moduleName, revision, prefix);\r
+               return imports.add(moduleImport);\r
+       }\r
+\r
+       public Set<ModuleImport> getModuleImports() {\r
+               return imports;\r
+       }\r
+\r
+       public ContainerSchemaNodeBuilder addContainerNode(QName containerName, Stack<String> parentPath) {\r
+               List<String> pathToNode = new ArrayList<String>(parentPath);\r
+\r
+               ContainerSchemaNodeBuilder containerBuilder = new ContainerSchemaNodeBuilder(containerName);\r
+\r
+               ChildNodeBuilder parent = (ChildNodeBuilder)moduleNodes.get(pathToNode);\r
+               if(parent != null) {\r
+                       parent.addChildNode(containerBuilder);\r
+               }\r
+\r
+               pathToNode.add(containerName.getLocalName());\r
+               moduleNodes.put(pathToNode, containerBuilder);\r
+               addedChilds.put(pathToNode, containerBuilder);\r
+\r
+               return containerBuilder;\r
+       }\r
+\r
+       public ListSchemaNodeBuilder addListNode(QName listName, Stack<String> parentPath) {\r
+               List<String> pathToNode = new ArrayList<String>(parentPath);\r
+\r
+               ListSchemaNodeBuilder listBuilder = new ListSchemaNodeBuilder(listName);\r
+\r
+               ChildNodeBuilder parent = (ChildNodeBuilder)moduleNodes.get(pathToNode);\r
+               if(parent != null) {\r
+                       parent.addChildNode(listBuilder);\r
+               }\r
+\r
+               pathToNode.add(listName.getLocalName());\r
+               moduleNodes.put(pathToNode, listBuilder);\r
+               addedChilds.put(pathToNode, listBuilder);\r
+\r
+               return listBuilder;\r
+       }\r
+\r
+       public LeafSchemaNodeBuilder addLeafNode(QName leafName, Stack<String> parentPath) {\r
+               List<String> pathToNode = new ArrayList<String>(parentPath);\r
+\r
+               LeafSchemaNodeBuilder leafBuilder = new LeafSchemaNodeBuilder(leafName);\r
+\r
+               ChildNodeBuilder parent = (ChildNodeBuilder)moduleNodes.get(pathToNode);\r
+               if(parent != null) {\r
+                       parent.addChildNode(leafBuilder);\r
+               }\r
+\r
+               pathToNode.add(leafName.getLocalName());\r
+               addedChilds.put(pathToNode, leafBuilder);\r
+               moduleNodes.put(pathToNode, leafBuilder);\r
+\r
+               return leafBuilder;\r
+       }\r
+\r
+       public LeafListSchemaNodeBuilder addLeafListNode(QName leafListName, Stack<String> parentPath) {\r
+               List<String> pathToNode = new ArrayList<String>(parentPath);\r
+\r
+               LeafListSchemaNodeBuilder leafListBuilder = new LeafListSchemaNodeBuilder(leafListName);\r
+               ChildNodeBuilder parent = (ChildNodeBuilder)moduleNodes.get(pathToNode);\r
+               if(parent != null) {\r
+                       parent.addChildNode(leafListBuilder);\r
+               }\r
+\r
+               pathToNode.add(leafListName.getLocalName());\r
+               addedChilds.put(pathToNode, leafListBuilder);\r
+               moduleNodes.put(pathToNode, leafListBuilder);\r
+\r
+               return leafListBuilder;\r
+       }\r
+\r
+       public GroupingBuilder addGrouping(QName qname, Stack<String> parentPath) {\r
+               List<String> pathToGroup = new ArrayList<String>(parentPath);\r
+\r
+               GroupingBuilder builder = new GroupingBuilderImpl(qname);\r
+               ChildNodeBuilder parentNodeBuilder = (ChildNodeBuilder)moduleNodes.get(pathToGroup);\r
+               if(parentNodeBuilder != null) {\r
+                       parentNodeBuilder.addGrouping(builder);\r
+               }\r
+\r
+               pathToGroup.add(qname.getLocalName());\r
+               moduleNodes.put(pathToGroup, builder);\r
+               addedGroupings.put(pathToGroup, builder);\r
+\r
+               return builder;\r
+       }\r
+\r
+       public AugmentationSchemaBuilder addAugment(String name, Stack<String> parentPath) {\r
+               List<String> pathToAugment = new ArrayList<String>(parentPath);\r
+\r
+               AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(name);\r
+\r
+               // augment can only be in 'module' or 'uses' statement\r
+               UsesNodeBuilder parent = addedUsesNodes.get(pathToAugment);\r
+               if(parent != null) {\r
+                       parent.addAugment(builder);\r
+               }\r
+\r
+               pathToAugment.add(name);\r
+               moduleNodes.put(pathToAugment, builder);\r
+               addedAugments.add(builder);\r
+\r
+               return builder;\r
+       }\r
+\r
+       public UsesNodeBuilder addUsesNode(String groupingPathStr, Stack<String> parentPath) {\r
+               List<String> pathToUses = new ArrayList<String>(parentPath);\r
+\r
+               UsesNodeBuilder builder = new UsesNodeBuilderImpl(groupingPathStr);\r
+\r
+               ChildNodeBuilder parent = (ChildNodeBuilder)moduleNodes.get(pathToUses);\r
+               if(parent != null) {\r
+                       parent.addUsesNode(builder);\r
+               }\r
+\r
+               pathToUses.add(groupingPathStr);\r
+               addedUsesNodes.put(pathToUses, builder);\r
+\r
+               return builder;\r
+       }\r
+\r
+       public RpcDefinitionBuilder addRpc(QName qname, Stack<String> parentPath) {\r
+               List<String> pathToRpc = new ArrayList<String>(parentPath);\r
+\r
+               RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(qname);\r
+\r
+               pathToRpc.add(qname.getLocalName());\r
+               addedRpcs.put(pathToRpc, rpcBuilder);\r
+\r
+               QName inputQName = new QName(qname.getNamespace(), qname.getRevision(), qname.getPrefix(), "input");\r
+               ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(inputQName);\r
+               List<String> pathToInput = new ArrayList<String>(pathToRpc);\r
+               pathToInput.add("input");\r
+               moduleNodes.put(pathToInput, inputBuilder);\r
+               rpcBuilder.setInput(inputBuilder);\r
+\r
+               QName outputQName = new QName(qname.getNamespace(), qname.getRevision(), qname.getPrefix(), "output");\r
+               ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(outputQName);\r
+               List<String> pathToOutput = new ArrayList<String>(pathToRpc);\r
+               pathToOutput.add("output");\r
+               moduleNodes.put(pathToOutput, outputBuilder);\r
+               rpcBuilder.setOutput(outputBuilder);\r
+\r
+               return rpcBuilder;\r
+       }\r
+\r
+       public NotificationBuilder addNotification(QName notificationName, Stack<String> parentPath) {\r
+               List<String> pathToNotification = new ArrayList<String>(parentPath);\r
+\r
+               NotificationBuilder notificationBuilder = new NotificationBuilder(notificationName);\r
+\r
+               pathToNotification.add(notificationName.getLocalName());\r
+               moduleNodes.put(pathToNotification, notificationBuilder);\r
+               addedNotifications.add(notificationBuilder);\r
+\r
+               return notificationBuilder;\r
+       }\r
+\r
+       public FeatureBuilder addFeature(QName featureName, Stack<String> parentPath) {\r
+               List<String> pathToFeature = new ArrayList<String>(parentPath);\r
+               pathToFeature.add(featureName.getLocalName());\r
+\r
+               FeatureBuilder builder = new FeatureBuilder(featureName);\r
+               addedFeatures.put(pathToFeature, builder);\r
+               return builder;\r
+       }\r
+\r
+       public TypedefBuilder addTypedef(QName typeDefName, Stack<String> parentPath) {\r
+               List<String> pathToType = new ArrayList<String>(parentPath);\r
+               TypedefBuilder builder = new TypedefBuilder(typeDefName);\r
+               TypeDefinitionAwareBuilder parent = (TypeDefinitionAwareBuilder)moduleNodes.get(pathToType);\r
+               if(parent != null) {\r
+                       parent.addTypedef(builder);\r
+               }\r
+               pathToType.add(typeDefName.getLocalName());\r
+               addedTypedefs.put(pathToType, builder);\r
+               moduleNodes.put(pathToType, builder);\r
+               return builder;\r
+       }\r
+\r
+       public Set<TypeDefinitionBuilder> getModuleTypedefs() {\r
+               Set<TypeDefinitionBuilder> typedefs = new HashSet<TypeDefinitionBuilder>();\r
+               for(Map.Entry<List<String>, TypeDefinitionBuilder> entry : addedTypedefs.entrySet()) {\r
+                       if(entry.getKey().size() == 2) {\r
+                               typedefs.add(entry.getValue());\r
+                       }\r
+               }\r
+               return typedefs;\r
+       }\r
+\r
+       public void setType(TypeDefinition<?> type, Stack<String> parentPath) {\r
+               TypeAwareBuilder parent = (TypeAwareBuilder)moduleNodes.get(parentPath);\r
+               parent.setType(type);\r
+       }\r
+\r
+       public DeviationBuilder addDeviation(String targetPath) {\r
+               DeviationBuilder builder = new DeviationBuilder(targetPath);\r
+               addedDeviations.put(targetPath, builder);\r
+               return builder;\r
+       }\r
+\r
+       public MustDefinitionBuilder addMustDefinition(String xpathStr, Stack<String> parentPath) {\r
+               MustAwareBuilder parent = (MustAwareBuilder)moduleNodes.get(parentPath);\r
+               String path = parentPath.get(parentPath.size()-1);\r
+               if(parent == null) {\r
+                       for(Map.Entry<String, DeviationBuilder> db : addedDeviations.entrySet()) {\r
+                               String key = db.getKey();\r
+                               if(key.equals(path)) {\r
+                                       parent = db.getValue();\r
+                               }\r
+                       }\r
+               }\r
+               MustDefinitionBuilder builder = new MustDefinitionBuilder(xpathStr);\r
+               parent.setMustDefinitionBuilder(builder);\r
+               return builder;\r
+       }\r
+\r
+       public ModuleBuilder addSubmodule(QName qname) {\r
+               ModuleBuilder submoduleBuilder = new ModuleBuilder(qname.getLocalName());\r
+               return submoduleBuilder;\r
+       }\r
+\r
+\r
+\r
+       private class ModuleImpl implements Module {\r
+\r
+       private URI namespace;\r
+       private final String name;\r
+       private Date revision;\r
+       private String prefix;\r
+       private String yangVersion;\r
+       private String description;\r
+       private String reference;\r
+       private String organization;\r
+       private String contact;\r
+       private Set<ModuleImport> imports;\r
+       private Set<FeatureDefinition> features;\r
+       private Set<TypeDefinition<?>> typeDefinitions;\r
+       private Set<NotificationDefinition> notifications;\r
+       private Set<AugmentationSchema> augmentations;\r
+       private Set<RpcDefinition> rpcs;\r
+       private Set<Deviation> deviations;\r
+       private Map<QName, DataSchemaNode> childNodes;\r
+       private Set<GroupingDefinition> groupings;\r
+       private Set<UsesNode> uses;\r
+\r
+       private ModuleImpl(String name) {\r
+               this.name = name;\r
+       }\r
+\r
+\r
+       @Override\r
+       public URI getNamespace() {\r
+               return namespace;\r
+       }\r
+       private void setNamespace(URI namespace) {\r
+               this.namespace = namespace;\r
+       }\r
+\r
+       @Override\r
+       public String getName() {\r
+               return name;\r
+       }\r
+\r
+       @Override\r
+       public Date getRevision() {\r
+               return revision;\r
+       }\r
+       private void setRevision(Date revision) {\r
+               this.revision = revision;\r
+       }\r
+\r
+       @Override\r
+       public String getPrefix() {\r
+               return prefix;\r
+       }\r
+       private void setPrefix(String prefix) {\r
+               this.prefix = prefix;\r
+       }\r
+\r
+       @Override\r
+       public String getYangVersion() {\r
+               return yangVersion;\r
+       }\r
+       private void setYangVersion(String yangVersion) {\r
+               this.yangVersion = yangVersion;\r
+       }\r
+\r
+       @Override\r
+       public String getDescription() {\r
+               return description;\r
+       }\r
+       private void setDescription(String description) {\r
+               this.description = description;\r
+       }\r
+\r
+       @Override\r
+       public String getReference() {\r
+               return reference;\r
+       }\r
+       private void setReference(String reference) {\r
+               this.reference = reference;\r
+       }\r
+\r
+       @Override\r
+       public String getOrganization() {\r
+               return organization;\r
+       }\r
+       private void setOrganization(String organization) {\r
+               this.organization = organization;\r
+       }\r
+\r
+       @Override\r
+       public String getContact() {\r
+               return contact;\r
+       }\r
+       private void setContact(String contact) {\r
+               this.contact = contact;\r
+       }\r
+\r
+       @Override\r
+       public Set<ModuleImport> getImports() {\r
+               return imports;\r
+       }\r
+       private void setImports(Set<ModuleImport> imports) {\r
+               this.imports = imports;\r
+       }\r
+\r
+       @Override\r
+       public Set<FeatureDefinition> getFeatures() {\r
+               return features;\r
+       }\r
+       private void setFeatures(Set<FeatureDefinition> features) {\r
+               this.features = features;\r
+       }\r
+\r
+       @Override\r
+       public Set<TypeDefinition<?>> getTypeDefinitions() {\r
+               return typeDefinitions;\r
+       }\r
+       private void setTypeDefinitions(Set<TypeDefinition<?>> typeDefinitions) {\r
+               this.typeDefinitions = typeDefinitions;\r
+       }\r
+\r
+       @Override\r
+       public Set<NotificationDefinition> getNotifications() {\r
+               return notifications;\r
+       }\r
+       private void setNotifications(Set<NotificationDefinition> notifications) {\r
+               this.notifications = notifications;\r
+       }\r
+\r
+       @Override\r
+               public Set<AugmentationSchema> getAugmentations() {\r
+                       return augmentations;\r
+               }\r
+       private void setAugmentations(Set<AugmentationSchema> augmentations) {\r
+                       this.augmentations = augmentations;\r
+               }\r
+\r
+       @Override\r
+       public Set<RpcDefinition> getRpcs() {\r
+               return rpcs;\r
+       }\r
+       private void setRpcs(Set<RpcDefinition> rpcs) {\r
+               this.rpcs = rpcs;\r
+       }\r
+\r
+       @Override\r
+       public Set<Deviation> getDeviations() {\r
+               return deviations;\r
+       }\r
+       private void setDeviations(Set<Deviation> deviations) {\r
+               this.deviations = deviations;\r
+       }\r
+\r
+       @Override\r
+       public Set<DataSchemaNode> getChildNodes() {\r
+               return new HashSet<DataSchemaNode>(childNodes.values());\r
+       }\r
+       private void setChildNodes(Map<QName, DataSchemaNode> childNodes) {\r
+               this.childNodes = childNodes;\r
+       }\r
+\r
+       @Override\r
+       public Set<GroupingDefinition> getGroupings() {\r
+               return groupings;\r
+       }\r
+       private void setGroupings(Set<GroupingDefinition> groupings) {\r
+               this.groupings = groupings;\r
+       }\r
+\r
+       @Override\r
+       public Set<UsesNode> getUses() {\r
+                       return uses;\r
+               }\r
+               private void setUses(Set<UsesNode> uses) {\r
+                       this.uses = uses;\r
+               }\r
+\r
+       @Override\r
+               public DataSchemaNode getDataChildByName(QName name) {\r
+                       return childNodes.get(name);\r
+               }\r
+               @Override\r
+               public DataSchemaNode getDataChildByName(String name) {\r
+                       DataSchemaNode result = null;\r
+                       for(Map.Entry<QName, DataSchemaNode> entry : childNodes.entrySet()) {\r
+                               if(entry.getKey().getLocalName().equals(name)) {\r
+                                       result = entry.getValue();\r
+                                       break;\r
+                               }\r
+                       }\r
+                       return result;\r
+               }\r
+\r
+               @Override\r
+               public String toString() {\r
+                       StringBuilder sb = new StringBuilder(ModuleImpl.class.getSimpleName());\r
+                       sb.append("[\n");\r
+                       sb.append("name="+ name +",\n");\r
+                       sb.append("namespace="+ namespace +",\n");\r
+                       sb.append("revision="+ revision +",\n");\r
+                       sb.append("prefix="+ prefix +",\n");\r
+                       sb.append("yangVersion="+ yangVersion +",\n");\r
+                       sb.append("description="+ description +",\n");\r
+                       sb.append("reference="+ reference +",\n");\r
+                       sb.append("organization="+ organization +",\n");\r
+                       sb.append("contact="+ contact +",\n");\r
+                       sb.append("childNodes="+ childNodes.values() +",\n");\r
+                       sb.append("groupings="+ groupings +",\n");\r
+                       sb.append("imports="+ imports +",\n");\r
+                       sb.append("features="+ features +",\n");\r
+                       sb.append("typeDefinitions="+ typeDefinitions +",\n");\r
+                       sb.append("notifications="+ notifications +",\n");\r
+                       sb.append("augmentations="+ augmentations +",\n");\r
+                       sb.append("rpcs="+ rpcs +",\n");\r
+                       sb.append("deviations="+ deviations +"\n");\r
+                       sb.append("]");\r
+                       return sb.toString();\r
+               }\r
+\r
+    }\r
+\r
+       private ModuleImport createModuleImport(final String moduleName, final Date revision, final String prefix) {\r
+               ModuleImport moduleImport = new ModuleImport() {\r
+                       @Override\r
+                       public String getModuleName() {\r
+                               return moduleName;\r
+                       }\r
+                       @Override\r
+                       public Date getRevision() {\r
+                               return revision;\r
+                       }\r
+                       @Override\r
+                       public String getPrefix() {\r
+                               return prefix;\r
+                       }\r
+\r
+                       @Override\r
+                       public int hashCode() {\r
+                               final int prime = 31;\r
+                   int result = 1;\r
+                   result = prime * result + ((moduleName == null) ? 0 : moduleName.hashCode());\r
+                   result = prime * result + ((revision == null) ? 0 : revision.hashCode());\r
+                   result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());\r
+                   return result;\r
+                       }\r
+\r
+                       @Override\r
+               public boolean equals(Object obj) {\r
+                   if (this == obj) {\r
+                       return true;\r
+                   }\r
+                   if (obj == null) {\r
+                       return false;\r
+                   }\r
+                   if (getClass() != obj.getClass()) {\r
+                       return false;\r
+                   }\r
+                   ModuleImport other = (ModuleImport) obj;\r
+                   if (getModuleName() == null) {\r
+                       if (other.getModuleName() != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!getModuleName().equals(other.getModuleName())) {\r
+                       return false;\r
+                   }\r
+                   if (getRevision() == null) {\r
+                       if (other.getRevision() != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!getRevision().equals(other.getRevision())) {\r
+                       return false;\r
+                   }\r
+                   if (getPrefix() == null) {\r
+                       if (other.getPrefix() != null) {\r
+                           return false;\r
+                       }\r
+                   } else if (!getPrefix().equals(other.getPrefix())) {\r
+                       return false;\r
+                   }\r
+                   return true;\r
+               }\r
+\r
+                       @Override\r
+                       public String toString() {\r
+                               return "ModuleImport[moduleName="+ moduleName +", revision="+ revision +", prefix="+ prefix +"]";\r
+                       }\r
+               };\r
+               return moduleImport;\r
+       }\r
+\r
+       /**\r
+        * Traverse through given addedChilds and add only direct module childs. Direct\r
+        * module child path size is 2 (1. module name, 2. child name).\r
+        *\r
+        * @param addedChilds\r
+        * @return map of children, where key is child QName and value is child itself\r
+        */\r
+       private Map<QName, DataSchemaNode> buildModuleChildNodes(\r
+                       Map<List<String>, DataSchemaNodeBuilder> addedChilds) {\r
+               final Map<QName, DataSchemaNode> childNodes = new HashMap<QName, DataSchemaNode>();\r
+               for (Map.Entry<List<String>, DataSchemaNodeBuilder> entry : addedChilds\r
+                               .entrySet()) {\r
+                       if (entry.getKey().size() == 2) {\r
+                               DataSchemaNode node = entry.getValue().build();\r
+                               QName qname = entry.getValue().getQName();\r
+                               childNodes.put(qname, node);\r
+                       }\r
+               }\r
+               return childNodes;\r
+       }\r
+\r
+       /**\r
+        * Traverse through given addedGroupings and add only direct module groupings. Direct\r
+        * module grouping path size is 2 (1. module name, 2. grouping name).\r
+        *\r
+        * @param addedGroupings\r
+        * @return set of built GroupingDefinition objects\r
+        */\r
+       private Set<GroupingDefinition> buildModuleGroupings(Map<List<String>, GroupingBuilder> addedGroupings) {\r
+               final Set<GroupingDefinition> groupings = new HashSet<GroupingDefinition>();\r
+               for(Map.Entry<List<String>, GroupingBuilder> entry : addedGroupings.entrySet()) {\r
+                       if(entry.getKey().size() == 2) {\r
+                               groupings.add(entry.getValue().build());\r
+                       }\r
+               }\r
+               return groupings;\r
+       }\r
+\r
+       /**\r
+        * Traverse through given addedRpcs and build RpcDefinition objects.\r
+        * @param addedRpcs\r
+        * @return set of built RpcDefinition objects\r
+        */\r
+       private Set<RpcDefinition> buildModuleRpcs(Map<List<String>, RpcDefinitionBuilder> addedRpcs) {\r
+               final Set<RpcDefinition> rpcs = new HashSet<RpcDefinition>();\r
+               RpcDefinitionBuilder builder;\r
+               for(Map.Entry<List<String>, RpcDefinitionBuilder> entry : addedRpcs.entrySet()) {\r
+                       builder = entry.getValue();\r
+                       RpcDefinition rpc = builder.build();\r
+                       rpcs.add(rpc);\r
+               }\r
+               return rpcs;\r
+       }\r
+\r
+       /**\r
+        * Traverse through given addedTypedefs and add only direct module typedef statements. Direct\r
+        * module typedef path size is 2 (1. module name, 2. typedef name).\r
+        *\r
+        * @param addedTypedefs\r
+        * @return set of built module typedef statements\r
+        */\r
+       private Set<TypeDefinition<?>> buildModuleTypedefs(Map<List<String>, TypeDefinitionBuilder> addedTypedefs) {\r
+               Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();\r
+               for(Map.Entry<List<String>, TypeDefinitionBuilder> entry : addedTypedefs.entrySet()) {\r
+                       if(entry.getKey().size() == 2) {\r
+                               TypeDefinition<? extends TypeDefinition<?>> node = entry.getValue().build();\r
+                               typedefs.add(node);\r
+                       }\r
+               }\r
+               return typedefs;\r
+       }\r
+\r
+       /**\r
+        * Traverse through given addedUsesNodes and add only direct module uses nodes. Direct\r
+        * module uses node path size is 2 (1. module name, 2. uses name).\r
+        *\r
+        * @param addedUsesNodes\r
+        * @return set of built module uses nodes\r
+        */\r
+       private Set<UsesNode> buildUsesNodes(Map<List<String>, UsesNodeBuilder> addedUsesNodes) {\r
+               final Set<UsesNode> usesNodeDefinitions = new HashSet<UsesNode>();\r
+               for (Map.Entry<List<String>, UsesNodeBuilder> entry : addedUsesNodes.entrySet()) {\r
+                       if (entry.getKey().size() == 2) {\r
+                               usesNodeDefinitions.add(entry.getValue().build());\r
+                       }\r
+               }\r
+               return usesNodeDefinitions;\r
+       }\r
+\r
+       /**\r
+        * Traverse through given addedFeatures and add only direct module features. Direct\r
+        * module feature path size is 2 (1. module name, 2. feature name).\r
+        *\r
+        * @param addedFeatures\r
+        * @return set of built module features\r
+        */\r
+       private Set<FeatureDefinition> buildModuleFeatures(Map<List<String>, FeatureBuilder> addedFeatures) {\r
+               Set<FeatureDefinition> features = new HashSet<FeatureDefinition>();\r
+               for(Map.Entry<List<String>, FeatureBuilder> entry : addedFeatures.entrySet()) {\r
+                       if(entry.getKey().size() == 2) {\r
+                               features.add((FeatureDefinition)entry.getValue().build());\r
+                       }\r
+               }\r
+               return features;\r
+       }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/MustAwareBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/MustAwareBuilder.java
new file mode 100644 (file)
index 0000000..4798590
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.model.parser.builder;
+
+/**
+ * Interface for all nodes which can contain 'must' definition: [container, leaf, leaf-list, list, anyxml, deviate]
+ */
+public interface MustAwareBuilder {
+
+       void setMustDefinitionBuilder(MustDefinitionBuilder mustDefinitionBuilder);
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/MustDefinitionBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/MustDefinitionBuilder.java
new file mode 100644 (file)
index 0000000..fecfae8
--- /dev/null
@@ -0,0 +1,86 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import org.opendaylight.controller.model.parser.api.Builder;\r
+import org.opendaylight.controller.yang.model.api.MustDefinition;\r
+import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;\r
+\r
+\r
+public class MustDefinitionBuilder implements Builder {\r
+\r
+       private final MustDefinitionImpl instance;\r
+\r
+       MustDefinitionBuilder(String xpathStr) {\r
+               instance = new MustDefinitionImpl(xpathStr);\r
+       }\r
+\r
+       @Override\r
+       public MustDefinition build() {\r
+               return instance;\r
+       }\r
+\r
+       public void setDescription(String description) {\r
+               instance.setDescription(description);\r
+       }\r
+\r
+       public void setReference(String reference) {\r
+               instance.setReference(reference);\r
+       }\r
+\r
+       private static class MustDefinitionImpl implements MustDefinition {\r
+\r
+               private final String xpathStr;\r
+               private String description;\r
+               private String reference;\r
+\r
+               private MustDefinitionImpl(String xpathStr) {\r
+                       this.xpathStr = xpathStr;\r
+               }\r
+\r
+               @Override\r
+               public String getDescription() {\r
+                       return description;\r
+               }\r
+               private void setDescription(String description) {\r
+                       this.description = description;\r
+               }\r
+\r
+               @Override\r
+               public String getErrorAppTag() {\r
+                       // TODO Auto-generated method stub\r
+                       return null;\r
+               }\r
+\r
+               @Override\r
+               public String getErrorMessage() {\r
+                       // TODO Auto-generated method stub\r
+                       return null;\r
+               }\r
+\r
+               @Override\r
+               public String getReference() {\r
+                       return reference;\r
+               }\r
+               private void setReference(String reference) {\r
+                       this.reference = reference;\r
+               }\r
+\r
+               @Override\r
+               public RevisionAwareXPath getXpath() {\r
+                       // TODO Auto-generated method stub\r
+                       return null;\r
+               }\r
+\r
+               @Override\r
+               public String toString() {\r
+                       return MustDefinitionImpl.class.getSimpleName() +"[xpathStr="+ xpathStr +"]";\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/NotificationBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/NotificationBuilder.java
new file mode 100644 (file)
index 0000000..52decc0
--- /dev/null
@@ -0,0 +1,229 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.model.parser.api.AbstractChildNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.DataSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.GroupingBuilder;\r
+import org.opendaylight.controller.model.parser.api.SchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeDefinitionAwareBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeDefinitionBuilder;\r
+import org.opendaylight.controller.model.parser.api.UsesNodeBuilder;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;\r
+import org.opendaylight.controller.yang.model.api.NotificationDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaNode;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+import org.opendaylight.controller.yang.model.api.UsesNode;\r
+\r
+\r
+public class NotificationBuilder extends AbstractChildNodeBuilder implements TypeDefinitionAwareBuilder, SchemaNodeBuilder {\r
+\r
+       private final NotificationDefinitionImpl instance;\r
+       private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();\r
+       private final Set<UsesNodeBuilder> addedUsesNodes = new HashSet<UsesNodeBuilder>();\r
+\r
+       NotificationBuilder(QName qname) {\r
+               super(qname);\r
+               instance = new NotificationDefinitionImpl(qname);\r
+       }\r
+\r
+       @Override\r
+       public SchemaNode build() {\r
+               // CHILD NODES\r
+               Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();\r
+               for (DataSchemaNodeBuilder node : childNodes) {\r
+                       childs.put(node.getQName(), node.build());\r
+               }\r
+               instance.setChildNodes(childs);\r
+\r
+               // GROUPINGS\r
+               Set<GroupingDefinition> groupingDefinitions = new HashSet<GroupingDefinition>();\r
+               for (GroupingBuilder builder : groupings) {\r
+                       groupingDefinitions.add(builder.build());\r
+               }\r
+               instance.setGroupings(groupingDefinitions);\r
+\r
+               // TYPEDEFS\r
+               Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();\r
+               for (TypeDefinitionBuilder entry : addedTypedefs) {\r
+                       typedefs.add(entry.build());\r
+               }\r
+               instance.setTypeDefinitions(typedefs);\r
+\r
+               // USES\r
+               Set<UsesNode> uses = new HashSet<UsesNode>();\r
+               for (UsesNodeBuilder builder : addedUsesNodes) {\r
+                       uses.add(builder.build());\r
+               }\r
+               instance.setUses(uses);\r
+\r
+               return instance;\r
+       }\r
+\r
+       @Override\r
+       public void addTypedef(TypeDefinitionBuilder type) {\r
+               addedTypedefs.add(type);\r
+       }\r
+\r
+       @Override\r
+       public void addUsesNode(UsesNodeBuilder usesNodeBuilder) {\r
+               addedUsesNodes.add(usesNodeBuilder);\r
+       }\r
+\r
+       @Override\r
+       public void setPath(SchemaPath schemaPath) {\r
+               instance.setPath(schemaPath);\r
+       }\r
+\r
+       @Override\r
+       public void setDescription(String description) {\r
+               instance.setDescription(description);\r
+       }\r
+\r
+       @Override\r
+       public void setReference(String reference) {\r
+               instance.setReference(reference);\r
+       }\r
+\r
+       @Override\r
+       public void setStatus(Status status) {\r
+               instance.setStatus(status);\r
+       }\r
+\r
+\r
+       private class NotificationDefinitionImpl implements NotificationDefinition {\r
+\r
+               private final QName qname;\r
+               private SchemaPath path;\r
+               private String description;\r
+               private String reference;\r
+               private Status status;\r
+\r
+               private Map<QName, DataSchemaNode> childNodes;\r
+               private Set<GroupingDefinition> groupings;\r
+               private Set<TypeDefinition<?>> typeDefinitions;\r
+\r
+               private Set<UsesNode> uses;\r
+\r
+               private NotificationDefinitionImpl(QName qname) {\r
+                       this.qname = qname;\r
+               }\r
+\r
+               @Override\r
+               public QName getQName() {\r
+                       return qname;\r
+               }\r
+\r
+               @Override\r
+               public SchemaPath getPath() {\r
+                       return path;\r
+               }\r
+               private void setPath(SchemaPath path) {\r
+                       this.path = path;\r
+               }\r
+\r
+               @Override\r
+               public String getDescription() {\r
+                       return description;\r
+               }\r
+               private void setDescription(String description) {\r
+                       this.description = description;\r
+               }\r
+\r
+               @Override\r
+               public String getReference() {\r
+                       return reference;\r
+               }\r
+               private void setReference(String reference) {\r
+                       this.reference = reference;\r
+               }\r
+\r
+               @Override\r
+               public Status getStatus() {\r
+                       return status;\r
+               }\r
+               private void setStatus(Status status) {\r
+                       this.status = status;\r
+               }\r
+\r
+               @Override\r
+               public Set<DataSchemaNode> getChildNodes() {\r
+                       return new HashSet<DataSchemaNode>(childNodes.values());\r
+               }\r
+               private void setChildNodes(Map<QName, DataSchemaNode> childNodes) {\r
+                       this.childNodes = childNodes;\r
+               }\r
+\r
+               @Override\r
+               public Set<GroupingDefinition> getGroupings() {\r
+                       return groupings;\r
+               }\r
+               private void setGroupings(Set<GroupingDefinition> groupings) {\r
+                       this.groupings = groupings;\r
+               }\r
+\r
+               @Override\r
+               public Set<UsesNode> getUses() {\r
+                       return uses;\r
+               }\r
+               private void setUses(Set<UsesNode> uses) {\r
+                       this.uses = uses;\r
+               }\r
+\r
+               @Override\r
+               public Set<TypeDefinition<?>> getTypeDefinitions() {\r
+                       return typeDefinitions;\r
+               }\r
+               private void setTypeDefinitions(Set<TypeDefinition<?>> typeDefinitions) {\r
+                       this.typeDefinitions = typeDefinitions;\r
+               }\r
+\r
+               @Override\r
+               public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+                       // TODO Auto-generated method stub\r
+                       return null;\r
+               }\r
+\r
+               @Override\r
+               public DataSchemaNode getDataChildByName(QName name) {\r
+                       return childNodes.get(name);\r
+               }\r
+\r
+               @Override\r
+               public DataSchemaNode getDataChildByName(String name) {\r
+                       DataSchemaNode result = null;\r
+                       for (Map.Entry<QName, DataSchemaNode> entry : childNodes.entrySet()) {\r
+                               if (entry.getKey().getLocalName().equals(name)) {\r
+                                       result = entry.getValue();\r
+                                       break;\r
+                               }\r
+                       }\r
+                       return result;\r
+               }\r
+\r
+               @Override\r
+               public String toString() {\r
+                       StringBuilder sb = new StringBuilder(\r
+                                       NotificationDefinitionImpl.class.getSimpleName());\r
+                       sb.append("[qname=" + qname + "]");\r
+                       return sb.toString();\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/RpcDefinitionBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/RpcDefinitionBuilder.java
new file mode 100644 (file)
index 0000000..55f361b
--- /dev/null
@@ -0,0 +1,264 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.model.parser.api.ChildNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.DataSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.GroupingBuilder;\r
+import org.opendaylight.controller.model.parser.api.SchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeDefinitionAwareBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeDefinitionBuilder;\r
+import org.opendaylight.controller.model.parser.api.UsesNodeBuilder;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;\r
+import org.opendaylight.controller.yang.model.api.RpcDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public class RpcDefinitionBuilder implements ChildNodeBuilder,\r
+        SchemaNodeBuilder, TypeDefinitionAwareBuilder {\r
+\r
+    private final RpcDefinitionImpl instance;\r
+    private final QName qname;\r
+    private ContainerSchemaNodeBuilder inputBuilder;\r
+    private ContainerSchemaNodeBuilder outputBuilder;\r
+    private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();\r
+    private final Set<GroupingBuilder> addedGroupings = new HashSet<GroupingBuilder>();\r
+\r
+    RpcDefinitionBuilder(QName qname) {\r
+        this.qname = qname;\r
+        this.instance = new RpcDefinitionImpl(qname);\r
+    }\r
+\r
+    @Override\r
+    public RpcDefinition build() {\r
+        final ContainerSchemaNode input = inputBuilder.build();\r
+        final ContainerSchemaNode output = outputBuilder.build();\r
+        instance.setInput(input);\r
+        instance.setOutput(output);\r
+\r
+        // TYPEDEFS\r
+        Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();\r
+        for (TypeDefinitionBuilder entry : addedTypedefs) {\r
+            typedefs.add(entry.build());\r
+        }\r
+        instance.setTypeDefinitions(typedefs);\r
+\r
+        // GROUPINGS\r
+        final Set<GroupingDefinition> groupings = new HashSet<GroupingDefinition>();\r
+        for (GroupingBuilder entry : addedGroupings) {\r
+            groupings.add(entry.build());\r
+        }\r
+        instance.setGroupings(groupings);\r
+\r
+        return instance;\r
+    }\r
+\r
+    void setInput(ContainerSchemaNodeBuilder inputBuilder) {\r
+        this.inputBuilder = inputBuilder;\r
+    }\r
+\r
+    void setOutput(ContainerSchemaNodeBuilder outputBuilder) {\r
+        this.outputBuilder = outputBuilder;\r
+    }\r
+\r
+    @Override\r
+    public void addTypedef(TypeDefinitionBuilder type) {\r
+        addedTypedefs.add(type);\r
+    }\r
+\r
+    @Override\r
+    public void setPath(SchemaPath schemaPath) {\r
+        instance.setPath(schemaPath);\r
+    }\r
+\r
+    @Override\r
+    public void setDescription(String description) {\r
+        instance.setDescription(description);\r
+    }\r
+\r
+    @Override\r
+    public void setReference(String reference) {\r
+        instance.setReference(reference);\r
+    }\r
+\r
+    @Override\r
+    public void setStatus(Status status) {\r
+        instance.setStatus(status);\r
+    }\r
+\r
+    @Override\r
+    public QName getQName() {\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public void addChildNode(DataSchemaNodeBuilder childNode) {\r
+        throw new UnsupportedOperationException(\r
+                "Can not add child node to rpc definition: rpc can not contains child nodes.");\r
+    }\r
+\r
+    @Override\r
+    public void addGrouping(GroupingBuilder grouping) {\r
+        addedGroupings.add(grouping);\r
+    }\r
+\r
+    @Override\r
+    public void addUsesNode(UsesNodeBuilder usesBuilder) {\r
+        throw new UnsupportedOperationException(\r
+                "Can not add uses node to rpc definition: rpc can not contains uses nodes.");\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        return qname.hashCode();\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (!(obj instanceof RpcDefinitionBuilder)) {\r
+            return false;\r
+        }\r
+        RpcDefinitionBuilder other = (RpcDefinitionBuilder) obj;\r
+        if (other.qname == null) {\r
+            if (this.qname != null) {\r
+                return false;\r
+            }\r
+        } else if (!other.qname.equals(this.qname)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    private static class RpcDefinitionImpl implements RpcDefinition {\r
+\r
+        private final QName qname;\r
+        private SchemaPath path;\r
+        private String description;\r
+        private String reference;\r
+        private Status status;\r
+\r
+        private ContainerSchemaNode input;\r
+        private ContainerSchemaNode output;\r
+\r
+        private Set<TypeDefinition<?>> typeDefinitions;\r
+        private Set<GroupingDefinition> groupings;\r
+\r
+        private RpcDefinitionImpl(QName qname) {\r
+            this.qname = qname;\r
+        }\r
+\r
+        @Override\r
+        public QName getQName() {\r
+            return qname;\r
+        }\r
+\r
+        @Override\r
+        public SchemaPath getPath() {\r
+            return path;\r
+        }\r
+\r
+        private void setPath(SchemaPath path) {\r
+            this.path = path;\r
+        }\r
+\r
+        @Override\r
+        public String getDescription() {\r
+            return description;\r
+        }\r
+\r
+        private void setDescription(String description) {\r
+            this.description = description;\r
+        }\r
+\r
+        @Override\r
+        public String getReference() {\r
+            return reference;\r
+        }\r
+\r
+        private void setReference(String reference) {\r
+            this.reference = reference;\r
+        }\r
+\r
+        @Override\r
+        public Status getStatus() {\r
+            return status;\r
+        }\r
+\r
+        private void setStatus(Status status) {\r
+            this.status = status;\r
+        }\r
+\r
+        @Override\r
+        public ContainerSchemaNode getInput() {\r
+            return input;\r
+        }\r
+\r
+        private void setInput(ContainerSchemaNode input) {\r
+            this.input = input;\r
+        }\r
+\r
+        @Override\r
+        public ContainerSchemaNode getOutput() {\r
+            return output;\r
+        }\r
+\r
+        private void setOutput(ContainerSchemaNode output) {\r
+            this.output = output;\r
+        }\r
+\r
+        @Override\r
+        public Set<TypeDefinition<?>> getTypeDefinitions() {\r
+            return typeDefinitions;\r
+        }\r
+\r
+        private void setTypeDefinitions(Set<TypeDefinition<?>> typeDefinitions) {\r
+            this.typeDefinitions = typeDefinitions;\r
+        }\r
+\r
+        @Override\r
+        public Set<GroupingDefinition> getGroupings() {\r
+            return groupings;\r
+        }\r
+\r
+        private void setGroupings(Set<GroupingDefinition> groupings) {\r
+            this.groupings = groupings;\r
+        }\r
+\r
+        @Override\r
+        public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+            // TODO Auto-generated method stub\r
+            return null;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            StringBuilder sb = new StringBuilder(\r
+                    RpcDefinitionImpl.class.getSimpleName() + "[");\r
+            sb.append("qname=" + qname);\r
+            sb.append(", path=" + path);\r
+            sb.append(", description=" + description);\r
+            sb.append(", reference=" + reference);\r
+            sb.append(", status=" + status);\r
+            sb.append(", input=" + input);\r
+            sb.append(", output=" + output + "]");\r
+            return sb.toString();\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/TypedefBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/TypedefBuilder.java
new file mode 100644 (file)
index 0000000..a6a3c60
--- /dev/null
@@ -0,0 +1,196 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.parser.api.SchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeAwareBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeDefinitionBuilder;\r
+import org.opendaylight.controller.model.util.UnknownType;\r
+import org.opendaylight.controller.model.util.YangTypesConverter;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+\r
+public class TypedefBuilder implements TypeDefinitionBuilder, SchemaNodeBuilder, TypeAwareBuilder {\r
+\r
+       private final QName qname;\r
+       private SchemaPath schemaPath;\r
+       private TypeDefinition<?> baseType;\r
+\r
+       private String description;\r
+       private String reference;\r
+       private Status status;\r
+\r
+       TypedefBuilder(QName qname) {\r
+               this.qname = qname;\r
+       }\r
+\r
+       @Override\r
+       public TypeDefinition<? extends TypeDefinition<?>> build() {\r
+               final TypeDefinition<?> type = YangTypesConverter.javaTypeForBaseYangType(qname);\r
+               if(type != null) {\r
+                       return type;\r
+               } else {\r
+                       if(baseType != null) {\r
+                               // typedef\r
+                               TypeDefinitionImpl instance = new TypeDefinitionImpl(qname);\r
+                               instance.setDescription(description);\r
+                               instance.setReference(reference);\r
+                               instance.setStatus(status);\r
+                               instance.setPath(schemaPath);\r
+                               instance.setBaseType(baseType);\r
+                               return instance;\r
+                       } else {\r
+                               // type\r
+                               final UnknownType.Builder unknownBuilder = new UnknownType.Builder(qname, description, reference);\r
+                               unknownBuilder.status(status);\r
+                               return unknownBuilder.build();\r
+                       }\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public QName getQName() {\r
+               return qname;\r
+       }\r
+\r
+       @Override\r
+       public void setPath(final SchemaPath schemaPath) {\r
+               this.schemaPath = schemaPath;\r
+       }\r
+\r
+       @Override\r
+       public void setDescription(final String description) {\r
+               this.description = description;\r
+       }\r
+\r
+       @Override\r
+       public void setReference(final String reference) {\r
+               this.reference = reference;\r
+       }\r
+\r
+       @Override\r
+       public void setStatus(final Status status) {\r
+               if(status != null) {\r
+                       this.status = status;\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public TypeDefinition<?> getType() {\r
+               return baseType;\r
+       }\r
+\r
+       @Override\r
+       public void setType(TypeDefinition<?> baseType) {\r
+               this.baseType = baseType;\r
+       }\r
+\r
+       @Override\r
+       public TypeDefinition<?> getBaseType() {\r
+               return baseType;\r
+       }\r
+\r
+\r
+\r
+       private static class TypeDefinitionImpl<T extends TypeDefinition<T>> implements TypeDefinition<T> {\r
+\r
+               private final QName qname;\r
+               private SchemaPath path;\r
+               private String description;\r
+               private String reference;\r
+               private Status status = Status.CURRENT;\r
+               private T baseType;\r
+\r
+               private TypeDefinitionImpl(QName qname) {\r
+                       this.qname = qname;\r
+               }\r
+\r
+               @Override\r
+               public QName getQName() {\r
+                       return qname;\r
+               }\r
+\r
+               @Override\r
+               public SchemaPath getPath() {\r
+                       return path;\r
+               }\r
+               private void setPath(SchemaPath path) {\r
+                       this.path = path;\r
+               }\r
+\r
+               @Override\r
+               public String getDescription() {\r
+                       return description;\r
+               }\r
+               private void setDescription(String description) {\r
+                       this.description = description;\r
+               }\r
+\r
+               @Override\r
+               public String getReference() {\r
+                       return reference;\r
+               }\r
+               private void setReference(String reference) {\r
+                       this.reference = reference;\r
+               }\r
+\r
+               @Override\r
+               public Status getStatus() {\r
+                       return status;\r
+               }\r
+               private void setStatus(Status status) {\r
+                       this.status = status;\r
+               }\r
+\r
+               @Override\r
+               public T getBaseType() {\r
+                       return baseType;\r
+               }\r
+               private void setBaseType(T type) {\r
+                       this.baseType = type;\r
+               }\r
+\r
+               @Override\r
+               public String getUnits() {\r
+                       // TODO Auto-generated method stub\r
+                       return null;\r
+               }\r
+\r
+               @Override\r
+               public Object getDefaultValue() {\r
+                       // TODO Auto-generated method stub\r
+                       return null;\r
+               }\r
+\r
+               @Override\r
+               public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+                       // TODO Auto-generated method stub\r
+                       return null;\r
+               }\r
+\r
+               @Override\r
+               public String toString() {\r
+                       final StringBuilder sb = new StringBuilder(TypeDefinitionImpl.class.getSimpleName());\r
+                       sb.append("[");\r
+                       sb.append("qname="+ qname);\r
+                       sb.append(", path="+ path);\r
+                       sb.append(", description="+ description);\r
+                       sb.append(", reference="+ reference);\r
+                       sb.append(", status="+ status);\r
+                       sb.append(", baseType="+ baseType +"]");\r
+                       return sb.toString();\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/UsesNodeBuilderImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/UsesNodeBuilderImpl.java
new file mode 100644 (file)
index 0000000..df626f1
--- /dev/null
@@ -0,0 +1,78 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.parser.api.AugmentationSchemaBuilder;\r
+import org.opendaylight.controller.model.parser.api.Builder;\r
+import org.opendaylight.controller.model.parser.api.UsesNodeBuilder;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.UsesNode;\r
+\r
+public class UsesNodeBuilderImpl implements UsesNodeBuilder, Builder {\r
+\r
+    private final String groupingPathStr;\r
+\r
+    UsesNodeBuilderImpl(String groupingPathStr) {\r
+        this.groupingPathStr = groupingPathStr;\r
+    }\r
+\r
+    @Override\r
+    public UsesNode build() {\r
+        SchemaPath groupingPath = parseUsesPath(groupingPathStr);\r
+        final UsesNodeImpl instance = new UsesNodeImpl(groupingPath);\r
+        return instance;\r
+    }\r
+\r
+    public void addAugment(AugmentationSchemaBuilder augmentBuilder) {\r
+        // TODO:\r
+    }\r
+\r
+    private SchemaPath parseUsesPath(String augmentPath) {\r
+        String[] splittedPath = augmentPath.split("/");\r
+        List<QName> path = new ArrayList<QName>();\r
+        QName name;\r
+        for (String pathElement : splittedPath) {\r
+            String[] splittedElement = pathElement.split(":");\r
+            if (splittedElement.length == 1) {\r
+                name = new QName(null, null, null, splittedElement[0]);\r
+            } else {\r
+                name = new QName(null, null, splittedElement[0],\r
+                        splittedElement[1]);\r
+            }\r
+            path.add(name);\r
+        }\r
+        // TODO: absolute vs relative?\r
+        return new SchemaPath(path, false);\r
+    }\r
+\r
+    private static class UsesNodeImpl implements UsesNode {\r
+\r
+        private final SchemaPath groupingPath;\r
+\r
+        private UsesNodeImpl(SchemaPath groupingPath) {\r
+            this.groupingPath = groupingPath;\r
+        }\r
+\r
+        @Override\r
+        public SchemaPath getGroupingPath() {\r
+            return groupingPath;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            return UsesNodeImpl.class.getSimpleName() + "[groupingPath="\r
+                    + groupingPath + "]";\r
+        }\r
+\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/YangModelBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/builder/YangModelBuilder.java
new file mode 100644 (file)
index 0000000..bc0f363
--- /dev/null
@@ -0,0 +1,198 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.antlr.v4.runtime.ANTLRInputStream;\r
+import org.antlr.v4.runtime.CommonTokenStream;\r
+import org.antlr.v4.runtime.tree.ParseTree;\r
+import org.antlr.v4.runtime.tree.ParseTreeWalker;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangLexer;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser;\r
+import org.opendaylight.controller.model.parser.api.AugmentationSchemaBuilder;\r
+import org.opendaylight.controller.model.parser.api.AugmentationTargetBuilder;\r
+import org.opendaylight.controller.model.parser.api.Builder;\r
+import org.opendaylight.controller.model.parser.api.TypeAwareBuilder;\r
+import org.opendaylight.controller.model.parser.api.TypeDefinitionBuilder;\r
+import org.opendaylight.controller.model.parser.impl.YangModelParserImpl;\r
+import org.opendaylight.controller.model.util.UnknownType;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.AugmentationSchema;\r
+import org.opendaylight.controller.yang.model.api.Module;\r
+import org.opendaylight.controller.yang.model.api.ModuleImport;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+public class YangModelBuilder implements Builder {\r
+\r
+    private static final Logger logger = LoggerFactory\r
+            .getLogger(YangModelBuilder.class);\r
+\r
+    private final Map<String, ModuleBuilder> modules = new HashMap<String, ModuleBuilder>();\r
+\r
+    public YangModelBuilder(String... yangFiles) {\r
+        final YangModelParserImpl yangModelParser = new YangModelParserImpl();\r
+        final ParseTreeWalker walker = new ParseTreeWalker();\r
+\r
+        List<ParseTree> trees = parseYangFiles(yangFiles);\r
+\r
+        ModuleBuilder[] builders = new ModuleBuilder[trees.size()];\r
+\r
+        for (int i = 0; i < trees.size(); i++) {\r
+            walker.walk(yangModelParser, trees.get(i));\r
+            builders[i] = yangModelParser.getModuleBuilder();\r
+        }\r
+\r
+        for (ModuleBuilder builder : builders) {\r
+            final String builderName = builder.getName();\r
+            modules.put(builderName, builder);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public Map<String, Module> build() {\r
+        Map<String, Module> builtModules = new HashMap<String, Module>();\r
+        for (ModuleBuilder builder : modules.values()) {\r
+            validateBuilder(builder);\r
+            builtModules.put(builder.getName(), builder.build());\r
+        }\r
+        return builtModules;\r
+    }\r
+\r
+    private void validateBuilder(ModuleBuilder builder) {\r
+        resolveTypedefs(builder);\r
+        resolveAugments(builder);\r
+    }\r
+\r
+    private void resolveTypedefs(ModuleBuilder builder) {\r
+        Map<List<String>, TypeAwareBuilder> dirtyNodes = builder\r
+                .getDirtyNodes();\r
+        if (dirtyNodes.size() == 0) {\r
+            return;\r
+        } else {\r
+            for (Map.Entry<List<String>, TypeAwareBuilder> entry : dirtyNodes\r
+                    .entrySet()) {\r
+                TypeAwareBuilder tab = entry.getValue();\r
+                TypeDefinitionBuilder tdb = findTypeAwareBuilder(\r
+                        entry.getValue(), builder);\r
+                tab.setType(tdb.build());\r
+            }\r
+        }\r
+    }\r
+\r
+    private TypeDefinitionBuilder findTypeAwareBuilder(\r
+            TypeAwareBuilder typeBuilder, ModuleBuilder builder) {\r
+        UnknownType type = (UnknownType) typeBuilder.getType();\r
+        QName typeQName = type.getQName();\r
+        String typeName = type.getQName().getLocalName();\r
+        String prefix = typeQName.getPrefix();\r
+\r
+        ModuleBuilder dependentModuleBuilder;\r
+        if (prefix.equals(builder.getPrefix())) {\r
+            dependentModuleBuilder = builder;\r
+        } else {\r
+            String dependentModuleName = getDependentModuleName(builder, prefix);\r
+            dependentModuleBuilder = modules.get(dependentModuleName);\r
+        }\r
+\r
+        Set<TypeDefinitionBuilder> typedefs = dependentModuleBuilder\r
+                .getModuleTypedefs();\r
+\r
+        TypeDefinitionBuilder lookedUpBuilder = null;\r
+        for (TypeDefinitionBuilder tdb : typedefs) {\r
+            QName qname = tdb.getQName();\r
+            if (qname.getLocalName().equals(typeName)) {\r
+                lookedUpBuilder = tdb;\r
+                break;\r
+            }\r
+        }\r
+\r
+        if (lookedUpBuilder.getBaseType() instanceof UnknownType) {\r
+            return findTypeAwareBuilder((TypeAwareBuilder) lookedUpBuilder,\r
+                    dependentModuleBuilder);\r
+        } else {\r
+            return lookedUpBuilder;\r
+        }\r
+    }\r
+\r
+    private void resolveAugments(ModuleBuilder builder) {\r
+        Set<AugmentationSchemaBuilder> augmentBuilders = builder\r
+                .getAddedAugments();\r
+\r
+        Set<AugmentationSchema> augments = new HashSet<AugmentationSchema>();\r
+        for (AugmentationSchemaBuilder augmentBuilder : augmentBuilders) {\r
+            SchemaPath augmentTargetSchemaPath = augmentBuilder.getTargetPath();\r
+            String prefix = null;\r
+            List<String> augmentTargetPath = new ArrayList<String>();\r
+            for (QName pathPart : augmentTargetSchemaPath.getPath()) {\r
+                prefix = pathPart.getPrefix();\r
+                augmentTargetPath.add(pathPart.getLocalName());\r
+            }\r
+            String dependentModuleName = getDependentModuleName(builder, prefix);\r
+            augmentTargetPath.add(0, dependentModuleName);\r
+\r
+            ModuleBuilder dependentModule = modules.get(dependentModuleName);\r
+            AugmentationTargetBuilder augmentTarget = (AugmentationTargetBuilder) dependentModule\r
+                    .getNode(augmentTargetPath);\r
+            AugmentationSchema result = augmentBuilder.build();\r
+            augmentTarget.addAugmentation(result);\r
+            augments.add(result);\r
+        }\r
+        builder.setAugmentations(augments);\r
+    }\r
+\r
+    private List<ParseTree> parseYangFiles(String... yangFiles) {\r
+        List<ParseTree> trees = new ArrayList<ParseTree>();\r
+        File yangFile;\r
+        for (String fileName : yangFiles) {\r
+            try {\r
+                yangFile = new File(fileName);\r
+                FileInputStream inStream = new FileInputStream(yangFile);\r
+                ANTLRInputStream input = new ANTLRInputStream(inStream);\r
+                final YangLexer lexer = new YangLexer(input);\r
+                final CommonTokenStream tokens = new CommonTokenStream(lexer);\r
+                final YangParser parser = new YangParser(tokens);\r
+                trees.add(parser.yang());\r
+            } catch (IOException e) {\r
+                logger.warn("Exception while reading yang file: " + fileName, e);\r
+            }\r
+        }\r
+        return trees;\r
+    }\r
+\r
+    /**\r
+     * Returns name of dependent module based on given prefix.\r
+     * \r
+     * @param builder\r
+     *            current builder which contains import\r
+     * @param prefix\r
+     *            prefix of dependent module used in current builder\r
+     * @return name of dependent module\r
+     */\r
+    private String getDependentModuleName(ModuleBuilder builder, String prefix) {\r
+        ModuleImport moduleImport = null;\r
+        for (ModuleImport mi : builder.getModuleImports()) {\r
+            if (mi.getPrefix().equals(prefix)) {\r
+                moduleImport = mi;\r
+                break;\r
+            }\r
+        }\r
+        return moduleImport.getModuleName();\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/impl/YangModelParserImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/impl/YangModelParserImpl.java
new file mode 100644 (file)
index 0000000..7b121bd
--- /dev/null
@@ -0,0 +1,703 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.impl;\r
+\r
+import static org.opendaylight.controller.model.parser.util.YangModelBuilderHelper.*;\r
+\r
+import java.net.URI;\r
+import java.net.URISyntaxException;\r
+import java.text.DateFormat;\r
+import java.text.ParseException;\r
+import java.text.SimpleDateFormat;\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.Stack;\r
+\r
+import org.antlr.v4.runtime.tree.ParseTree;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParserBaseListener;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Config_argContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Config_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Container_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Description_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_add_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_delete_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_not_supported_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_replace_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Import_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Key_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Leaf_list_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Leaf_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.List_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Module_header_stmtsContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Namespace_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Ordered_by_argContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Ordered_by_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Prefix_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Presence_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Reference_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Revision_date_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Revision_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Revision_stmtsContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Status_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.StringContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Type_body_stmtsContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Yang_version_stmtContext;\r
+import org.opendaylight.controller.model.api.type.EnumTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.LengthConstraint;\r
+import org.opendaylight.controller.model.api.type.PatternConstraint;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+import org.opendaylight.controller.model.parser.api.AugmentationSchemaBuilder;\r
+import org.opendaylight.controller.model.parser.api.GroupingBuilder;\r
+import org.opendaylight.controller.model.parser.builder.ContainerSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.builder.DeviationBuilder;\r
+import org.opendaylight.controller.model.parser.builder.FeatureBuilder;\r
+import org.opendaylight.controller.model.parser.builder.LeafListSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.builder.LeafSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.builder.ListSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.builder.ModuleBuilder;\r
+import org.opendaylight.controller.model.parser.builder.MustDefinitionBuilder;\r
+import org.opendaylight.controller.model.parser.builder.NotificationBuilder;\r
+import org.opendaylight.controller.model.parser.builder.RpcDefinitionBuilder;\r
+import org.opendaylight.controller.model.parser.builder.TypedefBuilder;\r
+import org.opendaylight.controller.model.parser.util.YangModelBuilderHelper;\r
+import org.opendaylight.controller.model.util.BitsType;\r
+import org.opendaylight.controller.model.util.EnumerationType;\r
+import org.opendaylight.controller.model.util.Leafref;\r
+import org.opendaylight.controller.model.util.StringType;\r
+import org.opendaylight.controller.model.util.YangTypesConverter;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+public class YangModelParserImpl extends YangParserBaseListener {\r
+\r
+    private static final Logger logger = LoggerFactory\r
+            .getLogger(YangModelParserImpl.class);\r
+\r
+    private ModuleBuilder moduleBuilder;\r
+\r
+    private String moduleName;\r
+    private URI namespace;\r
+    private String yangModelPrefix;\r
+    private Date revision;\r
+\r
+    private final DateFormat simpleDateFormat = new SimpleDateFormat(\r
+            "yyyy-mm-dd");\r
+    private final Stack<String> actualPath = new Stack<String>();\r
+\r
+    @Override\r
+    public void enterModule_stmt(YangParser.Module_stmtContext ctx) {\r
+        moduleName = stringFromNode(ctx);\r
+        actualPath.push(moduleName);\r
+        moduleBuilder = new ModuleBuilder(moduleName);\r
+    }\r
+\r
+    @Override\r
+    public void exitModule_stmt(YangParser.Module_stmtContext ctx) {\r
+        final String moduleName = actualPath.pop();\r
+        logger.debug("Exiting module " + moduleName);\r
+    }\r
+\r
+    @Override\r
+    public void enterModule_header_stmts(final Module_header_stmtsContext ctx) {\r
+        super.enterModule_header_stmts(ctx);\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); ++i) {\r
+            final ParseTree treeNode = ctx.getChild(i);\r
+            if (treeNode instanceof Namespace_stmtContext) {\r
+                String namespaceStr = stringFromNode(treeNode);\r
+                try {\r
+                    this.namespace = new URI(namespaceStr);\r
+                    moduleBuilder.setNamespace(namespace);\r
+                } catch (URISyntaxException e) {\r
+                    logger.warn("Failed to parse module namespace", e);\r
+                }\r
+            } else if (treeNode instanceof Prefix_stmtContext) {\r
+                yangModelPrefix = stringFromNode(treeNode);\r
+                moduleBuilder.setPrefix(yangModelPrefix);\r
+            } else if (treeNode instanceof Yang_version_stmtContext) {\r
+                final String yangVersion = stringFromNode(treeNode);\r
+                moduleBuilder.setYangVersion(yangVersion);\r
+            }\r
+        }\r
+    }\r
+\r
+    // TODO: resolve submodule parsing\r
+    @Override\r
+    public void enterSubmodule_header_stmts(\r
+            YangParser.Submodule_header_stmtsContext ctx) {\r
+        String submoduleName = stringFromNode(ctx);\r
+        QName submoduleQName = new QName(namespace, revision, yangModelPrefix,\r
+                submoduleName);\r
+        moduleBuilder.addSubmodule(submoduleQName);\r
+        updatePath(submoduleName);\r
+    }\r
+\r
+    @Override\r
+    public void exitSubmodule_header_stmts(\r
+            YangParser.Submodule_header_stmtsContext ctx) {\r
+        final String submodule = actualPath.pop();\r
+        logger.debug("exiting submodule " + submodule);\r
+    }\r
+\r
+    @Override\r
+    public void enterOrganization_stmt(YangParser.Organization_stmtContext ctx) {\r
+        final String organization = stringFromNode(ctx);\r
+        moduleBuilder.setOrganization(organization);\r
+    }\r
+\r
+    @Override\r
+    public void enterContact_stmt(YangParser.Contact_stmtContext ctx) {\r
+        String contact = stringFromNode(ctx);\r
+        moduleBuilder.setContact(contact);\r
+    }\r
+\r
+    @Override\r
+    public void enterRevision_stmts(Revision_stmtsContext ctx) {\r
+        for (int i = 0; i < ctx.getChildCount(); ++i) {\r
+            final ParseTree treeNode = ctx.getChild(i);\r
+            if (treeNode instanceof Revision_stmtContext) {\r
+                final String revisionDateStr = stringFromNode(treeNode);\r
+                try {\r
+                    revision = simpleDateFormat.parse(revisionDateStr);\r
+                } catch (ParseException e) {\r
+                    logger.warn("Failed to parse revision string: "\r
+                            + revisionDateStr);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void enterDescription_stmt(YangParser.Description_stmtContext ctx) {\r
+        // if this is module description...\r
+        if (actualPath.size() == 1) {\r
+            moduleBuilder.setDescription(stringFromNode(ctx));\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void enterImport_stmt(Import_stmtContext ctx) {\r
+        super.enterImport_stmt(ctx);\r
+\r
+        final String importName = stringFromNode(ctx);\r
+        String importPrefix = null;\r
+        Date importRevision = null;\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); ++i) {\r
+            final ParseTree treeNode = ctx.getChild(i);\r
+            if (treeNode instanceof Prefix_stmtContext) {\r
+                importPrefix = stringFromNode(treeNode);\r
+            }\r
+            if (treeNode instanceof Revision_date_stmtContext) {\r
+                String importRevisionStr = stringFromNode(treeNode);\r
+                try {\r
+                    importRevision = simpleDateFormat.parse(importRevisionStr);\r
+                } catch (Exception e) {\r
+                    logger.warn("Failed to parse import revision-date.", e);\r
+                }\r
+            }\r
+        }\r
+        moduleBuilder.addModuleImport(importName, importRevision, importPrefix);\r
+    }\r
+\r
+    @Override\r
+    public void enterAugment_stmt(YangParser.Augment_stmtContext ctx) {\r
+        final String augmentPath = stringFromNode(ctx);\r
+        AugmentationSchemaBuilder builder = moduleBuilder.addAugment(\r
+                augmentPath, actualPath);\r
+        updatePath(augmentPath);\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if (child instanceof Description_stmtContext) {\r
+                String desc = stringFromNode(child);\r
+                builder.setDescription(desc);\r
+            } else if (child instanceof Reference_stmtContext) {\r
+                String ref = stringFromNode(child);\r
+                builder.setReference(ref);\r
+            } else if (child instanceof Status_stmtContext) {\r
+                Status status = getStatus((Status_stmtContext) child);\r
+                builder.setStatus(status);\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void exitAugment_stmt(YangParser.Augment_stmtContext ctx) {\r
+        final String augment = actualPath.pop();\r
+        logger.debug("exiting augment " + augment);\r
+    }\r
+\r
+    @Override\r
+    public void enterMust_stmt(YangParser.Must_stmtContext ctx) {\r
+        String mustText = "";\r
+        String description = null;\r
+        String reference = null;\r
+        for (int i = 0; i < ctx.getChildCount(); ++i) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if (child instanceof StringContext) {\r
+                final StringContext context = (StringContext) child;\r
+                for (int j = 0; j < context.getChildCount(); j++) {\r
+                    String mustPart = context.getChild(j).getText();\r
+                    if (j == 0) {\r
+                        mustText += mustPart\r
+                                .substring(0, mustPart.length() - 1);\r
+                        continue;\r
+                    }\r
+                    if (j % 2 == 0) {\r
+                        mustText += mustPart.substring(1);\r
+                    }\r
+                }\r
+            } else if (child instanceof Description_stmtContext) {\r
+                description = stringFromNode(child);\r
+            } else if (child instanceof Reference_stmtContext) {\r
+                reference = stringFromNode(child);\r
+            }\r
+        }\r
+        MustDefinitionBuilder builder = moduleBuilder.addMustDefinition(\r
+                mustText, actualPath);\r
+        builder.setDescription(description);\r
+        builder.setReference(reference);\r
+    }\r
+\r
+    @Override\r
+    public void enterTypedef_stmt(YangParser.Typedef_stmtContext ctx) {\r
+        String typedefName = stringFromNode(ctx);\r
+        QName typedefQName = new QName(namespace, revision, yangModelPrefix,\r
+                typedefName);\r
+        TypedefBuilder builder = moduleBuilder.addTypedef(typedefQName,\r
+                actualPath);\r
+        updatePath(typedefName);\r
+\r
+        builder.setPath(getActualSchemaPath(actualPath, namespace, revision,\r
+                yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, builder);\r
+    }\r
+\r
+    @Override\r
+    public void exitTypedef_stmt(YangParser.Typedef_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterType_stmt(YangParser.Type_stmtContext ctx) {\r
+        String typeName = stringFromNode(ctx);\r
+        QName typeQName;\r
+        if (typeName.contains(":")) {\r
+            String[] splittedName = typeName.split(":");\r
+            // if this type contains prefix, it means that it point to type in\r
+            // external module\r
+            typeQName = new QName(null, null, splittedName[0], splittedName[1]);\r
+        } else {\r
+            typeQName = new QName(namespace, revision, yangModelPrefix,\r
+                    typeName);\r
+        }\r
+\r
+        TypeDefinition<?> type = null;\r
+\r
+        if (!YangTypesConverter.isBaseYangType(typeName)) {\r
+            if (typeName.equals("leafref")) {\r
+                // TODO: RevisionAwareXPath implementation\r
+                type = new Leafref(new RevisionAwareXPath() {\r
+                });\r
+            } else {\r
+                type = parseUnknownType(typeQName, ctx);\r
+                // mark parent node of this type statement as dirty\r
+                moduleBuilder.addDirtyNode(actualPath);\r
+            }\r
+        } else {\r
+\r
+            Type_body_stmtsContext typeBody = null;\r
+            for (int i = 0; i < ctx.getChildCount(); i++) {\r
+                if (ctx.getChild(i) instanceof Type_body_stmtsContext) {\r
+                    typeBody = (Type_body_stmtsContext) ctx.getChild(i);\r
+                    break;\r
+                }\r
+            }\r
+\r
+            if (typeBody == null) {\r
+                // if there are no constraints, just grab default base yang type\r
+                type = YangTypesConverter.javaTypeForBaseYangType(typeName);\r
+            } else {\r
+                List<RangeConstraint> rangeStatements = getRangeConstraints(typeBody);\r
+                Integer fractionDigits = getFractionDigits(typeBody);\r
+                List<LengthConstraint> lengthStatements = getLengthConstraints(typeBody);\r
+                List<PatternConstraint> patternStatements = getPatternConstraint(typeBody);\r
+                List<EnumTypeDefinition.EnumPair> enumConstants = YangModelBuilderHelper\r
+                        .getEnumConstants(typeBody);\r
+\r
+                if (typeName.equals("decimal64")) {\r
+                    type = YangTypesConverter.javaTypeForBaseYangDecimal64Type(\r
+                            rangeStatements, fractionDigits);\r
+                } else if (typeName.startsWith("int")\r
+                        || typeName.startsWith("uint")) {\r
+                    type = YangTypesConverter.javaTypeForBaseYangIntegerType(\r
+                            typeName, rangeStatements);\r
+                } else if (typeName.equals("enumeration")) {\r
+                    type = new EnumerationType(enumConstants);\r
+                } else if (typeName.equals("string")) {\r
+                    type = new StringType(lengthStatements, patternStatements);\r
+                } else if (typeName.equals("bits")) {\r
+                    type = new BitsType(getBits(typeBody, actualPath,\r
+                            namespace, revision, yangModelPrefix));\r
+                } else {\r
+                    // TODO: implement binary + instance-identifier types\r
+                }\r
+            }\r
+\r
+        }\r
+\r
+        moduleBuilder.setType(type, actualPath);\r
+        updatePath(typeName);\r
+    }\r
+\r
+    @Override\r
+    public void exitType_stmt(YangParser.Type_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterGrouping_stmt(YangParser.Grouping_stmtContext ctx) {\r
+        final String groupName = stringFromNode(ctx);\r
+        QName groupQName = new QName(namespace, revision, yangModelPrefix,\r
+                groupName);\r
+        GroupingBuilder groupBuilder = moduleBuilder.addGrouping(groupQName,\r
+                actualPath);\r
+        updatePath("grouping");\r
+        updatePath(groupName);\r
+        parseSchemaNodeArgs(ctx, groupBuilder);\r
+    }\r
+\r
+    @Override\r
+    public void exitGrouping_stmt(YangParser.Grouping_stmtContext ctx) {\r
+        String actContainer = actualPath.pop();\r
+        actContainer += "-" + actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterContainer_stmt(Container_stmtContext ctx) {\r
+        super.enterContainer_stmt(ctx);\r
+        String containerName = stringFromNode(ctx);\r
+        QName containerQName = new QName(namespace, revision, yangModelPrefix,\r
+                containerName);\r
+        ContainerSchemaNodeBuilder containerBuilder = moduleBuilder\r
+                .addContainerNode(containerQName, actualPath);\r
+        updatePath(containerName);\r
+\r
+        containerBuilder.setPath(getActualSchemaPath(actualPath, namespace,\r
+                revision, yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, containerBuilder);\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); ++i) {\r
+            final ParseTree childNode = ctx.getChild(i);\r
+            if (childNode instanceof Presence_stmtContext) {\r
+                containerBuilder.setPresenceContainer(true);\r
+            } else if (childNode instanceof Config_stmtContext) {\r
+                for (int j = 0; j < childNode.getChildCount(); j++) {\r
+                    ParseTree configArg = childNode.getChild(j);\r
+                    if (configArg instanceof Config_argContext) {\r
+                        String config = stringFromNode(configArg);\r
+                        if (config.equals("true")) {\r
+                            containerBuilder.setConfiguration(true);\r
+                        } else {\r
+                            containerBuilder.setConfiguration(false);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void exitContainer_stmt(Container_stmtContext ctx) {\r
+        super.exitContainer_stmt(ctx);\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    private boolean isLeafReadOnly(final ParseTree leaf) {\r
+        if (leaf != null) {\r
+            for (int i = 0; i < leaf.getChildCount(); ++i) {\r
+                final ParseTree configContext = leaf.getChild(i);\r
+                if (configContext instanceof Config_argContext) {\r
+                    final String value = stringFromNode(configContext);\r
+                    if (value.equals("true")) {\r
+                        return true;\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public void enterLeaf_stmt(Leaf_stmtContext ctx) {\r
+        super.enterLeaf_stmt(ctx);\r
+\r
+        final String leafName = stringFromNode(ctx);\r
+        QName leafQName = new QName(namespace, revision, yangModelPrefix,\r
+                leafName);\r
+        LeafSchemaNodeBuilder leafBuilder = moduleBuilder.addLeafNode(\r
+                leafQName, actualPath);\r
+        updatePath(leafName);\r
+\r
+        leafBuilder.setPath(getActualSchemaPath(actualPath, namespace,\r
+                revision, yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, leafBuilder);\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if (child instanceof Config_stmtContext) {\r
+                leafBuilder.setConfiguration(isLeafReadOnly(child));\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void exitLeaf_stmt(YangParser.Leaf_stmtContext ctx) {\r
+        final String actLeaf = actualPath.pop();\r
+        logger.debug("exiting " + actLeaf);\r
+    }\r
+\r
+    @Override\r
+    public void enterUses_stmt(YangParser.Uses_stmtContext ctx) {\r
+        final String groupingPathStr = stringFromNode(ctx);\r
+        moduleBuilder.addUsesNode(groupingPathStr, actualPath);\r
+        updatePath(groupingPathStr);\r
+    }\r
+\r
+    @Override\r
+    public void exitUses_stmt(YangParser.Uses_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterLeaf_list_stmt(Leaf_list_stmtContext ctx) {\r
+        super.enterLeaf_list_stmt(ctx);\r
+\r
+        final String leafListName = stringFromNode(ctx);\r
+        QName leafListQName = new QName(namespace, revision, yangModelPrefix,\r
+                leafListName);\r
+        LeafListSchemaNodeBuilder leafListBuilder = moduleBuilder\r
+                .addLeafListNode(leafListQName, actualPath);\r
+        updatePath(leafListName);\r
+\r
+        parseSchemaNodeArgs(ctx, leafListBuilder);\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); ++i) {\r
+            final ParseTree childNode = ctx.getChild(i);\r
+            if (childNode instanceof Config_stmtContext) {\r
+                leafListBuilder.setConfiguration(isLeafReadOnly(childNode));\r
+            } else if (childNode instanceof Ordered_by_stmtContext) {\r
+                final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;\r
+                final boolean userOrdered = parseUserOrdered(orderedBy);\r
+                leafListBuilder.setUserOrdered(userOrdered);\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void exitLeaf_list_stmt(YangParser.Leaf_list_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterList_stmt(List_stmtContext ctx) {\r
+        super.enterList_stmt(ctx);\r
+\r
+        final String containerName = stringFromNode(ctx);\r
+        QName containerQName = new QName(namespace, revision, yangModelPrefix,\r
+                containerName);\r
+        ListSchemaNodeBuilder listBuilder = moduleBuilder.addListNode(\r
+                containerQName, actualPath);\r
+        updatePath(containerName);\r
+\r
+        listBuilder.setPath(getActualSchemaPath(actualPath, namespace,\r
+                revision, yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, listBuilder);\r
+\r
+        String keyDefinition = "";\r
+        for (int i = 0; i < ctx.getChildCount(); ++i) {\r
+            ParseTree childNode = ctx.getChild(i);\r
+\r
+            if (childNode instanceof Ordered_by_stmtContext) {\r
+                final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;\r
+                final boolean userOrdered = parseUserOrdered(orderedBy);\r
+                listBuilder.setUserOrdered(userOrdered);\r
+            } else if (childNode instanceof Key_stmtContext) {\r
+                List<QName> key = createListKey(keyDefinition, namespace,\r
+                        revision, keyDefinition);\r
+                listBuilder.setKeyDefinition(key);\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void exitList_stmt(List_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterNotification_stmt(YangParser.Notification_stmtContext ctx) {\r
+        final String notificationName = stringFromNode(ctx);\r
+        QName notificationQName = new QName(namespace, revision,\r
+                yangModelPrefix, notificationName);\r
+        NotificationBuilder notificationBuilder = moduleBuilder\r
+                .addNotification(notificationQName, actualPath);\r
+        updatePath(notificationName);\r
+\r
+        notificationBuilder.setPath(getActualSchemaPath(actualPath, namespace,\r
+                revision, yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, notificationBuilder);\r
+    }\r
+\r
+    @Override\r
+    public void exitNotification_stmt(YangParser.Notification_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterRpc_stmt(YangParser.Rpc_stmtContext ctx) {\r
+        final String rpcName = stringFromNode(ctx);\r
+        QName rpcQName = new QName(namespace, revision, yangModelPrefix,\r
+                rpcName);\r
+        RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(rpcQName,\r
+                actualPath);\r
+        updatePath(rpcName);\r
+\r
+        rpcBuilder.setPath(getActualSchemaPath(actualPath, namespace, revision,\r
+                yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, rpcBuilder);\r
+    }\r
+\r
+    @Override\r
+    public void exitRpc_stmt(YangParser.Rpc_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterInput_stmt(YangParser.Input_stmtContext ctx) {\r
+        updatePath("input");\r
+    }\r
+\r
+    @Override\r
+    public void exitInput_stmt(YangParser.Input_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterOutput_stmt(YangParser.Output_stmtContext ctx) {\r
+        updatePath("output");\r
+    }\r
+\r
+    @Override\r
+    public void exitOutput_stmt(YangParser.Output_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterFeature_stmt(YangParser.Feature_stmtContext ctx) {\r
+        final String featureName = stringFromNode(ctx);\r
+        QName featureQName = new QName(namespace, revision, yangModelPrefix,\r
+                featureName);\r
+        FeatureBuilder featureBuilder = moduleBuilder.addFeature(featureQName,\r
+                actualPath);\r
+        updatePath(featureName);\r
+\r
+        featureBuilder.setPath(getActualSchemaPath(actualPath, namespace,\r
+                revision, yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, featureBuilder);\r
+    }\r
+\r
+    @Override\r
+    public void exitFeature_stmt(YangParser.Feature_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterDeviation_stmt(YangParser.Deviation_stmtContext ctx) {\r
+        final String targetPath = stringFromNode(ctx);\r
+        String reference = null;\r
+        String deviate = null;\r
+        DeviationBuilder builder = moduleBuilder.addDeviation(targetPath);\r
+        updatePath(targetPath);\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if (child instanceof Reference_stmtContext) {\r
+                reference = stringFromNode(child);\r
+            } else if (child instanceof Deviate_not_supported_stmtContext) {\r
+                deviate = stringFromNode(child);\r
+            } else if (child instanceof Deviate_add_stmtContext) {\r
+                deviate = stringFromNode(child);\r
+            } else if (child instanceof Deviate_replace_stmtContext) {\r
+                deviate = stringFromNode(child);\r
+            } else if (child instanceof Deviate_delete_stmtContext) {\r
+                deviate = stringFromNode(child);\r
+            }\r
+        }\r
+        builder.setReference(reference);\r
+        builder.setDeviate(deviate);\r
+    }\r
+\r
+    @Override\r
+    public void exitDeviation_stmt(YangParser.Deviation_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    public ModuleBuilder getModuleBuilder() {\r
+        return moduleBuilder;\r
+    }\r
+\r
+    private void updatePath(String containerName) {\r
+        actualPath.push(containerName);\r
+    }\r
+\r
+    /**\r
+     * Parse ordered-by statement.\r
+     * \r
+     * @param childNode\r
+     *            Ordered_by_stmtContext\r
+     * @return true, if ordered-by contains value 'user' or false otherwise\r
+     */\r
+    private boolean parseUserOrdered(Ordered_by_stmtContext childNode) {\r
+        boolean result = false;\r
+        for (int j = 0; j < childNode.getChildCount(); j++) {\r
+            ParseTree orderArg = childNode.getChild(j);\r
+            if (orderArg instanceof Ordered_by_argContext) {\r
+                String orderStr = stringFromNode(orderArg);\r
+                if (orderStr.equals("system")) {\r
+                    result = false;\r
+                } else if (orderStr.equals("user")) {\r
+                    result = true;\r
+                } else {\r
+                    logger.warn("Invalid 'ordered-by' statement.");\r
+                }\r
+            }\r
+        }\r
+        return result;\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/util/YangModelBuilderHelper.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/model/parser/util/YangModelBuilderHelper.java
new file mode 100644 (file)
index 0000000..7d9dcf1
--- /dev/null
@@ -0,0 +1,659 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.util;\r
+\r
+import java.net.URI;\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.Stack;\r
+\r
+import org.antlr.v4.runtime.tree.ParseTree;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Bit_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Bits_specificationContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Decimal64_specificationContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Description_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Enum_specificationContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Enum_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Fraction_digits_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Length_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Numerical_restrictionsContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Pattern_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Position_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Range_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Reference_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Status_argContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Status_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.StringContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.String_restrictionsContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Type_body_stmtsContext;\r
+import org.opendaylight.controller.model.api.type.BitsTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.EnumTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.LengthConstraint;\r
+import org.opendaylight.controller.model.api.type.PatternConstraint;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+import org.opendaylight.controller.model.api.type.BitsTypeDefinition.Bit;\r
+import org.opendaylight.controller.model.parser.api.SchemaNodeBuilder;\r
+import org.opendaylight.controller.model.util.BaseConstraints;\r
+import org.opendaylight.controller.model.util.UnknownType;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+public class YangModelBuilderHelper {\r
+\r
+    private static final Logger logger = LoggerFactory\r
+            .getLogger(YangModelBuilderHelper.class);\r
+\r
+    /**\r
+     * Get 'description', 'reference' and 'status' statements and fill in\r
+     * builder.\r
+     * \r
+     * @param ctx\r
+     *            context to parse\r
+     * @param builder\r
+     *            builder to fill in with parsed statements\r
+     */\r
+    public static void parseSchemaNodeArgs(ParseTree ctx,\r
+            SchemaNodeBuilder builder) {\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if (child instanceof Description_stmtContext) {\r
+                String desc = stringFromNode(child);\r
+                builder.setDescription(desc);\r
+            } else if (child instanceof Reference_stmtContext) {\r
+                String ref = stringFromNode(child);\r
+                builder.setReference(ref);\r
+            } else if (child instanceof Status_stmtContext) {\r
+                Status status = getStatus((Status_stmtContext) child);\r
+                builder.setStatus(status);\r
+            }\r
+        }\r
+    }\r
+\r
+    public static SchemaPath getActualSchemaPath(Stack<String> actualPath,\r
+            URI namespace, Date revision, String prefix) {\r
+        final List<QName> path = new ArrayList<QName>();\r
+        QName qname;\r
+        for (String pathElement : actualPath) {\r
+            qname = new QName(namespace, revision, prefix, pathElement);\r
+            path.add(qname);\r
+        }\r
+        return new SchemaPath(path, true);\r
+    }\r
+\r
+    public static Status getStatus(Status_stmtContext ctx) {\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree statusArg = ctx.getChild(i);\r
+            if (statusArg instanceof Status_argContext) {\r
+                String statusArgStr = stringFromNode(statusArg);\r
+                if (statusArgStr.equals("current")) {\r
+                    return Status.CURRENT;\r
+                } else if (statusArgStr.equals("deprecated")) {\r
+                    return Status.DEPRECATED;\r
+                } else if (statusArgStr.equals("obsolete")) {\r
+                    return Status.OBSOLOTE;\r
+                } else {\r
+                    logger.warn("Invalid 'status' statement: " + statusArgStr);\r
+                }\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+    public static String stringFromNode(final ParseTree treeNode) {\r
+        final String result = "";\r
+        for (int j = 0; j < treeNode.getChildCount(); ++j) {\r
+            if (treeNode.getChild(j) instanceof StringContext) {\r
+                final StringContext context = (StringContext) treeNode\r
+                        .getChild(j);\r
+\r
+                if (context != null) {\r
+                    return context.getChild(0).getText().replace("\"", "");\r
+                }\r
+            }\r
+        }\r
+        return result;\r
+    }\r
+\r
+    public static SchemaPath parsePath(String augmentPath) {\r
+        boolean absolute = augmentPath.startsWith("/");\r
+        String[] splittedPath = augmentPath.split("/");\r
+        List<QName> path = new ArrayList<QName>();\r
+        QName name;\r
+        for (String pathElement : splittedPath) {\r
+            if (pathElement.length() > 0) {\r
+                String[] splittedElement = pathElement.split(":");\r
+                if (splittedElement.length == 1) {\r
+                    name = new QName(null, null, null, splittedElement[0]);\r
+                } else {\r
+                    name = new QName(null, null, splittedElement[0],\r
+                            splittedElement[1]);\r
+                }\r
+                path.add(name);\r
+            }\r
+        }\r
+        return new SchemaPath(path, absolute);\r
+    }\r
+\r
+    public static List<QName> createListKey(String keyDefinition,\r
+            URI namespace, Date revision, String prefix) {\r
+        List<QName> key = new ArrayList<QName>();\r
+        String[] splittedKey = keyDefinition.split(" ");\r
+\r
+        QName qname = null;\r
+        for (String keyElement : splittedKey) {\r
+            if (keyElement.length() != 0) {\r
+                qname = new QName(namespace, revision, prefix, keyElement);\r
+                key.add(qname);\r
+            }\r
+        }\r
+        return key;\r
+    }\r
+\r
+    public static TypeDefinition<?> parseUnknownType(QName typedefQName,\r
+            ParseTree ctx) {\r
+        UnknownType.Builder ut = new UnknownType.Builder(typedefQName);\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if (child instanceof Type_body_stmtsContext) {\r
+                for (int j = 0; j < child.getChildCount(); j++) {\r
+                    ParseTree typeBodyChild = child.getChild(j);\r
+                    // NUMERICAL RESTRICTIONS\r
+                    if (typeBodyChild instanceof Numerical_restrictionsContext) {\r
+                        for (int k = 0; k < typeBodyChild.getChildCount(); k++) {\r
+                            ParseTree numRestrictionsChild = typeBodyChild\r
+                                    .getChild(k);\r
+                            if (numRestrictionsChild instanceof Range_stmtContext) {\r
+                                List<RangeConstraint> ranges = parseRangeConstraints((Range_stmtContext) numRestrictionsChild);\r
+                                ut.rangeStatements(ranges);\r
+                            }\r
+                        }\r
+                        // STRING RESTRICTIONS\r
+                    } else if (typeBodyChild instanceof String_restrictionsContext) {\r
+                        List<PatternConstraint> patterns = new ArrayList<PatternConstraint>();\r
+                        List<LengthConstraint> lengths = new ArrayList<LengthConstraint>();\r
+                        for (int k = 0; k < typeBodyChild.getChildCount(); k++) {\r
+                            ParseTree stringRestrictionsChild = typeBodyChild\r
+                                    .getChild(k);\r
+                            if (stringRestrictionsChild instanceof Pattern_stmtContext) {\r
+                                patterns.add(parsePatternConstraint((Pattern_stmtContext) stringRestrictionsChild));\r
+                            } else if (stringRestrictionsChild instanceof Length_stmtContext) {\r
+                                lengths = parseLengthConstraints((Length_stmtContext) stringRestrictionsChild);\r
+                            }\r
+                        }\r
+                        ut.patterns(patterns);\r
+                        ut.lengthStatements(lengths);\r
+                        // DECIMAL64\r
+                    } else if (typeBodyChild instanceof Decimal64_specificationContext) {\r
+                        for (int k = 0; k < typeBodyChild.getChildCount(); k++) {\r
+                            ParseTree fdChild = typeBodyChild.getChild(k);\r
+                            if (fdChild instanceof Fraction_digits_stmtContext) {\r
+                                // TODO: implement fraction digits\r
+                                // return\r
+                                // Integer.valueOf(stringFromNode(fdChild));\r
+                            }\r
+                        }\r
+                    }\r
+\r
+                }\r
+            }\r
+        }\r
+        return ut.build();\r
+    }\r
+\r
+    public static List<RangeConstraint> getRangeConstraints(\r
+            Type_body_stmtsContext ctx) {\r
+        List<RangeConstraint> rangeConstraints = new ArrayList<RangeConstraint>();\r
+        for (int j = 0; j < ctx.getChildCount(); j++) {\r
+            ParseTree numRestrChild = ctx.getChild(j);\r
+            if (numRestrChild instanceof Numerical_restrictionsContext) {\r
+                for (int k = 0; k < numRestrChild.getChildCount(); k++) {\r
+                    ParseTree rangeChild = numRestrChild.getChild(k);\r
+                    if (rangeChild instanceof Range_stmtContext) {\r
+                        rangeConstraints\r
+                                .addAll(parseRangeConstraints((Range_stmtContext) rangeChild));\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return rangeConstraints;\r
+    }\r
+\r
+    private static List<RangeConstraint> parseRangeConstraints(\r
+            Range_stmtContext ctx) {\r
+        List<RangeConstraint> rangeConstraints = new ArrayList<RangeConstraint>();\r
+        String description = null;\r
+        String reference = null;\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if (child instanceof Description_stmtContext) {\r
+                description = stringFromNode(child);\r
+            } else if (child instanceof Reference_stmtContext) {\r
+                reference = stringFromNode(child);\r
+            }\r
+        }\r
+\r
+        String rangeStr = stringFromNode(ctx);\r
+        String trimmed = rangeStr.replace(" ", "");\r
+        String[] splittedRange = trimmed.split("\\|");\r
+        for (String rangeDef : splittedRange) {\r
+            // TODO: this needs to be refactored, because valid range can be\r
+            // also defined as "1..max"\r
+            String[] splittedRangeDef = rangeDef.split("\\.\\.");\r
+            Long min = Long.valueOf(splittedRangeDef[0]);\r
+            Long max = Long.valueOf(splittedRangeDef[1]);\r
+            RangeConstraint range = BaseConstraints.rangeConstraint(min, max,\r
+                    description, reference);\r
+            rangeConstraints.add(range);\r
+        }\r
+\r
+        return rangeConstraints;\r
+    }\r
+\r
+    public static Integer getFractionDigits(Type_body_stmtsContext ctx) {\r
+        for (int j = 0; j < ctx.getChildCount(); j++) {\r
+            ParseTree dec64specChild = ctx.getChild(j);\r
+            if (dec64specChild instanceof Decimal64_specificationContext) {\r
+                for (int k = 0; k < dec64specChild.getChildCount(); k++) {\r
+                    ParseTree fdChild = dec64specChild.getChild(k);\r
+                    if (fdChild instanceof Fraction_digits_stmtContext) {\r
+                        return Integer.valueOf(stringFromNode(fdChild));\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+    public static List<EnumTypeDefinition.EnumPair> getEnumConstants(\r
+            Type_body_stmtsContext ctx) {\r
+        List<EnumTypeDefinition.EnumPair> enumConstants = new ArrayList<EnumTypeDefinition.EnumPair>();\r
+\r
+        out: for (int j = 0; j < ctx.getChildCount(); j++) {\r
+            ParseTree enumSpecChild = ctx.getChild(j);\r
+            if (enumSpecChild instanceof Enum_specificationContext) {\r
+                for (int k = 0; k < enumSpecChild.getChildCount(); k++) {\r
+                    ParseTree enumChild = enumSpecChild.getChild(k);\r
+                    if (enumChild instanceof Enum_stmtContext) {\r
+                        enumConstants.add(createEnumPair(\r
+                                (Enum_stmtContext) enumChild, k));\r
+                        if (k == enumSpecChild.getChildCount() - 1) {\r
+                            break out;\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return enumConstants;\r
+    }\r
+\r
+    private static EnumTypeDefinition.EnumPair createEnumPair(\r
+            Enum_stmtContext ctx, final int value) {\r
+        final String name = stringFromNode(ctx);\r
+        return new EnumTypeDefinition.EnumPair() {\r
+\r
+            @Override\r
+            public QName getQName() {\r
+                // TODO Auto-generated method stub\r
+                return null;\r
+            }\r
+\r
+            @Override\r
+            public SchemaPath getPath() {\r
+                // TODO Auto-generated method stub\r
+                return null;\r
+            }\r
+\r
+            @Override\r
+            public String getDescription() {\r
+                // TODO Auto-generated method stub\r
+                return null;\r
+            }\r
+\r
+            @Override\r
+            public String getReference() {\r
+                // TODO Auto-generated method stub\r
+                return null;\r
+            }\r
+\r
+            @Override\r
+            public Status getStatus() {\r
+                // TODO Auto-generated method stub\r
+                return null;\r
+            }\r
+\r
+            @Override\r
+            public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+                // TODO Auto-generated method stub\r
+                return null;\r
+            }\r
+\r
+            @Override\r
+            public String getName() {\r
+                return name;\r
+            }\r
+\r
+            @Override\r
+            public Integer getValue() {\r
+                return value;\r
+            }\r
+\r
+            @Override\r
+            public String toString() {\r
+                return EnumTypeDefinition.EnumPair.class.getSimpleName()\r
+                        + "[name=" + name + ", value=" + value + "]";\r
+            }\r
+        };\r
+    }\r
+\r
+    public static List<LengthConstraint> getLengthConstraints(\r
+            Type_body_stmtsContext ctx) {\r
+        List<LengthConstraint> lengthConstraints = new ArrayList<LengthConstraint>();\r
+        for (int j = 0; j < ctx.getChildCount(); j++) {\r
+            ParseTree stringRestrChild = ctx.getChild(j);\r
+            if (stringRestrChild instanceof String_restrictionsContext) {\r
+                for (int k = 0; k < stringRestrChild.getChildCount(); k++) {\r
+                    ParseTree lengthChild = stringRestrChild.getChild(k);\r
+                    if (lengthChild instanceof Length_stmtContext) {\r
+                        lengthConstraints\r
+                                .addAll(parseLengthConstraints((Length_stmtContext) lengthChild));\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return lengthConstraints;\r
+    }\r
+\r
+    private static List<LengthConstraint> parseLengthConstraints(\r
+            Length_stmtContext ctx) {\r
+        List<LengthConstraint> lengthConstraints = new ArrayList<LengthConstraint>();\r
+        String description = null;\r
+        String reference = null;\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if (child instanceof Description_stmtContext) {\r
+                description = stringFromNode(child);\r
+            } else if (child instanceof Reference_stmtContext) {\r
+                reference = stringFromNode(child);\r
+            }\r
+        }\r
+\r
+        String lengthStr = stringFromNode(ctx);\r
+        String trimmed = lengthStr.replace(" ", "");\r
+        String[] splittedRange = trimmed.split("\\|");\r
+        for (String rangeDef : splittedRange) {\r
+            // TODO: this needs to be refactored, because valid length can be\r
+            // also defined as "1"\r
+            String[] splittedRangeDef = rangeDef.split("\\.\\.");\r
+            Long min = Long.valueOf(splittedRangeDef[0]);\r
+            Long max = Long.valueOf(splittedRangeDef[1]);\r
+            LengthConstraint range = BaseConstraints.lengthConstraint(min, max,\r
+                    description, reference);\r
+            lengthConstraints.add(range);\r
+        }\r
+\r
+        return lengthConstraints;\r
+    }\r
+\r
+    public static List<PatternConstraint> getPatternConstraint(\r
+            Type_body_stmtsContext ctx) {\r
+        List<PatternConstraint> patterns = new ArrayList<PatternConstraint>();\r
+\r
+        out: for (int j = 0; j < ctx.getChildCount(); j++) {\r
+            ParseTree stringRestrChild = ctx.getChild(j);\r
+            if (stringRestrChild instanceof String_restrictionsContext) {\r
+                for (int k = 0; k < stringRestrChild.getChildCount(); k++) {\r
+                    ParseTree lengthChild = stringRestrChild.getChild(k);\r
+                    if (lengthChild instanceof Pattern_stmtContext) {\r
+                        patterns.add(parsePatternConstraint((Pattern_stmtContext) lengthChild));\r
+                        if (k == lengthChild.getChildCount() - 1) {\r
+                            break out;\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return patterns;\r
+    }\r
+\r
+    /**\r
+     * Internal helper method.\r
+     * \r
+     * @param ctx\r
+     *            pattern context\r
+     * @return PatternConstraint object\r
+     */\r
+    private static PatternConstraint parsePatternConstraint(\r
+            Pattern_stmtContext ctx) {\r
+        String description = null;\r
+        String reference = null;\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if (child instanceof Description_stmtContext) {\r
+                description = stringFromNode(child);\r
+            } else if (child instanceof Reference_stmtContext) {\r
+                reference = stringFromNode(child);\r
+            }\r
+        }\r
+        String pattern = stringFromNode(ctx);\r
+        return BaseConstraints.patternConstraint(pattern, description,\r
+                reference);\r
+    }\r
+\r
+    public static List<BitsTypeDefinition.Bit> getBits(\r
+            Type_body_stmtsContext ctx, Stack<String> actualPath,\r
+            URI namespace, Date revision, String prefix) {\r
+        List<BitsTypeDefinition.Bit> bits = new ArrayList<BitsTypeDefinition.Bit>();\r
+        for (int j = 0; j < ctx.getChildCount(); j++) {\r
+            ParseTree bitsSpecChild = ctx.getChild(j);\r
+            if (bitsSpecChild instanceof Bits_specificationContext) {\r
+                for (int k = 0; k < bitsSpecChild.getChildCount(); k++) {\r
+                    ParseTree bitChild = bitsSpecChild.getChild(k);\r
+                    if (bitChild instanceof Bit_stmtContext) {\r
+                        bits.add(parseBit((Bit_stmtContext) bitChild,\r
+                                actualPath, namespace, revision, prefix));\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return bits;\r
+    }\r
+\r
+    private static BitsTypeDefinition.Bit parseBit(final Bit_stmtContext ctx,\r
+            Stack<String> actualPath, final URI namespace, final Date revision,\r
+            final String prefix) {\r
+        String name = stringFromNode(ctx);\r
+        final QName qname = new QName(namespace, revision, prefix, name);\r
+        Long position = null;\r
+\r
+        String description = null;\r
+        String reference = null;\r
+        Status status = Status.CURRENT;\r
+\r
+        Stack<String> bitPath = new Stack<String>();\r
+        bitPath.addAll(actualPath);\r
+        bitPath.add(name);\r
+\r
+        SchemaPath schemaPath = getActualSchemaPath(bitPath, namespace,\r
+                revision, prefix);\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if (child instanceof Position_stmtContext) {\r
+                String positionStr = stringFromNode(child);\r
+                position = Long.valueOf(positionStr);\r
+                if (position < 0 || position > 4294967295L) {\r
+                    throw new IllegalArgumentException(\r
+                            "position value MUST be in the range 0 to 4294967295, but was: "\r
+                                    + position);\r
+                }\r
+            } else if (child instanceof Description_stmtContext) {\r
+                description = stringFromNode(child);\r
+            } else if (child instanceof Reference_stmtContext) {\r
+                reference = stringFromNode(child);\r
+            } else if (child instanceof Status_stmtContext) {\r
+                status = getStatus((Status_stmtContext) child);\r
+            }\r
+        }\r
+\r
+        // TODO: extensionDefinitions\r
+        return createBit(qname, schemaPath, description, reference, status,\r
+                null, position);\r
+    }\r
+\r
+    private static BitsTypeDefinition.Bit createBit(final QName qname,\r
+            final SchemaPath schemaPath, final String description,\r
+            final String reference, final Status status,\r
+            final List<ExtensionDefinition> extensionDefinitions,\r
+            final Long position) {\r
+        return new BitsTypeDefinition.Bit() {\r
+\r
+            @Override\r
+            public QName getQName() {\r
+                return qname;\r
+            }\r
+\r
+            @Override\r
+            public SchemaPath getPath() {\r
+                return schemaPath;\r
+            }\r
+\r
+            @Override\r
+            public String getDescription() {\r
+                return description;\r
+            }\r
+\r
+            @Override\r
+            public String getReference() {\r
+                return reference;\r
+            }\r
+\r
+            @Override\r
+            public Status getStatus() {\r
+                return status;\r
+            }\r
+\r
+            @Override\r
+            public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+                return extensionDefinitions;\r
+            }\r
+\r
+            @Override\r
+            public Long getPosition() {\r
+                return position;\r
+            }\r
+\r
+            @Override\r
+            public String getName() {\r
+                return qname.getLocalName();\r
+            }\r
+\r
+            @Override\r
+            public int hashCode() {\r
+                final int prime = 31;\r
+                int result = 1;\r
+                result = prime * result\r
+                        + ((qname == null) ? 0 : qname.hashCode());\r
+                result = prime * result\r
+                        + ((schemaPath == null) ? 0 : schemaPath.hashCode());\r
+                result = prime * result\r
+                        + ((description == null) ? 0 : description.hashCode());\r
+                result = prime * result\r
+                        + ((reference == null) ? 0 : reference.hashCode());\r
+                result = prime * result\r
+                        + ((status == null) ? 0 : status.hashCode());\r
+                result = prime * result\r
+                        + ((position == null) ? 0 : position.hashCode());\r
+                result = prime\r
+                        * result\r
+                        + ((extensionDefinitions == null) ? 0\r
+                                : extensionDefinitions.hashCode());\r
+                return result;\r
+            }\r
+\r
+            @Override\r
+            public boolean equals(Object obj) {\r
+                if (this == obj) {\r
+                    return true;\r
+                }\r
+                if (obj == null) {\r
+                    return false;\r
+                }\r
+                if (getClass() != obj.getClass()) {\r
+                    return false;\r
+                }\r
+                Bit other = (Bit) obj;\r
+                if (qname == null) {\r
+                    if (other.getQName() != null) {\r
+                        return false;\r
+                    }\r
+                } else if (!qname.equals(other.getQName())) {\r
+                    return false;\r
+                }\r
+                if (schemaPath == null) {\r
+                    if (other.getPath() != null) {\r
+                        return false;\r
+                    }\r
+                } else if (!schemaPath.equals(other.getPath())) {\r
+                    return false;\r
+                }\r
+                if (description == null) {\r
+                    if (other.getDescription() != null) {\r
+                        return false;\r
+                    }\r
+                } else if (!description.equals(other.getDescription())) {\r
+                    return false;\r
+                }\r
+                if (reference == null) {\r
+                    if (other.getReference() != null) {\r
+                        return false;\r
+                    }\r
+                } else if (!reference.equals(other.getReference())) {\r
+                    return false;\r
+                }\r
+                if (status == null) {\r
+                    if (other.getStatus() != null) {\r
+                        return false;\r
+                    }\r
+                } else if (!status.equals(other.getStatus())) {\r
+                    return false;\r
+                }\r
+                if (extensionDefinitions == null) {\r
+                    if (other.getExtensionSchemaNodes() != null) {\r
+                        return false;\r
+                    }\r
+                } else if (!extensionDefinitions.equals(other\r
+                        .getExtensionSchemaNodes())) {\r
+                    return false;\r
+                }\r
+                if (position == null) {\r
+                    if (other.getPosition() != null) {\r
+                        return false;\r
+                    }\r
+                } else if (!position.equals(other.getPosition())) {\r
+                    return false;\r
+                }\r
+                return true;\r
+            }\r
+\r
+            @Override\r
+            public String toString() {\r
+                return Bit.class.getSimpleName() + "[name="\r
+                        + qname.getLocalName() + ", position=" + position + "]";\r
+            }\r
+        };\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/builder/ContainerSchemaNodeBuilderTest.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/builder/ContainerSchemaNodeBuilderTest.java
new file mode 100644 (file)
index 0000000..55e1197
--- /dev/null
@@ -0,0 +1,118 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import static org.junit.Assert.*;\r
+import static org.mockito.Mockito.when;\r
+\r
+import java.net.URI;\r
+import java.util.Date;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.mockito.Mock;\r
+import org.mockito.MockitoAnnotations;\r
+import org.opendaylight.controller.model.parser.api.GroupingBuilder;\r
+import org.opendaylight.controller.model.parser.api.UsesNodeBuilder;\r
+import org.opendaylight.controller.model.parser.builder.ContainerSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.builder.MustDefinitionBuilder;\r
+import org.opendaylight.controller.model.parser.builder.TypedefBuilder;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.AugmentationSchema;\r
+import org.opendaylight.controller.yang.model.api.ConstraintDefinition;\r
+import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;\r
+import org.opendaylight.controller.yang.model.api.MustDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+import org.opendaylight.controller.yang.model.api.UsesNode;\r
+\r
+\r
+public class ContainerSchemaNodeBuilderTest {\r
+\r
+       private ContainerSchemaNodeBuilder tested;\r
+\r
+       private final String NAME = "test-container";\r
+\r
+       private final URI namespace = URI.create("test:container.name");\r
+       private final Date revision = new Date();\r
+       private final String prefix = "x";\r
+\r
+       private SchemaPath schemaPath;\r
+       private final String description = "description of container";\r
+       private final String reference = "reference";\r
+\r
+       private QName typedefQName;\r
+       private TypedefBuilder typeBuilder;\r
+       @Mock private AugmentationSchema augment;\r
+       @Mock private ConstraintDefinition constraint;\r
+       @Mock private UsesNodeBuilder usesBuilder;\r
+       @Mock private UsesNode uses;\r
+       @Mock private MustDefinitionBuilder mustBuilder;\r
+       @Mock private MustDefinition must;\r
+       @Mock private GroupingBuilder groupingBuilder;\r
+       @Mock private GroupingDefinition grouping;\r
+\r
+       @Before\r
+       public void init() {\r
+               MockitoAnnotations.initMocks(this);\r
+               when(usesBuilder.build()).thenReturn(uses);\r
+               when(mustBuilder.build()).thenReturn(must);\r
+               when(groupingBuilder.build()).thenReturn(grouping);\r
+\r
+               schemaPath = TestUtils.createSchemaPath(true, namespace, "main", "interface");\r
+               typedefQName = new QName(namespace, "test-type");\r
+               typeBuilder = new TypedefBuilder(typedefQName);\r
+\r
+               QName qname = new QName(namespace, revision, prefix, NAME);\r
+               tested = new ContainerSchemaNodeBuilder(qname);\r
+       }\r
+\r
+       @Test\r
+       public void test() {\r
+               tested.addTypedef(typeBuilder);\r
+               tested.setPath(schemaPath);\r
+               tested.setDescription(description);\r
+               tested.setReference(reference);\r
+               tested.setStatus(Status.OBSOLOTE);\r
+               tested.setConfiguration(false);\r
+               tested.setConstraints(constraint);\r
+               tested.addUsesNode(usesBuilder);\r
+               tested.addAugmentation(augment);\r
+               tested.setMustDefinitionBuilder(mustBuilder);\r
+               tested.setPresenceContainer(true);\r
+\r
+               ContainerSchemaNode result = tested.build();\r
+\r
+               Set<TypeDefinition<?>> expectedTypedefs = result.getTypeDefinitions();\r
+               assertEquals(1, expectedTypedefs.size());\r
+               assertEquals(typedefQName, expectedTypedefs.iterator().next().getQName());\r
+\r
+               Set<AugmentationSchema> expectedAugments = new HashSet<AugmentationSchema>();\r
+               expectedAugments.add(augment);\r
+               assertEquals(expectedAugments, result.getAvailableAugmentations());\r
+\r
+               assertEquals(schemaPath, result.getPath());\r
+               assertEquals(description, result.getDescription());\r
+               assertEquals(reference, result.getReference());\r
+               assertEquals(Status.OBSOLOTE, result.getStatus());\r
+               assertFalse(result.isConfiguration());\r
+               assertEquals(constraint, result.getConstraints());\r
+\r
+               Set<UsesNode> expectedUses = new HashSet<UsesNode>();\r
+               expectedUses.add(uses);\r
+               assertEquals(expectedUses, result.getUses());\r
+\r
+               assertTrue(result.isPresenceContainer());\r
+               assertEquals(must, result.getMustDefinition());\r
+       }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/builder/LeafListSchemaNodeBuilderTest.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/builder/LeafListSchemaNodeBuilderTest.java
new file mode 100644 (file)
index 0000000..9df458a
--- /dev/null
@@ -0,0 +1,99 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import static org.junit.Assert.*;\r
+import static org.mockito.Mockito.when;\r
+\r
+import java.net.URI;\r
+import java.util.Date;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.mockito.Mock;\r
+import org.mockito.MockitoAnnotations;\r
+import org.opendaylight.controller.model.parser.api.GroupingBuilder;\r
+import org.opendaylight.controller.model.parser.api.UsesNodeBuilder;\r
+import org.opendaylight.controller.model.parser.builder.LeafSchemaNodeBuilder;\r
+import org.opendaylight.controller.model.parser.builder.MustDefinitionBuilder;\r
+import org.opendaylight.controller.model.parser.builder.TypedefBuilder;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ConstraintDefinition;\r
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;\r
+import org.opendaylight.controller.yang.model.api.LeafSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.MustDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+import org.opendaylight.controller.yang.model.api.UsesNode;\r
+\r
+\r
+public class LeafListSchemaNodeBuilderTest {\r
+\r
+       private LeafSchemaNodeBuilder tested;\r
+\r
+       private final String NAME = "test-leaf";\r
+\r
+       private final URI namespace = URI.create("test:leaf.name");\r
+       private final Date revision = new Date();\r
+       private final String prefix = "x";\r
+\r
+       private SchemaPath schemaPath;\r
+       private final String description = "description of container";\r
+       private final String reference = "reference";\r
+\r
+       private QName typedefQName;\r
+       private TypeDefinition<?> type;\r
+       @Mock private ConstraintDefinition constraint;\r
+       @Mock private UsesNodeBuilder usesBuilder;\r
+       @Mock private UsesNode uses;\r
+       @Mock private MustDefinitionBuilder mustBuilder;\r
+       @Mock private MustDefinition must;\r
+       @Mock private GroupingBuilder groupingBuilder;\r
+       @Mock private GroupingDefinition grouping;\r
+\r
+       @Before\r
+       public void init() {\r
+               MockitoAnnotations.initMocks(this);\r
+               when(usesBuilder.build()).thenReturn(uses);\r
+               when(mustBuilder.build()).thenReturn(must);\r
+               when(groupingBuilder.build()).thenReturn(grouping);\r
+\r
+               schemaPath = TestUtils.createSchemaPath(true, namespace, "main", "interface");\r
+               typedefQName = new QName(namespace, "test-type");\r
+               TypedefBuilder typeBuilder = new TypedefBuilder(typedefQName);\r
+               type = typeBuilder.build();\r
+\r
+               QName qname = new QName(namespace, revision, prefix, NAME);\r
+               tested = new LeafSchemaNodeBuilder(qname);\r
+       }\r
+\r
+       @Test\r
+       public void test() {\r
+               tested.setType(type);\r
+               tested.setPath(schemaPath);\r
+               tested.setDescription(description);\r
+               tested.setReference(reference);\r
+               tested.setStatus(Status.OBSOLOTE);\r
+               tested.setConfiguration(false);\r
+               tested.setConstraints(constraint);\r
+               tested.setMustDefinitionBuilder(mustBuilder);\r
+\r
+               LeafSchemaNode result = tested.build();\r
+\r
+               assertEquals(type, result.getType());\r
+               assertEquals(schemaPath, result.getPath());\r
+               assertEquals(description, result.getDescription());\r
+               assertEquals(reference, result.getReference());\r
+               assertEquals(Status.OBSOLOTE, result.getStatus());\r
+               assertFalse(result.isConfiguration());\r
+               assertEquals(constraint, result.getConstraints());\r
+               assertEquals(must, result.getMustDefinition());\r
+       }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/builder/ListSchemaNodeBuilderTest.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/builder/ListSchemaNodeBuilderTest.java
new file mode 100644 (file)
index 0000000..7085dae
--- /dev/null
@@ -0,0 +1,121 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import static org.junit.Assert.*;\r
+import static org.mockito.Mockito.when;\r
+\r
+import java.net.URI;\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.mockito.Mock;\r
+import org.mockito.MockitoAnnotations;\r
+import org.opendaylight.controller.model.parser.api.GroupingBuilder;\r
+import org.opendaylight.controller.model.parser.api.UsesNodeBuilder;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.AugmentationSchema;\r
+import org.opendaylight.controller.yang.model.api.ConstraintDefinition;\r
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;\r
+import org.opendaylight.controller.yang.model.api.ListSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.MustDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+import org.opendaylight.controller.yang.model.api.UsesNode;\r
+\r
+\r
+public class ListSchemaNodeBuilderTest {\r
+\r
+       private ListSchemaNodeBuilder tested;\r
+\r
+       private static final String NAME = "test-list";\r
+\r
+       private final URI namespace = URI.create("test:list.name");\r
+       private final Date revision = new Date();\r
+       private final String prefix = "x";\r
+\r
+       private SchemaPath schemaPath;\r
+       private final String description = "description of list";\r
+       private final String reference = "reference";\r
+\r
+       private QName typedefQName;\r
+       private TypedefBuilder typeBuilder;\r
+       @Mock private AugmentationSchema augment;\r
+       @Mock private ConstraintDefinition constraint;\r
+       @Mock private UsesNodeBuilder usesBuilder;\r
+       @Mock private UsesNode uses;\r
+       @Mock private MustDefinitionBuilder mustBuilder;\r
+       @Mock private MustDefinition must;\r
+       @Mock private GroupingBuilder groupingBuilder;\r
+       @Mock private GroupingDefinition grouping;\r
+       private List<QName> keyDefinition;\r
+\r
+       @Before\r
+       public void init() {\r
+               MockitoAnnotations.initMocks(this);\r
+               when(usesBuilder.build()).thenReturn(uses);\r
+               when(mustBuilder.build()).thenReturn(must);\r
+               when(groupingBuilder.build()).thenReturn(grouping);\r
+\r
+               schemaPath = TestUtils.createSchemaPath(true, namespace, "main", NAME);\r
+               typedefQName = new QName(namespace, "test-type");\r
+               typeBuilder = new TypedefBuilder(typedefQName);\r
+\r
+               keyDefinition = new ArrayList<QName>();\r
+               keyDefinition.add(new QName(namespace, "name"));\r
+\r
+               QName qname = new QName(namespace, revision, prefix, NAME);\r
+               tested = new ListSchemaNodeBuilder(qname);\r
+       }\r
+\r
+       @Test\r
+       public void test() {\r
+               tested.addTypedef(typeBuilder);\r
+               tested.setPath(schemaPath);\r
+               tested.setDescription(description);\r
+               tested.setReference(reference);\r
+               tested.setStatus(Status.OBSOLOTE);\r
+               tested.setConfiguration(false);\r
+               tested.setConstraints(constraint);\r
+               tested.addUsesNode(usesBuilder);\r
+               tested.addAugmentation(augment);\r
+               tested.setUserOrdered(true);\r
+               tested.setKeyDefinition(keyDefinition);\r
+\r
+               ListSchemaNode result = tested.build();\r
+\r
+               Set<TypeDefinition<?>> expectedTypedefs = result.getTypeDefinitions();\r
+               assertEquals(1, expectedTypedefs.size());\r
+               assertEquals(typedefQName, expectedTypedefs.iterator().next().getQName());\r
+\r
+               Set<AugmentationSchema> expectedAugments = new HashSet<AugmentationSchema>();\r
+               expectedAugments.add(augment);\r
+               assertEquals(expectedAugments, result.getAvailableAugmentations());\r
+\r
+               assertEquals(schemaPath, result.getPath());\r
+               assertEquals(description, result.getDescription());\r
+               assertEquals(reference, result.getReference());\r
+               assertEquals(Status.OBSOLOTE, result.getStatus());\r
+               assertFalse(result.isConfiguration());\r
+               assertEquals(constraint, result.getConstraints());\r
+\r
+               Set<UsesNode> expectedUses = new HashSet<UsesNode>();\r
+               expectedUses.add(uses);\r
+               assertEquals(expectedUses, result.getUses());\r
+\r
+               assertTrue(result.isUserOrdered());\r
+               assertEquals(keyDefinition, result.getKeyDefinition());\r
+       }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/builder/TestUtils.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/builder/TestUtils.java
new file mode 100644 (file)
index 0000000..0c5bb48
--- /dev/null
@@ -0,0 +1,33 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.builder;\r
+\r
+import java.net.URI;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+\r
+\r
+public class TestUtils {\r
+\r
+       private TestUtils () {\r
+       }\r
+\r
+       public static SchemaPath createSchemaPath(boolean absolute, URI namespace, String... path) {\r
+               List<QName> names = new ArrayList<QName>();\r
+               QName qname;\r
+               for(String pathPart : path) {\r
+                       qname = new QName(namespace, pathPart);\r
+                       names.add(qname);\r
+               }\r
+               return new SchemaPath(names, absolute);\r
+       }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/impl/YangModelParserTest.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/model/parser/impl/YangModelParserTest.java
new file mode 100644 (file)
index 0000000..4a90d80
--- /dev/null
@@ -0,0 +1,97 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.parser.impl;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.util.Set;\r
+\r
+import org.antlr.v4.runtime.ANTLRInputStream;\r
+import org.antlr.v4.runtime.CommonTokenStream;\r
+import org.antlr.v4.runtime.tree.ParseTree;\r
+import org.antlr.v4.runtime.tree.ParseTreeWalker;\r
+import org.junit.Test;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangLexer;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser;\r
+import org.opendaylight.controller.sal.binding.model.api.GeneratedType;\r
+\r
+public class YangModelParserTest {\r
+\r
+    @Test\r
+    public void testPackageNameConstruction() {\r
+        try {\r
+            final InputStream inStream = getClass().getResourceAsStream(\r
+                    "/simple-list-demo.yang");\r
+            if (inStream != null) {\r
+                ANTLRInputStream input = new ANTLRInputStream(inStream);\r
+                final YangLexer lexer = new YangLexer(input);\r
+                final CommonTokenStream tokens = new CommonTokenStream(lexer);\r
+                final YangParser parser = new YangParser(tokens);\r
+\r
+                final ParseTree tree = parser.yang();\r
+                final ParseTreeWalker walker = new ParseTreeWalker();\r
+\r
+                // final YangModelParserImpl modelParser = new\r
+                // YangModelParserImpl(tree, new TypeProviderImpl());\r
+                // walker.walk(modelParser, tree);\r
+                // final Set<GeneratedType> genTypes =\r
+                // modelParser.generatedTypes();\r
+\r
+                // getTypesTest(genTypes);\r
+\r
+            }\r
+        } catch (IOException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    private void getTypesTest(final Set<GeneratedType> genTypes) {\r
+        int typesCount = 0;\r
+        for (final GeneratedType type : genTypes) {\r
+            if (type.getName().equals("Topology")) {\r
+                assertEquals(4, type.getMethodDefinitions().size());\r
+                ++typesCount;\r
+            }\r
+            if (type.getName().equals("NetworkNodes")) {\r
+                assertEquals(2, type.getMethodDefinitions().size());\r
+                ++typesCount;\r
+            }\r
+            if (type.getName().equals("NetworkNode")) {\r
+                assertEquals(1, type.getMethodDefinitions().size());\r
+                ++typesCount;\r
+            }\r
+            if (type.getName().equals("NodeAttributes")) {\r
+                assertEquals(2, type.getMethodDefinitions().size());\r
+                ++typesCount;\r
+            }\r
+            if (type.getName().equals("NetworkLinks")) {\r
+                assertEquals(2, type.getMethodDefinitions().size());\r
+                ++typesCount;\r
+            }\r
+            if (type.getName().equals("NetworkLink")) {\r
+                assertEquals(3, type.getMethodDefinitions().size());\r
+                ++typesCount;\r
+            }\r
+            if (type.getName().equals("Source")) {\r
+                assertEquals(2, type.getMethodDefinitions().size());\r
+                ++typesCount;\r
+            }\r
+            if (type.getName().equals("Destination")) {\r
+                assertEquals(2, type.getMethodDefinitions().size());\r
+                ++typesCount;\r
+            }\r
+            if (type.getName().equals("LinkAttributes")) {\r
+                assertEquals(0, type.getMethodDefinitions().size());\r
+                ++typesCount;\r
+            }\r
+        }\r
+        assertEquals(9, typesCount);\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang1.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang1.yang
new file mode 100644 (file)
index 0000000..16d6087
--- /dev/null
@@ -0,0 +1,60 @@
+module types1 {
+       yang-version 1;
+    namespace "urn:simple.container.demo";
+    prefix "t1";
+    
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+    
+    
+    container interfaces {
+         list ifEntry {
+             key "ifIndex";
+
+             leaf ifIndex {
+                 type uint32;
+             }
+             leaf ifDescr {
+                 type string;
+             }
+             leaf ifType {
+                 type uint8;
+             }
+             leaf ifMtu {
+                 type int32;
+             }
+         }
+     }
+    
+    
+    
+    
+    
+//    leaf name {
+//             type my-string;
+//     }
+       
+//     typedef my-string {
+//             type string {
+//                     length "0..4";
+//             pattern "[0-9a-fA-F]*";
+//             }
+//     }
+
+
+//     leaf completed {
+//             type types2:percent;
+//  }
+
+//     leaf testleaf {
+//             type data:my-base-int32-type;
+//     }
+
+//     leaf-list domain-search {
+//             type string;
+//             description "List of domain names to search";
+//     }
+       
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang2.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang2.yang
new file mode 100644 (file)
index 0000000..8c73b51
--- /dev/null
@@ -0,0 +1,27 @@
+module types2 {
+       yang-version 1;
+    namespace "urn:simple.types.data.demo";
+    prefix "t2";
+    
+    import types1 {
+         prefix "if";
+     }
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "This is types-data test description";
+
+    revision "2013-02-27" {
+        reference " WILL BE DEFINED LATER";
+    }
+    
+    
+     augment "/if:interfaces/if:ifEntry" {
+         when "if:ifType='ds0'";
+         leaf ds0ChannelNumber {
+             type string;
+         }
+     }
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang3.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang3.yang
new file mode 100644 (file)
index 0000000..0d09259
--- /dev/null
@@ -0,0 +1,35 @@
+module types3 {
+       yang-version 1;
+    namespace "urn:simple.types3.data.demo";
+    prefix "scd";
+
+    organization "Cisco";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description "This is types-data test description";
+
+    revision "2013-02-27" {
+        reference " WILL BE DEFINED LATER";
+    }
+    
+    typedef my-decimal {
+         type decimal64 {
+               fraction-digits 2;
+         }
+    }
+
+       typedef my-base-int32-type {
+         type int32 {
+               range "0..32";
+         }
+    }
+    
+    typedef percent {
+         type uint8 {
+             range "0 .. 100";
+         }
+         description "Percentage";
+       }
+       
+}
diff --git a/opendaylight/sal/yang-prototype/sal/.gitignore b/opendaylight/sal/yang-prototype/sal/.gitignore
new file mode 100644 (file)
index 0000000..ea8c4bf
--- /dev/null
@@ -0,0 +1 @@
+/target
diff --git a/opendaylight/sal/yang-prototype/sal/pom.xml b/opendaylight/sal/yang-prototype/sal/pom.xml
new file mode 100644 (file)
index 0000000..7cda2ac
--- /dev/null
@@ -0,0 +1,90 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+       <modelVersion>4.0.0</modelVersion>\r
+       <groupId>org.opendaylight.controller</groupId>\r
+       <artifactId>sal</artifactId>\r
+       <version>1.0-SNAPSHOT</version>\r
+       <packaging>pom</packaging>\r
+\r
+       <modules>\r
+               <module>sal-core-api</module>\r
+               <module>sal-data-api</module>\r
+               <module>sal-binding-api</module>\r
+               <module>sal-schema-repository-api</module>\r
+               <module>sal-common</module>\r
+               <module>sal-core-spi</module>\r
+               <module>../yang</module>\r
+               <module>sal-broker-impl</module>\r
+               <module>sal-core-demo</module>\r
+       </modules>\r
+\r
+       <dependencies>\r
+\r
+               <dependency>\r
+                       <groupId>junit</groupId>\r
+                       <artifactId>junit</artifactId>\r
+                       <version>4.10</version>\r
+                       <scope>test</scope>\r
+                       <optional>true</optional>\r
+               </dependency>\r
+               <dependency>\r
+                       <groupId>org.slf4j</groupId>\r
+                       <artifactId>slf4j-api</artifactId>\r
+                       <version>1.7.2</version>\r
+               </dependency>\r
+               <dependency>\r
+                       <groupId>org.slf4j</groupId>\r
+                       <artifactId>slf4j-simple</artifactId>\r
+                       <version>1.7.2</version>\r
+               </dependency>\r
+       </dependencies>\r
+       <build>\r
+               <plugins>\r
+                       <plugin>\r
+                               <groupId>org.apache.maven.plugins</groupId>\r
+                               <artifactId>maven-compiler-plugin</artifactId>\r
+                               <version>2.0</version>\r
+                               <inherited>true</inherited>\r
+                               <configuration>\r
+                                       <source>1.6</source>\r
+                                       <target>1.6</target>\r
+                               </configuration>\r
+                       </plugin>\r
+                       <plugin>\r
+                               <groupId>org.apache.maven.plugins</groupId>\r
+                               <artifactId>maven-javadoc-plugin</artifactId>\r
+                               <version>2.8.1</version>\r
+                               <configuration>\r
+                                       <stylesheet>maven</stylesheet>\r
+                               </configuration>\r
+                               <executions>\r
+                                       <execution>\r
+                                               <goals>\r
+                                                       <goal>aggregate</goal>\r
+                                               </goals>\r
+                                               <phase>site</phase>\r
+                                       </execution>\r
+                               </executions>\r
+                       </plugin>\r
+               </plugins>\r
+       </build>\r
+       <reporting>\r
+               <plugins>\r
+                       <plugin>\r
+                               <groupId>org.codehaus.mojo</groupId>\r
+                               <artifactId>findbugs-maven-plugin</artifactId>\r
+                               <version>2.4.0</version>\r
+                               <configuration>\r
+                                       <effort>Max</effort>\r
+                                       <threshold>Low</threshold>\r
+                                       <goal>site</goal>\r
+                               </configuration>\r
+                       </plugin>\r
+                       <plugin>\r
+                               <groupId>org.codehaus.mojo</groupId>\r
+                               <artifactId>jdepend-maven-plugin</artifactId>\r
+                               <version>2.0-beta-2</version>\r
+                       </plugin>\r
+               </plugins>\r
+       </reporting>
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-api/.gitignore b/opendaylight/sal/yang-prototype/sal/sal-binding-api/.gitignore
new file mode 100644 (file)
index 0000000..ea8c4bf
--- /dev/null
@@ -0,0 +1 @@
+/target
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-api/pom.xml b/opendaylight/sal/yang-prototype/sal/sal-binding-api/pom.xml
new file mode 100644 (file)
index 0000000..b339e30
--- /dev/null
@@ -0,0 +1,27 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>sal</artifactId>\r
+    <version>1.0-SNAPSHOT</version>\r
+  </parent>\r
+   <artifactId>sal-binding-api</artifactId>\r
+   \r
+   <dependencies>\r
+       <dependency>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>yang-common</artifactId>\r
+               <version>1.0</version>\r
+       </dependency>\r
+       <dependency>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>yang-binding</artifactId>\r
+               <version>1.0</version>\r
+       </dependency>\r
+       <dependency>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>sal-common</artifactId>\r
+               <version>1.0-SNAPSHOT</version>\r
+       </dependency>\r
+   </dependencies>
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareBroker.java b/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareBroker.java
new file mode 100644 (file)
index 0000000..4c1e6f7
--- /dev/null
@@ -0,0 +1,167 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.api;\r
+\r
+import org.opendaylight.controller.yang.binding.RpcService;\r
+\r
+/**\r
+ * Binding-aware core of the SAL layer responsible for wiring the SAL consumers.\r
+ * \r
+ * The responsibility of the broker is to maintain registration of SAL\r
+ * functionality {@link Consumer}s and {@link Provider}s, store provider and\r
+ * consumer specific context and functionality registration via\r
+ * {@link ConsumerSession} and provide access to infrastructure services, which\r
+ * removes direct dependencies between providers and consumers.\r
+ * \r
+ * The Binding-aware broker is also responsible for translation from Java\r
+ * classes modeling the functionality and data to binding-indpenedent form which\r
+ * is used in SAL Core.\r
+ * \r
+ * \r
+ * <h3>Infrastructure services</h3> Some examples of infrastructure services:\r
+ * \r
+ * <ul>\r
+ * <li>YANG Module service - see {@link ConsumerSession#getRpcService(Class)},\r
+ * {@link ProviderSession}\r
+ * <li>Notification Service - see {@link NotificationService} and\r
+ * {@link NotificationProviderService}\r
+ * <li>Functionality and Data model\r
+ * <li>Data Store access and modification - see {@link DataBrokerService} and\r
+ * {@link DataProviderService}\r
+ * </ul>\r
+ * \r
+ * The services are exposed via session.\r
+ * \r
+ * <h3>Session-based access</h3>\r
+ * \r
+ * The providers and consumers needs to register in order to use the\r
+ * binding-independent SAL layer and to expose functionality via SAL layer.\r
+ * \r
+ * For more information about session-based access see {@link ConsumerSession}\r
+ * and {@link ProviderSession}\r
+ * \r
+ * \r
+\r
+ * \r
+ */\r
+public interface BindingAwareBroker {\r
+    /**\r
+     * Registers the {@link BindingAwareConsumer}, which will use the SAL layer.\r
+     * \r
+     * <p>\r
+     * Note that consumer could register additional functionality at later point\r
+     * by using service and functionality specific APIs.\r
+     * \r
+     * <p>\r
+     * The consumer is required to use returned session for all communication\r
+     * with broker or one of the broker services. The session is announced to\r
+     * the consumer by invoking\r
+     * {@link Consumer#onSessionInitiated(ConsumerSession)}.\r
+     * \r
+     * @param cons\r
+     *            Consumer to be registered.\r
+     * @return a session specific to consumer registration\r
+     * @throws IllegalArgumentException\r
+     *             If the consumer is <code>null</code>.\r
+     * @throws IllegalStateException\r
+     *             If the consumer is already registered.\r
+     */\r
+    ConsumerSession registerConsumer(BindingAwareConsumer consumer);\r
+\r
+    /**\r
+     * Registers the {@link BindingAwareProvider}, which will use the SAL layer.\r
+     * \r
+     * <p>\r
+     * During the registration, the broker obtains the initial functionality\r
+     * from consumer, using the\r
+     * {@link BindingAwareProvider#getImplementations()}, and register that\r
+     * functionality into system and concrete infrastructure services.\r
+     * \r
+     * <p>\r
+     * Note that provider could register additional functionality at later point\r
+     * by using service and functionality specific APIs.\r
+     * \r
+     * <p>\r
+     * The consumer is <b>required to use</b> returned session for all\r
+     * communication with broker or one of the broker services. The session is\r
+     * announced to the consumer by invoking\r
+     * {@link BindingAwareProvider#onSessionInitiated(ProviderSession)}.\r
+     * \r
+     * \r
+     * @param prov\r
+     *            Provider to be registered.\r
+     * @return a session unique to the provider registration.\r
+     * @throws IllegalArgumentException\r
+     *             If the provider is <code>null</code>.\r
+     * @throws IllegalStateException\r
+     *             If the consumer is already registered.\r
+     */\r
+    ProviderSession registerProvider(BindingAwareProvider provider);\r
+\r
+    /**\r
+     * {@link BindingAwareConsumer} specific access to the SAL functionality.\r
+     * \r
+     * <p>\r
+     * ConsumerSession is {@link BindingAwareConsumer}-specific access to the\r
+     * SAL functionality and infrastructure services.\r
+     * \r
+     * <p>\r
+     * The session serves to store SAL context (e.g. registration of\r
+     * functionality) for the consumer and provides access to the SAL\r
+     * infrastructure services and other functionality provided by\r
+     * {@link Provider}s.\r
+     * \r
+\r
+     * \r
+     */\r
+    public interface ConsumerSession {\r
+\r
+        /**\r
+         * Returns a session specific instance (implementation) of requested\r
+         * binding-aware infrastructural service\r
+         * \r
+         * @param service\r
+         *            Broker service\r
+         * @return Session specific implementation of service\r
+         */\r
+        <T extends BindingAwareService> T getSALService(Class<T> service);\r
+\r
+        /**\r
+         * Returns a session specific instance (implementation) of requested\r
+         * YANG module implentation / service provided by consumer.\r
+         * \r
+         * @param service\r
+         *            Broker service\r
+         * @return Session specific implementation of service\r
+         */\r
+        <T extends RpcService> T getRpcService(Class<T> module);\r
+    }\r
+\r
+    /**\r
+     * {@link BindingAwareProvider} specific access to the SAL functionality.\r
+     * \r
+     * <p>\r
+     * ProviderSession is {@link BindingAwareProvider}-specific access to the\r
+     * SAL functionality and infrastructure services, which also allows for\r
+     * exposing the provider's functionality to the other\r
+     * {@link BindingAwareConsumer}s.\r
+     * \r
+     * <p>\r
+     * The session serves to store SAL context (e.g. registration of\r
+     * functionality) for the providers and exposes access to the SAL\r
+     * infrastructure services, dynamic functionality registration and any other\r
+     * functionality provided by other {@link BindingAwareConsumer}s.\r
+     * \r
+     */\r
+    public interface ProviderSession extends ConsumerSession {\r
+\r
+        void addImplementation(RpcService implementation);\r
+\r
+        void removeImplementation(RpcService implementation);\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareConsumer.java b/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareConsumer.java
new file mode 100644 (file)
index 0000000..e32f8bc
--- /dev/null
@@ -0,0 +1,40 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.api;\r
+\r
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerSession;\r
+\r
+/**\r
+ * \r
+ * Defines the component of controller and supplies additional metadata. A\r
+ * component of the controller or application supplies a concrete implementation\r
+ * of this interface.\r
+ * \r
+ * A user-implemented component (application) which faciliates the SAL and SAL\r
+ * services to access infrastructure services or providers' functionality.\r
+ * \r
+\r
+ * \r
+ */\r
+public interface BindingAwareConsumer {\r
+\r
+    /**\r
+     * Callback signaling initialization of the consumer session to the SAL.\r
+     * \r
+     * The consumer MUST use the session for all communication with SAL or\r
+     * retrieving SAL infrastructure services.\r
+     * \r
+     * This method is invoked by\r
+     * {@link BindingAwareBroker#registerConsumer(BindingAwareConsumer)}\r
+     * \r
+     * @param session\r
+     *            Unique session between consumer and SAL.\r
+     */\r
+    void onSessionInitialized(ConsumerSession session);\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareProvider.java b/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareProvider.java
new file mode 100644 (file)
index 0000000..565c3d2
--- /dev/null
@@ -0,0 +1,68 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.api;\r
+\r
+import java.util.Collection;\r
+\r
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerSession;\r
+import org.opendaylight.controller.yang.binding.RpcService;\r
+\r
+\r
+/**\r
+ * \r
+ * Defines the component of controller and supplies additional metadata. A\r
+ * component of the controller or application supplies a concrete implementation\r
+ * of this interface.\r
+ * \r
+ * <p>\r
+ * A user-implemented component (application) which facilitates the SAL and SAL\r
+ * services to access infrastructure services and to provide functionality to\r
+ * {@link Consumer}s and other providers.\r
+ * \r
+\r
+ * \r
+ */\r
+public interface BindingAwareProvider {\r
+\r
+    void onSessionInitialized(ConsumerSession session);\r
+\r
+    /**\r
+     * Returns a set of provided implementations of YANG modules and their rpcs.\r
+     * \r
+     * \r
+     * @return Set of provided implementation of YANG modules and their Rpcs\r
+     */\r
+    Collection<? extends RpcService> getImplementations();\r
+\r
+    /**\r
+     * Gets a set of implementations of provider functionality to be registered\r
+     * into system during the provider registration to the SAL.\r
+     * \r
+     * <p>\r
+     * This method is invoked by {@link Broker#registerProvider(Provider)} to\r
+     * learn the initial provided functionality\r
+     * \r
+     * @return Set of provider's functionality.\r
+     */\r
+    Collection<? extends ProviderFunctionality> getFunctionality();\r
+\r
+    /**\r
+     * Functionality provided by the {@link BindingAwareProvider}\r
+     * \r
+     * <p>\r
+     * Marker interface used to mark the interfaces describing specific\r
+     * functionality which could be exposed by providers to other components.\r
+     * \r
+\r
+     * \r
+     */\r
+    public interface ProviderFunctionality {\r
+\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareService.java b/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareService.java
new file mode 100644 (file)
index 0000000..e4d86e7
--- /dev/null
@@ -0,0 +1,40 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.api;\r
+\r
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerSession;\r
+\r
+/**\r
+ * \r
+ * Session-specific instance of the broker functionality.\r
+ * \r
+ * <p>\r
+ * BindingAwareService is marker interface for infrastructure services provided\r
+ * by the SAL. These services are session-specific, each\r
+ * {@link BindingAwareConsumer} and {@link BindingAwareProvider} usually has own\r
+ * instance of the service with it's own context.\r
+ * \r
+ * <p>\r
+ * The consumer's (or provider's) instance of specific service could be obtained\r
+ * by invoking {@link ConsumerSession#getSALService(Class)} method on session\r
+ * assigned to the consumer.\r
+ * \r
+ * <p>\r
+ * {@link BindingAwareService} and {@link BindingAwareProvider} may seem\r
+ * similar, but provider provides YANG model-based functionality and\r
+ * {@link BindingAwareProvider} exposes the necessary supporting functionality\r
+ * to implement specific functionality of YANG and to reuse it in the\r
+ * development of {@link BindingAwareConsumer}s and {@link BindingAwareProvider}\r
+ * s.\r
+ * \r
+\r
+ * \r
+ */\r
+public interface BindingAwareService {\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataBrokerService.java b/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataBrokerService.java
new file mode 100644 (file)
index 0000000..9195b6f
--- /dev/null
@@ -0,0 +1,137 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.api;\r
+\r
+import java.util.concurrent.Future;\r
+\r
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;\r
+import org.opendaylight.controller.yang.binding.DataRoot;\r
+import org.opendaylight.controller.yang.common.RpcResult;\r
+\r
+\r
+/**\r
+ * DataBrokerService provides unified access to the data stores available in the\r
+ * system.\r
+ * \r
+ * \r
+ * @see DataProviderService\r
+\r
+ */\r
+public interface DataBrokerService extends BindingAwareService {\r
+\r
+    /**\r
+     * Returns a data from specified Data Store.\r
+     * \r
+     * Returns all the data visible to the consumer from specified Data Store.\r
+     * \r
+     * @param <T>\r
+     *            Interface generated from YANG module representing root of data\r
+     * @param store\r
+     *            Identifier of the store, from which will be data retrieved\r
+     * @return data visible to the consumer\r
+     */\r
+    <T extends DataRoot> T getData(DataStoreIdentifier store, Class<T> rootType);\r
+\r
+    /**\r
+     * Returns a filtered subset of data from specified Data Store.\r
+     * \r
+     * <p>\r
+     * The filter is modeled as an hierarchy of Java TOs starting with\r
+     * implementation of {@link DataRoot} representing data root. The semantics\r
+     * of the filter tree is the same as filter semantics defined in the NETCONF\r
+     * protocol for rpc operations <code>get</code> and <code>get-config</code>\r
+     * in Section 6 of RFC6241.\r
+     * \r
+     * \r
+     * @see http://tools.ietf.org/html/rfc6241#section-6\r
+     * @param <T>\r
+     *            Interface generated from YANG module representing root of data\r
+     * @param store\r
+     *            Identifier of the store, from which will be data retrieved\r
+     * @param filter\r
+     *            Data tree filter similar to the NETCONF filter\r
+     * @return\r
+     */\r
+    <T extends DataRoot> T getData(DataStoreIdentifier store, T filter);\r
+\r
+    /**\r
+     * Returns a candidate data which are not yet commited.\r
+     * \r
+     * \r
+     * @param <T>\r
+     *            Interface generated from YANG module representing root of data\r
+     * @param store\r
+     *            Identifier of the store, from which will be data retrieved\r
+     * @return\r
+     */\r
+    <T extends DataRoot> T getCandidateData(DataStoreIdentifier store,\r
+            Class<T> rootType);\r
+\r
+    /**\r
+     * Returns a filtered subset of candidate data from specified Data Store.\r
+     * \r
+     * <p>\r
+     * The filter is modeled as an hierarchy of {@link Node} starting with\r
+     * {@link CompositeNode} representing data root. The semantics of the filter\r
+     * tree is the same as filter semantics defined in the NETCONF protocol for\r
+     * rpc operations <code>get</code> and <code>get-config</code> in Section 6\r
+     * of RFC6241.\r
+     * \r
+     * \r
+     * @see http://tools.ietf.org/html/rfc6241#section-6\r
+     * @param <T>\r
+     *            Interface generated from YANG module representing root of data\r
+     * @param store\r
+     *            Identifier of the store, from which will be data retrieved\r
+     * @param filter\r
+     *            A filter data root\r
+     * @return\r
+     */\r
+    <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, T filter);\r
+\r
+    /**\r
+     * \r
+     * @param <T>\r
+     *            Interface generated from YANG module representing root of data\r
+     * @param store\r
+     *            Identifier of the store, in which will be the candidate data\r
+     *            modified\r
+     * @param changeSet\r
+     *            Modification of data tree.\r
+     * @return Result object containing the modified data tree if the operation\r
+     *         was successful, otherwise list of the encountered errors.\r
+     */\r
+    RpcResult<DataRoot> editCandidateData(DataStoreIdentifier store,\r
+            DataRoot changeSet);\r
+\r
+    /**\r
+     * Initiates a two-phase commit of candidate data.\r
+     * \r
+     * <p>\r
+     * The {@link Consumer} could initiate a commit of candidate data\r
+     * \r
+     * <p>\r
+     * The successful commit changes the state of the system and may affect\r
+     * several components.\r
+     * \r
+     * <p>\r
+     * The effects of successful commit of data are described in the\r
+     * specifications and YANG models describing the {@link Provider} components\r
+     * of controller. It is assumed that {@link Consumer} has an understanding\r
+     * of this changes.\r
+     * \r
+     * \r
+     * @see DataCommitHandler for further information how two-phase commit is\r
+     *      processed.\r
+     * @param store\r
+     *            Identifier of the store, where commit should occur.\r
+     * @return Result of the commit, containing success information or list of\r
+     *         encountered errors, if commit was not successful.\r
+     */\r
+    Future<RpcResult<Void>> commit(DataStoreIdentifier store);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataCommitHandler.java b/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataCommitHandler.java
new file mode 100644 (file)
index 0000000..f568524
--- /dev/null
@@ -0,0 +1,209 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.api;\r
+\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality;\r
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;\r
+import org.opendaylight.controller.yang.common.RpcResult;\r
+\r
+\r
+/**\r
+ * Two phase commit handler (cohort) of the two-phase commit protocol of data.\r
+ * \r
+ * <p>\r
+ * The provider should expose the implementation of DataCommitHandler if it's\r
+ * functionality depends on any subset of data stored in data repositories, in\r
+ * order to participate in {@link DataBrokerService#commit(DataStoreIdentifier)\r
+ * operation.\r
+ * \r
+ * <p>\r
+ * Operations of two-phase commit handlers should not change data in data store,\r
+ * this is responsibility of the coordinator (broker or some component of the\r
+ * broker).\r
+ * \r
+ * The commit handlers are responsible for changing the internal state of the\r
+ * provider to reflect the commited changes in data.\r
+ * \r
+ * <h3>Two-phase commit</h3>\r
+ * \r
+ * <h4>Commit Request Phase</h4>\r
+ * \r
+ * <ol>\r
+ * <li> <code>Consumer</code> edits data by invocation of\r
+ * <code>DataBrokerService.editCandidateData(DataStoreIdentifier, DataRoot)</code>\r
+ * <li> <code>Consumer</code> starts a commit by invoking\r
+ * <code>DataBrokerService.commit(DataStoreIdentifier)</code>\r
+ * <li> <code>Broker</code> retrieves a list of all registered\r
+ * <code>DataCommitHandlers</code>\r
+ * <li>For each <code>DataCommitHandler</code>\r
+ * <ol>\r
+ * <li><code>Broker</code> invokes a\r
+ * <code>DataCommitHandler.requestCommit(DataStoreIdentifier)</code> operation.\r
+ * <li><code>DataCommitHandler</code> returns a <code>RpcResult</code> with\r
+ * <code>CommitTransaction</code>\r
+ * <li>If the result was successful, broker adds <code>CommitTransaction</code>\r
+ * to the list of opened transactions. If not, brokers stops a commit request\r
+ * phase and starts a rollback phase.\r
+ * </ol>\r
+ * <li><code>Broker</code> starts a commit finish phase\r
+ * </ol>\r
+ * \r
+ * <h4>Commit Finish Phase</h4>\r
+ * \r
+ * <ol>\r
+ * <li>For each <code>CommitTransaction</code> from Commit Request phase\r
+ * <ol>\r
+ * <li><code>Broker</code> broker invokes a\r
+ * <code>CommitTransaction.finish()</code>\r
+ * <li>The provider finishes a commit (applies the change) and returns an\r
+ * <code>RpcResult</code>.\r
+ * </ol>\r
+ * <li>\r
+ * <ul>\r
+ * <li>If all returned results means successful, the brokers end two-phase\r
+ * commit by returning a success commit result to the Consumer.\r
+ * <li>If error occured, the broker starts a commit rollback phase.\r
+ * </ul>\r
+ * </ol>\r
+ * \r
+ * <h4>Commit Rollback Phase</h4>\r
+ * <li>For each <code>CommitTransaction</code> from Commit Request phase\r
+ * <ol>\r
+ * <li><code>Broker</code>\r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * \r
+ * broker invokes a {@link CommitTransaction#finish()}\r
+ * <li>The provider rollbacks a commit and returns an {@link RpcResult} of\r
+ * rollback. </ol>\r
+ * <li>Broker returns a error result to the consumer.\r
+ * \r
+ * \r
+ * <h3>Registration of functionality</h3>\r
+ * The registration could be done by :\r
+ * <ul>\r
+ * <li>returning an instance of implementation in the return value of\r
+ * {@link Provider#getProviderFunctionality()}\r
+ * <li>passing an instance of implementation and {@link DataStoreIdentifier} of\r
+ * rpc as arguments to the\r
+ * {@link DataProviderService#addCommitHandler(DataStoreIdentifier, DataCommitHandler)}\r
+ * </ul>\r
+ * \r
+\r
+ * \r
+ */\r
+public interface DataCommitHandler extends ProviderFunctionality {\r
+    /**\r
+     * A set of Data Stores supported by implementation.\r
+     * \r
+     * The set of {@link DataStoreIdentifier}s which identifies target data\r
+     * stores which are supported by this commit handler. This set is used, when\r
+     * {@link Provider} is registered to the SAL, to register and expose the\r
+     * commit handler functionality to affected data stores.\r
+     * \r
+     * @return Set of Data Store identifiers\r
+     */\r
+    Set<DataStoreIdentifier> getSupportedDataStores();\r
+\r
+    /**\r
+     * The provider (commit handler) starts a commit transaction.\r
+     * \r
+     * <p>\r
+     * The commit handler (provider) prepares an commit scenario, rollback\r
+     * scenario and validates data.\r
+     * \r
+     * <p>\r
+     * If the provider is aware that at this point the commit would not be\r
+     * successful, the transaction is not created, but list of errors which\r
+     * prevented the start of transaction are returned.\r
+     * \r
+     * @param store\r
+     * @return Transaction object representing this commit, errors otherwise.\r
+     */\r
+    RpcResult<CommitTransaction> requestCommit(DataStoreIdentifier store);\r
+\r
+    public interface CommitTransaction {\r
+        /**\r
+         * \r
+         * @return Data store affected by the transaction\r
+         */\r
+        DataStoreIdentifier getDataStore();\r
+\r
+        /**\r
+         * Returns the handler associated with this transaction.\r
+         * \r
+         * @return Handler\r
+         */\r
+        DataCommitHandler getHandler();\r
+\r
+        /**\r
+         * \r
+         * Finishes a commit.\r
+         * \r
+         * The provider (commit handler) should apply all changes to its state\r
+         * which are a result of data change-\r
+         * \r
+         * @return\r
+         */\r
+        RpcResult<Void> finish() throws IllegalStateException;\r
+\r
+        /**\r
+         * Rollbacks a commit.\r
+         * \r
+         * @return\r
+         * @throws IllegalStateException\r
+         *             If the method is invoked after {@link #finish()}\r
+         */\r
+        RpcResult<Void> rollback() throws IllegalStateException;\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataProviderService.java b/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataProviderService.java
new file mode 100644 (file)
index 0000000..e4e7be5
--- /dev/null
@@ -0,0 +1,85 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.api;\r
+\r
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;\r
+\r
+public interface DataProviderService extends DataBrokerService {\r
+\r
+    /**\r
+     * Adds {@link DataValidator} for specified Data Store\r
+     * \r
+     * @param store\r
+     *            Data Store\r
+     * @param validator\r
+     *            Validator\r
+     */\r
+    public void addValidator(DataStoreIdentifier store, DataValidator validator);\r
+\r
+    /**\r
+     * Removes {@link DataValidator} from specified Data Store\r
+     * \r
+     * @param store\r
+     * @param validator\r
+     *            Validator\r
+     */\r
+    public void removeValidator(DataStoreIdentifier store,\r
+            DataValidator validator);\r
+\r
+    /**\r
+     * Adds {@link DataCommitHandler} for specified data store\r
+     * \r
+     * @param store\r
+     * @param provider\r
+     */\r
+    void addCommitHandler(DataStoreIdentifier store, DataCommitHandler provider);\r
+\r
+    /**\r
+     * Removes {@link DataCommitHandler} from specified data store\r
+     * \r
+     * @param store\r
+     * @param provider\r
+     */\r
+    void removeCommitHandler(DataStoreIdentifier store,\r
+            DataCommitHandler provider);\r
+\r
+    /**\r
+     * Adds {@link DataRefresher} for specified data store\r
+     * \r
+     * @param store\r
+     * @param refresher\r
+     */\r
+    void addRefresher(DataStoreIdentifier store, DataRefresher refresher);\r
+\r
+    /**\r
+     * Removes {@link DataRefresher} from specified data store\r
+     * \r
+     * @param store\r
+     * @param refresher\r
+     */\r
+    void removeRefresher(DataStoreIdentifier store, DataRefresher refresher);\r
+\r
+    /**\r
+     * Trigger for refreshing of the data exposed by the {@link Provider}\r
+     * \r
+\r
+     * \r
+     */\r
+    public interface DataRefresher extends\r
+            BindingAwareProvider.ProviderFunctionality {\r
+\r
+        /**\r
+         * Fired when some component explicitly requested the data refresh.\r
+         * \r
+         * The provider which exposed the {@link DataRefresher} should republish\r
+         * its provided data by editing the data in all affected data stores.\r
+         */\r
+        void refreshData();\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataRefresher.java b/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataRefresher.java
new file mode 100644 (file)
index 0000000..56b2a9f
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.api;\r
+\r
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality;\r
+\r
+public interface DataRefresher extends ProviderFunctionality {\r
+\r
+    void refreshData();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataValidator.java b/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/DataValidator.java
new file mode 100644 (file)
index 0000000..f2ad688
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.api;\r
+\r
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality;\r
+import org.opendaylight.controller.yang.binding.DataRoot;\r
+import org.opendaylight.controller.yang.common.RpcResult;\r
+\r
+\r
+public interface DataValidator extends ProviderFunctionality {\r
+\r
+    RpcResult<Void> validate(DataRoot data);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationProviderService.java b/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationProviderService.java
new file mode 100644 (file)
index 0000000..c5fc405
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.api;\r
+\r
+import org.opendaylight.controller.yang.binding.Notification;\r
+\r
+public interface NotificationProviderService extends NotificationService {\r
+\r
+    void notify(Notification notification);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationService.java b/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationService.java
new file mode 100644 (file)
index 0000000..92e30a5
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.api;\r
+\r
+import org.opendaylight.controller.yang.binding.Notification;\r
+import org.opendaylight.controller.yang.binding.NotificationListener;\r
+\r
+public interface NotificationService extends BindingAwareService {\r
+\r
+    void addNotificationListener(\r
+            Class<? extends Notification> notificationType,\r
+            NotificationListener listener);\r
+\r
+    void removeNotificationListener(\r
+            Class<? extends Notification> notificationType,\r
+            NotificationListener listener);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/package-info.java b/opendaylight/sal/yang-prototype/sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/package-info.java
new file mode 100644 (file)
index 0000000..552ac6a
--- /dev/null
@@ -0,0 +1,9 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.api;\r
+\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/pom.xml b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/pom.xml
new file mode 100644 (file)
index 0000000..131630d
--- /dev/null
@@ -0,0 +1,31 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>sal</artifactId>\r
+    <version>1.0-SNAPSHOT</version>\r
+  </parent>\r
+   <artifactId>sal-binding-broker-impl</artifactId>\r
+   \r
+   \r
+   \r
+   <dependencies>\r
+       <dependency>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>sal-binding-api</artifactId>\r
+               <version>1.0-SNAPSHOT</version>\r
+       </dependency>\r
+\r
+       <dependency>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>sal-core-api</artifactId>\r
+               <version>1.0-SNAPSHOT</version>\r
+       </dependency>\r
+\r
+       <dependency>\r
+               <groupId>org.slf4j</groupId>\r
+               <artifactId>slf4j-api</artifactId>\r
+               <version>1.6.4</version>\r
+       </dependency>\r
+   </dependencies>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/pom.xml b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/pom.xml
new file mode 100644 (file)
index 0000000..131c00d
--- /dev/null
@@ -0,0 +1,27 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+       <modelVersion>4.0.0</modelVersion>\r
+       <parent>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>sal</artifactId>\r
+               <version>1.0-SNAPSHOT</version>\r
+       </parent>\r
+       <artifactId>sal-broker-impl</artifactId>\r
+       <dependencies>\r
+               <dependency>\r
+                       <groupId>org.opendaylight.controller</groupId>\r
+                       <artifactId>sal-core-api</artifactId>\r
+                       <version>1.0-SNAPSHOT</version>\r
+               </dependency>\r
+               <dependency>\r
+                       <groupId>org.opendaylight.controller</groupId>\r
+                       <artifactId>sal-core-spi</artifactId>\r
+                       <version>1.0-SNAPSHOT</version>\r
+               </dependency>\r
+               <dependency>\r
+                       <groupId>org.slf4j</groupId>\r
+                       <artifactId>slf4j-api</artifactId>\r
+                       <version>1.6.4</version>\r
+               </dependency>\r
+       </dependencies>
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/BrokerImpl.java b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/BrokerImpl.java
new file mode 100644 (file)
index 0000000..97879fb
--- /dev/null
@@ -0,0 +1,130 @@
+
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.impl;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.concurrent.ExecutorService;\r
+import java.util.concurrent.Future;\r
+\r
+import org.opendaylight.controller.sal.core.api.Broker;\r
+import org.opendaylight.controller.sal.core.api.BrokerService;\r
+import org.opendaylight.controller.sal.core.api.Consumer;\r
+import org.opendaylight.controller.sal.core.api.Provider;\r
+import org.opendaylight.controller.sal.core.spi.BrokerModule;\r
+import org.opendaylight.controller.yang.common.QName;
+import org.opendaylight.controller.yang.common.RpcResult;
+import org.opendaylight.controller.yang.data.api.CompositeNode;
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+\r
+public class BrokerImpl implements Broker {\r
+    private static Logger log = LoggerFactory.getLogger(BrokerImpl.class);\r
+\r
+    private Set<ConsumerSessionImpl> sessions = new HashSet<ConsumerSessionImpl>();\r
+    private Set<ProviderSessionImpl> providerSessions = new HashSet<ProviderSessionImpl>();\r
+    // private ExecutorService executor;\r
+    private Set<BrokerModule> modules = new HashSet<BrokerModule>();\r
+\r
+    private Map<Class<? extends BrokerService>, BrokerModule> serviceProviders = new HashMap<Class<? extends BrokerService>, BrokerModule>();\r
+\r
+    @Override\r
+    public ConsumerSession registerConsumer(Consumer consumer) {\r
+        checkPredicates(consumer);\r
+        log.info("Registering consumer " + consumer);\r
+\r
+        ConsumerSessionImpl session = newSessionFor(consumer);\r
+        consumer.onSessionInitiated(session);\r
+\r
+        sessions.add(session);\r
+\r
+        return session;\r
+\r
+    }\r
+\r
+    @Override\r
+    public ProviderSession registerProvider(Provider provider) {\r
+        checkPredicates(provider);\r
+\r
+        ProviderSessionImpl session = newSessionFor(provider);\r
+        provider.onSessionInitiated(session);\r
+\r
+        providerSessions.add(session);\r
+        return session;\r
+    }\r
+\r
+    public <T extends BrokerService> T serviceFor(Class<T> service,\r
+            ConsumerSessionImpl session) {\r
+        BrokerModule prov = serviceProviders.get(service);\r
+        if (prov == null) {\r
+            log.warn("Service " + service.toString() + " is not supported");\r
+            return null;\r
+        }\r
+        return prov.getServiceForSession(service, session);\r
+    }\r
+\r
+    public Future<RpcResult<CompositeNode>> invokeRpc(QName rpc,\r
+            CompositeNode input) {\r
+        // TODO Implement this method\r
+        throw new UnsupportedOperationException("Not implemented");\r
+    }\r
+\r
+    private void checkPredicates(Provider prov) {\r
+        if (prov == null)\r
+            throw new IllegalArgumentException("Provider should not be null.");\r
+        for (ProviderSessionImpl session : providerSessions) {\r
+            if (prov.equals(session.getProvider()))\r
+                throw new IllegalStateException("Provider already registered");\r
+        }\r
+\r
+    }\r
+\r
+    private void checkPredicates(Consumer cons) {\r
+        if (cons == null)\r
+            throw new IllegalArgumentException("Consumer should not be null.");\r
+        for (ConsumerSessionImpl session : sessions) {\r
+            if (cons.equals(session.getConsumer()))\r
+                throw new IllegalStateException("Consumer already registered");\r
+        }\r
+    }\r
+\r
+    private ConsumerSessionImpl newSessionFor(Consumer cons) {\r
+        return new ConsumerSessionImpl(this, cons);\r
+    }\r
+\r
+    private ProviderSessionImpl newSessionFor(Provider provider) {\r
+        return new ProviderSessionImpl(this, provider);\r
+    }\r
+\r
+    public void addModule(BrokerModule module) {\r
+        log.info("Registering broker module " + module);\r
+        if (modules.contains(module)) {\r
+            log.error("Module already registered");\r
+            throw new IllegalArgumentException("Module already exists.");\r
+        }\r
+\r
+        Set<Class<? extends BrokerService>> provServices = module\r
+                .getProvidedServices();\r
+        for (Class<? extends BrokerService> serviceType : provServices) {\r
+            log.info("  Registering session service implementation: "\r
+                    + serviceType.getCanonicalName());\r
+            serviceProviders.put(serviceType, module);\r
+        }\r
+    }\r
+\r
+    public void consumerSessionClosed(ConsumerSessionImpl consumerSessionImpl) {\r
+        sessions.remove(consumerSessionImpl);\r
+        providerSessions.remove(consumerSessionImpl);\r
+    }\r
+\r
+}\r
+
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/BrokerServiceImpl.java b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/BrokerServiceImpl.java
new file mode 100644 (file)
index 0000000..4f25443
--- /dev/null
@@ -0,0 +1,16 @@
+
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.impl;\r
+\r
+import org.opendaylight.controller.sal.core.api.BrokerService;\r
+\r
+abstract public class BrokerServiceImpl implements BrokerService {\r
+\r
+    ConsumerSessionImpl session;\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/ConsumerSessionImpl.java b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/ConsumerSessionImpl.java
new file mode 100644 (file)
index 0000000..608c24b
--- /dev/null
@@ -0,0 +1,69 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.impl;\r
+\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.concurrent.Future;\r
+\r
+import org.opendaylight.controller.sal.core.api.BrokerService;\r
+import org.opendaylight.controller.sal.core.api.Consumer;\r
+import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.common.RpcResult;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+\r
+\r
+public class ConsumerSessionImpl implements ConsumerSession {\r
+\r
+    private final BrokerImpl broker;\r
+    private final Consumer consumer;\r
+\r
+    private Map<Class<? extends BrokerService>, BrokerService> instantiatedServices = new HashMap<Class<? extends BrokerService>, BrokerService>();\r
+\r
+    public Consumer getConsumer() {\r
+        return consumer;\r
+    }\r
+\r
+    public ConsumerSessionImpl(BrokerImpl broker, Consumer consumer) {\r
+        this.broker = broker;\r
+        this.consumer = consumer;\r
+    }\r
+\r
+    @Override\r
+    public Future<RpcResult<CompositeNode>> rpc(QName rpc, CompositeNode input) {\r
+        return broker.invokeRpc(rpc, input);\r
+    }\r
+\r
+    @Override\r
+    public <T extends BrokerService> T getService(Class<T> service) {\r
+        BrokerService potential = instantiatedServices.get(service);\r
+        if (potential != null) {\r
+            @SuppressWarnings("unchecked")\r
+            T ret = (T) potential;\r
+            return ret;\r
+        }\r
+        T ret = this.broker.serviceFor(service, this);\r
+        if (ret != null) {\r
+            instantiatedServices.put(service, ret);\r
+        }\r
+        return ret;\r
+    }\r
+\r
+    @Override\r
+    public void close() {\r
+        Collection<BrokerService> toStop = instantiatedServices.values();\r
+        for (BrokerService brokerService : toStop) {\r
+            brokerService.closeSession();\r
+        }\r
+        broker.consumerSessionClosed(this);\r
+    }\r
+\r
+}\r
+
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/ProviderSessionImpl.java b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/ProviderSessionImpl.java
new file mode 100644 (file)
index 0000000..e87b8bb
--- /dev/null
@@ -0,0 +1,48 @@
+
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.impl;\r
+\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.sal.core.api.Provider;\r
+import org.opendaylight.controller.sal.core.api.RpcImplementation;\r
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;\r
+import org.opendaylight.controller.yang.common.QName;
+\r
+\r
+public class ProviderSessionImpl extends ConsumerSessionImpl implements\r
+        ProviderSession {\r
+\r
+    private Provider provider;\r
+\r
+    public ProviderSessionImpl(BrokerImpl broker, Provider provider) {\r
+        super(broker, null);\r
+        this.provider = provider;\r
+    }\r
+\r
+    @Override\r
+    public void addRpcImplementation(QName rpcType,\r
+            RpcImplementation implementation) throws IllegalArgumentException {\r
+        // TODO Implement this method\r
+        throw new UnsupportedOperationException("Not implemented");\r
+    }\r
+\r
+    @Override\r
+    public void removeRpcImplementation(QName rpcType,\r
+            RpcImplementation implementation) throws IllegalArgumentException {\r
+        // TODO Implement this method\r
+        throw new UnsupportedOperationException("Not implemented");\r
+    }\r
+\r
+    public Provider getProvider() {\r
+        return this.provider;\r
+    }\r
+\r
+}\r
+
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/RpcUtils.java b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/RpcUtils.java
new file mode 100644 (file)
index 0000000..6edb981
--- /dev/null
@@ -0,0 +1,74 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.impl;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.List;\r
+import java.util.concurrent.Callable;\r
+\r
+import org.opendaylight.controller.sal.core.api.RpcImplementation;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.common.RpcError;\r
+import org.opendaylight.controller.yang.common.RpcResult;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+\r
+\r
+public class RpcUtils {\r
+\r
+    Callable<RpcResult<CompositeNode>> callableFor(\r
+            final RpcImplementation implemenation, final QName rpc,\r
+            final CompositeNode input) {\r
+\r
+        return new Callable<RpcResult<CompositeNode>>() {\r
+\r
+            @Override\r
+            public RpcResult<CompositeNode> call() throws Exception {\r
+                return implemenation.invokeRpc(rpc, input);\r
+            }\r
+        };\r
+    }\r
+\r
+    public static <T> RpcResult<T> getRpcResult(boolean successful, T result,\r
+            List<RpcError> errors) {\r
+        RpcResult<T> ret = new RpcResultTO<T>(successful, result, errors);\r
+        return ret;\r
+    }\r
+\r
+    private static class RpcResultTO<T> implements RpcResult<T> {\r
+\r
+        private final Collection<RpcError> errors;\r
+        private final T result;\r
+        private final boolean successful;\r
+\r
+        public RpcResultTO(boolean successful, T result, List<RpcError> errors) {\r
+            this.successful = successful;\r
+            this.result = result;\r
+            this.errors = Collections.unmodifiableList(new ArrayList<RpcError>(\r
+                    errors));\r
+        }\r
+\r
+        @Override\r
+        public boolean isSuccessful() {\r
+            return successful;\r
+        }\r
+\r
+        @Override\r
+        public T getResult() {\r
+            return result;\r
+        }\r
+\r
+        @Override\r
+        public Collection<RpcError> getErrors() {\r
+            return errors;\r
+        }\r
+\r
+    }\r
+}\r
+
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/Utils.java b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/Utils.java
new file mode 100644 (file)
index 0000000..810049f
--- /dev/null
@@ -0,0 +1,40 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.impl;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+\r
+public class Utils {\r
+\r
+    public static <T> void addToMap(Map<QName, List<T>> map, QName key, T value) {\r
+        List<T> list = map.get(key);\r
+        if (list == null) {\r
+            list = new ArrayList<T>();\r
+            map.put(key, list);\r
+        }\r
+        list.add(value);\r
+    }\r
+\r
+    public static <T> void removeFromMap(Map<QName, List<T>> map, QName key,\r
+            T value) {\r
+        List<T> list = map.get(key);\r
+        if (list == null) {\r
+            return;\r
+        }\r
+        list.remove(value);\r
+        if (list.isEmpty()) {\r
+            map.remove(key);\r
+        }\r
+    }\r
+}\r
+
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/data/DataBrokerModule.java b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/data/DataBrokerModule.java
new file mode 100644 (file)
index 0000000..7b93e5f
--- /dev/null
@@ -0,0 +1,411 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.impl.data;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.concurrent.Future;\r
+\r
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;\r
+import org.opendaylight.controller.sal.core.api.BrokerService;\r
+import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;\r
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;\r
+import org.opendaylight.controller.sal.core.api.Consumer.ConsumerFunctionality;\r
+import org.opendaylight.controller.sal.core.api.Provider.ProviderFunctionality;\r
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;\r
+import org.opendaylight.controller.sal.core.api.data.DataCommitHandler;\r
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;\r
+import org.opendaylight.controller.sal.core.api.data.DataValidator;\r
+import org.opendaylight.controller.sal.core.api.data.DataCommitHandler.CommitTransaction;\r
+import org.opendaylight.controller.sal.core.api.data.DataProviderService.DataRefresher;\r
+import org.opendaylight.controller.sal.core.impl.RpcUtils;\r
+import org.opendaylight.controller.sal.core.spi.BrokerModule;\r
+import org.opendaylight.controller.yang.common.RpcError;\r
+import org.opendaylight.controller.yang.common.RpcResult;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.CompositeNodeModification;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+\r
+public class DataBrokerModule implements BrokerModule {\r
+\r
+    private static final Logger log = LoggerFactory\r
+            .getLogger(DataBrokerModule.class);\r
+\r
+    private Map<DataStoreIdentifier, StoreContext> storeContext;\r
+\r
+    private SequentialCommitHandlerCoordinator coordinator = new SequentialCommitHandlerCoordinator();\r
+\r
+    @Override\r
+    public Set<Class<? extends BrokerService>> getProvidedServices() {\r
+        // FIXME: Refactor\r
+        Set<Class<? extends BrokerService>> ret = new HashSet<Class<? extends BrokerService>>();\r
+        ret.add(DataBrokerService.class);\r
+        ret.add(DataProviderService.class);\r
+        return ret;\r
+    }\r
+\r
+    @Override\r
+    public Set<Class<? extends ProviderFunctionality>> getSupportedProviderFunctionality() {\r
+        // FIXME Refactor\r
+        Set<Class<? extends ProviderFunctionality>> ret = new HashSet<Class<? extends ProviderFunctionality>>();\r
+        ret.add(DataValidator.class);\r
+        ret.add(DataCommitHandler.class);\r
+        ret.add(DataRefresher.class);\r
+        return ret;\r
+    }\r
+\r
+    @Override\r
+    public <T extends BrokerService> T getServiceForSession(Class<T> service,\r
+            ConsumerSession session) {\r
+        if (DataProviderService.class.equals(service)\r
+                && session instanceof ProviderSession) {\r
+            @SuppressWarnings("unchecked")\r
+            T ret = (T) newDataProviderService(session);\r
+            return ret;\r
+        } else if (DataBrokerService.class.equals(service)) {\r
+\r
+            @SuppressWarnings("unchecked")\r
+            T ret = (T) newDataConsumerService(session);\r
+            return ret;\r
+        }\r
+\r
+        throw new IllegalArgumentException(\r
+                "The requested session-specific service is not provided by this module.");\r
+    }\r
+\r
+    private DataProviderService newDataProviderService(ConsumerSession session) {\r
+        // TODO Implement this method\r
+        throw new UnsupportedOperationException("Not implemented");\r
+    }\r
+\r
+    private DataBrokerService newDataConsumerService(ConsumerSession session) {\r
+        // TODO Implement this method\r
+        throw new UnsupportedOperationException("Not implemented");\r
+    }\r
+\r
+    @Override\r
+    public Set<Class<? extends ConsumerFunctionality>> getSupportedConsumerFunctionality() {\r
+        // TODO Implement this method\r
+        throw new UnsupportedOperationException("Not implemented");\r
+    }\r
+\r
+    private static class StoreContext {\r
+        private Set<DataCommitHandler> commitHandlers = new HashSet<DataCommitHandler>();\r
+        private Set<DataValidator> validators = new HashSet<DataValidator>();\r
+        private Set<DataRefresher> refreshers = new HashSet<DataRefresher>();\r
+    }\r
+\r
+    private class DataConsumerSession implements DataBrokerService {\r
+\r
+        @Override\r
+        public CompositeNode getData(DataStoreIdentifier store) {\r
+            // TODO Implement this method\r
+            throw new UnsupportedOperationException("Not implemented");\r
+        }\r
+\r
+        @Override\r
+        public CompositeNode getData(DataStoreIdentifier store,\r
+                CompositeNode filter) {\r
+            // TODO Implement this method\r
+            throw new UnsupportedOperationException("Not implemented");\r
+        }\r
+\r
+        @Override\r
+        public CompositeNode getCandidateData(DataStoreIdentifier store) {\r
+            // TODO Implement this method\r
+            throw new UnsupportedOperationException("Not implemented");\r
+        }\r
+\r
+        @Override\r
+        public CompositeNode getCandidateData(DataStoreIdentifier store,\r
+                CompositeNode filter) {\r
+            // TODO Implement this method\r
+            throw new UnsupportedOperationException("Not implemented");\r
+        }\r
+\r
+        @Override\r
+        public RpcResult<CompositeNode> editCandidateData(\r
+                DataStoreIdentifier store, CompositeNodeModification changeSet) {\r
+            // TODO Implement this method\r
+            throw new UnsupportedOperationException("Not implemented");\r
+        }\r
+\r
+        @Override\r
+        public Future<RpcResult<Void>> commit(DataStoreIdentifier store) {\r
+            // TODO Implement this method\r
+            throw new UnsupportedOperationException("Not implemented");\r
+        }\r
+\r
+        @Override\r
+        public void closeSession() {\r
+            // TODO Implement this method\r
+            throw new UnsupportedOperationException("Not implemented");\r
+        }\r
+\r
+    }\r
+\r
+    private StoreContext context(DataStoreIdentifier store) {\r
+        return storeContext.get(store);\r
+    }\r
+\r
+    private class DataProviderSession extends DataConsumerSession implements\r
+            DataProviderService {\r
+\r
+        private Set<DataCommitHandler> providerCommitHandlers = new HashSet<DataCommitHandler>();\r
+        private Set<DataValidator> providerValidators = new HashSet<DataValidator>();\r
+        private Set<DataRefresher> providerRefreshers = new HashSet<DataRefresher>();\r
+\r
+        @Override\r
+        public void addValidator(DataStoreIdentifier store,\r
+                DataValidator validator) {\r
+            if (validator == null)\r
+                throw new IllegalArgumentException(\r
+                        "Validator should not be null");\r
+\r
+            providerValidators.add(validator);\r
+            context(store).validators.add(validator);\r
+        }\r
+\r
+        @Override\r
+        public void removeValidator(DataStoreIdentifier store,\r
+                DataValidator validator) {\r
+            if (validator == null)\r
+                throw new IllegalArgumentException(\r
+                        "Validator should not be null");\r
+\r
+            providerValidators.remove(validator);\r
+            context(store).validators.remove(validator);\r
+        }\r
+\r
+        @Override\r
+        public void addCommitHandler(DataStoreIdentifier store,\r
+                DataCommitHandler provider) {\r
+            if (provider == null)\r
+                throw new IllegalArgumentException(\r
+                        "CommitHandler should not be null");\r
+\r
+            providerCommitHandlers.add(provider);\r
+            context(store).commitHandlers.add(provider);\r
+        }\r
+\r
+        @Override\r
+        public void removeCommitHandler(DataStoreIdentifier store,\r
+                DataCommitHandler provider) {\r
+            if (provider == null)\r
+                throw new IllegalArgumentException(\r
+                        "CommitHandler should not be null");\r
+\r
+            providerCommitHandlers.remove(provider);\r
+            context(store).commitHandlers.remove(provider);\r
+        }\r
+\r
+        @Override\r
+        public void addRefresher(DataStoreIdentifier store,\r
+                DataRefresher provider) {\r
+            if (provider == null)\r
+                throw new IllegalArgumentException(\r
+                        "Refresher should not be null");\r
+\r
+            providerRefreshers.add(provider);\r
+            context(store).refreshers.add(provider);\r
+        }\r
+\r
+        @Override\r
+        public void removeRefresher(DataStoreIdentifier store,\r
+                DataRefresher provider) {\r
+            if (provider == null)\r
+                throw new IllegalArgumentException(\r
+                        "Refresher should not be null");\r
+\r
+            providerRefreshers.remove(provider);\r
+            context(store).refreshers.remove(provider);\r
+        }\r
+\r
+    }\r
+\r
+    private class SequentialCommitHandlerCoordinator implements\r
+            DataCommitHandler {\r
+\r
+        @Override\r
+        public RpcResult<CommitTransaction> requestCommit(\r
+                DataStoreIdentifier store) {\r
+            List<RpcError> errors = new ArrayList<RpcError>();\r
+            Set<CommitTransaction> transactions = new HashSet<DataCommitHandler.CommitTransaction>();\r
+            boolean successful = true;\r
+\r
+            for (DataCommitHandler commitHandler : context(store).commitHandlers) {\r
+                try {\r
+                    RpcResult<CommitTransaction> partialResult = commitHandler\r
+                            .requestCommit(store);\r
+                    successful = partialResult.isSuccessful() & successful;\r
+                    if (partialResult.isSuccessful()) {\r
+                        transactions.add(partialResult.getResult());\r
+                    }\r
+\r
+                    errors.addAll(partialResult.getErrors());\r
+                } catch (Exception e) {\r
+                    log.error("Uncaught exception prevented commit request."\r
+                            + e.getMessage(), e);\r
+                    successful = false;\r
+                    // FIXME: Add RPC Error with exception.\r
+                }\r
+                if (successful == false)\r
+                    break;\r
+            }\r
+            CommitTransaction transaction = new SequentialCommitTransaction(\r
+                    store, transactions);\r
+            return RpcUtils.getRpcResult(successful, transaction, errors);\r
+        }\r
+\r
+        @Override\r
+        public Set<DataStoreIdentifier> getSupportedDataStores() {\r
+            return Collections.emptySet();\r
+        }\r
+    }\r
+\r
+    private class SequentialCommitTransaction implements CommitTransaction {\r
+\r
+        final Set<CommitTransaction> transactions;\r
+        final DataStoreIdentifier store;\r
+\r
+        public SequentialCommitTransaction(DataStoreIdentifier s,\r
+                Set<CommitTransaction> t) {\r
+            transactions = t;\r
+            store = s;\r
+        }\r
+\r
+        @Override\r
+        public RpcResult<Void> finish() {\r
+            List<RpcError> errors = new ArrayList<RpcError>();\r
+            boolean successful = true;\r
+\r
+            for (CommitTransaction commitHandler : transactions) {\r
+                try {\r
+                    RpcResult<Void> partialResult = commitHandler.finish();\r
+                    successful = partialResult.isSuccessful() & successful;\r
+                    errors.addAll(partialResult.getErrors());\r
+                } catch (Exception e) {\r
+                    log.error(\r
+                            "Uncaught exception prevented finishing of commit."\r
+                                    + e.getMessage(), e);\r
+                    successful = false;\r
+                    // FIXME: Add RPC Error with exception.\r
+                }\r
+                if (successful == false)\r
+                    break;\r
+            }\r
+\r
+            return RpcUtils.getRpcResult(successful, null, errors);\r
+        }\r
+\r
+        @Override\r
+        public RpcResult<Void> rollback() {\r
+            List<RpcError> errors = new ArrayList<RpcError>();\r
+            boolean successful = true;\r
+\r
+            for (CommitTransaction commitHandler : transactions) {\r
+                try {\r
+                    RpcResult<Void> partialResult = commitHandler.rollback();\r
+                    successful = partialResult.isSuccessful() & successful;\r
+                    errors.addAll(partialResult.getErrors());\r
+                } catch (Exception e) {\r
+                    log.error(\r
+                            "Uncaught exception prevented rollback of commit."\r
+                                    + e.getMessage(), e);\r
+                    successful = false;\r
+                    // FIXME: Add RPC Error with exception.\r
+                }\r
+                if (successful == false)\r
+                    break;\r
+            }\r
+\r
+            return RpcUtils.getRpcResult(successful, null, errors);\r
+        }\r
+\r
+        @Override\r
+        public DataStoreIdentifier getDataStore() {\r
+            return this.store;\r
+        }\r
+\r
+        @Override\r
+        public DataCommitHandler getHandler() {\r
+            return coordinator;\r
+        }\r
+    }\r
+\r
+    private class ValidationCoordinator implements DataValidator {\r
+\r
+        private final DataStoreIdentifier store;\r
+\r
+        ValidationCoordinator(DataStoreIdentifier store) {\r
+            this.store = store;\r
+        }\r
+\r
+        @Override\r
+        public RpcResult<Void> validate(CompositeNode toValidate) {\r
+            List<RpcError> errors = new ArrayList<RpcError>();\r
+            boolean successful = true;\r
+\r
+            for (DataValidator validator : context(store).validators) {\r
+                try {\r
+                    RpcResult<Void> partialResult = validator\r
+                            .validate(toValidate);\r
+                    successful = partialResult.isSuccessful() & successful;\r
+                    errors.addAll(partialResult.getErrors());\r
+                } catch (Exception e) {\r
+                    log.error(\r
+                            "Uncaught exception prevented validation."\r
+                                    + e.getMessage(), e);\r
+                    successful = false;\r
+                    // FIXME: Add RPC Error with exception.\r
+                }\r
+                if (successful == false)\r
+                    break;\r
+            }\r
+\r
+            return RpcUtils.getRpcResult(successful, null, errors);\r
+        }\r
+\r
+        @Override\r
+        public Set<DataStoreIdentifier> getSupportedDataStores() {\r
+            return Collections.emptySet();\r
+        }\r
+\r
+    }\r
+\r
+    private class DataRefreshCoordinator implements DataRefresher {\r
+\r
+        private final DataStoreIdentifier store;\r
+\r
+        DataRefreshCoordinator(DataStoreIdentifier store) {\r
+            this.store = store;\r
+        }\r
+\r
+        @Override\r
+        public void refreshData() {\r
+\r
+            for (DataRefresher refresher : context(store).refreshers) {\r
+                try {\r
+                    refresher.refreshData();\r
+                } catch (Exception e) {\r
+                    log.error(\r
+                            "Uncaught exception during refresh of data: "\r
+                                    + e.getMessage(), e);\r
+                }\r
+\r
+            }\r
+        }\r
+    }\r
+}\r
+
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/data/package-info.java b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/data/package-info.java
new file mode 100644 (file)
index 0000000..34fa5e4
--- /dev/null
@@ -0,0 +1,10 @@
+
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+
+package org.opendaylight.controller.sal.core.impl.data;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/notify/NotificationModule.java b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/notify/NotificationModule.java
new file mode 100644 (file)
index 0000000..fd19e7e
--- /dev/null
@@ -0,0 +1,182 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.impl.notify;\r
+\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Map.Entry;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.sal.core.api.BrokerService;\r
+import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;\r
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;\r
+import org.opendaylight.controller.sal.core.api.Consumer.ConsumerFunctionality;\r
+import org.opendaylight.controller.sal.core.api.Provider.ProviderFunctionality;\r
+import org.opendaylight.controller.sal.core.api.notify.NotificationListener;\r
+import org.opendaylight.controller.sal.core.api.notify.NotificationProviderService;\r
+import org.opendaylight.controller.sal.core.api.notify.NotificationService;\r
+import org.opendaylight.controller.sal.core.impl.BrokerServiceImpl;\r
+import org.opendaylight.controller.sal.core.impl.Utils;\r
+import org.opendaylight.controller.sal.core.spi.BrokerModule;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+\r
+\r
+public class NotificationModule implements BrokerModule {\r
+    private static Logger log = LoggerFactory\r
+            .getLogger(NotificationModule.class);\r
+\r
+    private Map<QName, List<NotificationListener>> listeners = new HashMap<QName, List<NotificationListener>>();\r
+\r
+    @Override\r
+    public Set<Class<? extends BrokerService>> getProvidedServices() {\r
+        // FIXME Refactor\r
+        Set<Class<? extends BrokerService>> ret = new HashSet<Class<? extends BrokerService>>();\r
+        ret.add(NotificationService.class);\r
+        ret.add(NotificationProviderService.class);\r
+        return ret;\r
+    }\r
+\r
+    @Override\r
+    public Set<Class<? extends ConsumerFunctionality>> getSupportedConsumerFunctionality() {\r
+        // FIXME Refactor\r
+        Set<Class<? extends ConsumerFunctionality>> ret = new HashSet<Class<? extends ConsumerFunctionality>>();\r
+        ret.add(NotificationListener.class);\r
+        return ret;\r
+    }\r
+\r
+    @Override\r
+    public <T extends BrokerService> T getServiceForSession(Class<T> service,\r
+            ConsumerSession session) {\r
+        if (NotificationProviderService.class.equals(service)\r
+                && session instanceof ProviderSession) {\r
+            @SuppressWarnings("unchecked")\r
+            T ret = (T) newNotificationProviderService(session);\r
+            return ret;\r
+        } else if (NotificationService.class.equals(service)) {\r
+\r
+            @SuppressWarnings("unchecked")\r
+            T ret = (T) newNotificationConsumerService(session);\r
+            return ret;\r
+        }\r
+\r
+        throw new IllegalArgumentException(\r
+                "The requested session-specific service is not provided by this module.");\r
+    }\r
+\r
+    private void sendNotification(CompositeNode notification) {\r
+        QName type = notification.getNodeType();\r
+        List<NotificationListener> toNotify = listeners.get(type);\r
+        log.info("Publishing notification " + type);\r
+\r
+        if (toNotify == null) {\r
+            // No listeners were registered - returns.\r
+            return;\r
+        }\r
+\r
+        for (NotificationListener listener : toNotify) {\r
+            try {\r
+                // FIXME: ensure that notification is immutable\r
+                listener.onNotification(notification);\r
+            } catch (Exception e) {\r
+                log.error("Uncaught exception in NotificationListener", e);\r
+            }\r
+        }\r
+\r
+    }\r
+\r
+    private NotificationService newNotificationConsumerService(\r
+            ConsumerSession session) {\r
+        return new NotificationConsumerSessionImpl();\r
+    }\r
+\r
+    private NotificationProviderService newNotificationProviderService(\r
+            ConsumerSession session) {\r
+        return new NotificationProviderSessionImpl();\r
+    }\r
+\r
+    private class NotificationConsumerSessionImpl extends BrokerServiceImpl\r
+            implements NotificationService {\r
+\r
+        Map<QName, List<NotificationListener>> consumerListeners = new HashMap<QName, List<NotificationListener>>();\r
+        private boolean closed = false;\r
+\r
+        @Override\r
+        public void addNotificationListener(QName notification,\r
+                NotificationListener listener) {\r
+            checkSessionState();\r
+            if (notification == null) {\r
+                throw new IllegalArgumentException(\r
+                        "Notification type must not be null.");\r
+            }\r
+            if (listener == null) {\r
+                throw new IllegalArgumentException("Listener must not be null.");\r
+            }\r
+\r
+            Utils.addToMap(consumerListeners, notification, listener);\r
+            Utils.addToMap(listeners, notification, listener);\r
+            log.info("Registered listener for notification: " + notification);\r
+        }\r
+\r
+        @Override\r
+        public void removeNotificationListener(QName notification,\r
+                NotificationListener listener) {\r
+            checkSessionState();\r
+            if (notification == null) {\r
+                throw new IllegalArgumentException(\r
+                        "Notification type must not be null.");\r
+            }\r
+            if (listener == null) {\r
+                throw new IllegalArgumentException("Listener must not be null.");\r
+            }\r
+            Utils.removeFromMap(consumerListeners, notification, listener);\r
+            Utils.removeFromMap(listeners, notification, listener);\r
+        }\r
+\r
+        @Override\r
+        public void closeSession() {\r
+            closed = true;\r
+            Set<Entry<QName, List<NotificationListener>>> toRemove = consumerListeners\r
+                    .entrySet();\r
+            for (Entry<QName, List<NotificationListener>> entry : toRemove) {\r
+                listeners.get(entry.getKey()).removeAll(entry.getValue());\r
+            }\r
+        }\r
+\r
+        protected void checkSessionState() {\r
+            if (closed)\r
+                throw new IllegalStateException("Session is closed");\r
+        }\r
+    }\r
+\r
+    private class NotificationProviderSessionImpl extends\r
+            NotificationConsumerSessionImpl implements\r
+            NotificationProviderService {\r
+\r
+        @Override\r
+        public void sendNotification(CompositeNode notification) {\r
+            checkSessionState();\r
+            if (notification == null)\r
+                throw new IllegalArgumentException(\r
+                        "Notification must not be null.");\r
+            NotificationModule.this.sendNotification(notification);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public Set<Class<? extends ProviderFunctionality>> getSupportedProviderFunctionality() {\r
+        return Collections.emptySet();\r
+    }\r
+}\r
+
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/notify/package-info.java b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/notify/package-info.java
new file mode 100644 (file)
index 0000000..c068196
--- /dev/null
@@ -0,0 +1,9 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+
+package org.opendaylight.controller.sal.core.impl.notify;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/package-info.java b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/package-info.java
new file mode 100644 (file)
index 0000000..e29549d
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */
+package org.opendaylight.controller.sal.core.impl;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/rpc/RpcModule.java b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/rpc/RpcModule.java
new file mode 100644 (file)
index 0000000..58ceb5f
--- /dev/null
@@ -0,0 +1,5 @@
+package org.opendaylight.controller.sal.core.impl.rpc;\r
+\r
+public interface RpcModule {\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/rpc/package-info.java b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/rpc/package-info.java
new file mode 100644 (file)
index 0000000..41e9bcb
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.sal.core.impl.rpc;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-common/pom.xml b/opendaylight/sal/yang-prototype/sal/sal-common/pom.xml
new file mode 100644 (file)
index 0000000..a144b54
--- /dev/null
@@ -0,0 +1,14 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+       <modelVersion>4.0.0</modelVersion>\r
+       <parent>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>sal</artifactId>\r
+               <version>1.0-SNAPSHOT</version>\r
+       </parent>\r
+       <artifactId>sal-common</artifactId>\r
+\r
+       <dependencies>\r
+       </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-common/src/main/java/org/opendaylight/controller/sal/common/DataStoreIdentifier.java b/opendaylight/sal/yang-prototype/sal/sal-common/src/main/java/org/opendaylight/controller/sal/common/DataStoreIdentifier.java
new file mode 100644 (file)
index 0000000..194045e
--- /dev/null
@@ -0,0 +1,21 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.common;\r
+\r
+public interface DataStoreIdentifier {\r
+\r
+    Object getIdentifier();\r
+\r
+    String getName();\r
+\r
+    @Override\r
+    public boolean equals(Object obj);\r
+\r
+    @Override\r
+    public int hashCode();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-common/src/main/java/org/opendaylight/controller/sal/common/GlobalDataStore.java b/opendaylight/sal/yang-prototype/sal/sal-common/src/main/java/org/opendaylight/controller/sal/common/GlobalDataStore.java
new file mode 100644 (file)
index 0000000..1c30238
--- /dev/null
@@ -0,0 +1,29 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.common;\r
+\r
+public enum GlobalDataStore implements DataStoreIdentifier {\r
+    RuntimeInfo("Runtime Info"), Configuration("Configuration");\r
+\r
+    private final String name;\r
+\r
+    GlobalDataStore(String name) {\r
+        this.name = name;\r
+    }\r
+\r
+    @Override\r
+    public Object getIdentifier() {\r
+        return this;\r
+    }\r
+\r
+    @Override\r
+    public String getName() {\r
+        return this.name;\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-common/src/main/java/org/opendaylight/controller/sal/common/package-info.java b/opendaylight/sal/yang-prototype/sal/sal-common/src/main/java/org/opendaylight/controller/sal/common/package-info.java
new file mode 100644 (file)
index 0000000..e28fa94
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.common;\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/.gitignore b/opendaylight/sal/yang-prototype/sal/sal-core-api/.gitignore
new file mode 100644 (file)
index 0000000..ea8c4bf
--- /dev/null
@@ -0,0 +1 @@
+/target
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/pom.xml b/opendaylight/sal/yang-prototype/sal/sal-core-api/pom.xml
new file mode 100644 (file)
index 0000000..abdd3ad
--- /dev/null
@@ -0,0 +1,27 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>sal</artifactId>\r
+    <version>1.0-SNAPSHOT</version>\r
+  </parent>\r
+   <artifactId>sal-core-api</artifactId>\r
+   \r
+   <dependencies>\r
+               <dependency>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>sal-common</artifactId>\r
+               <version>1.0-SNAPSHOT</version>\r
+       </dependency>\r
+       <dependency>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>yang-data-api</artifactId>\r
+               <version>1.0</version>\r
+       </dependency>\r
+       <dependency>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>yang-model-api</artifactId>\r
+               <version>1.0</version>\r
+       </dependency>\r
+   </dependencies>
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/Broker.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/Broker.java
new file mode 100644 (file)
index 0000000..19c3e17
--- /dev/null
@@ -0,0 +1,233 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.api;\r
+\r
+import java.util.concurrent.Future;\r
+\r
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;\r
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;\r
+import org.opendaylight.controller.sal.core.api.notify.NotificationProviderService;\r
+import org.opendaylight.controller.sal.core.api.notify.NotificationService;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.common.RpcResult;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+\r
+\r
+/**\r
+ * Core component of the SAL layer responsible for wiring the SAL consumers.\r
+ * \r
+ * The responsibility of the broker is to maintain registration of SAL\r
+ * functionality {@link Consumer}s and {@link Provider}s, store provider and\r
+ * consumer specific context and functionality registration via\r
+ * {@link ConsumerSession} and provide access to infrastructure services, which\r
+ * removes direct dependencies between providers and consumers.\r
+ * \r
+ * \r
+ * <h3>Infrastructure services</h3> Some examples of infrastructure services:\r
+ * \r
+ * <ul>\r
+ * <li>RPC Invocation - see {@link ConsumerSession#rpc(QName, CompositeNode)},\r
+ * {@link ProviderSession#addRpcImplementation(QName, RpcImplementation)} and\r
+ * {@link RpcImplementation}\r
+ * <li>Notification Service - see {@link NotificationService} and\r
+ * {@link NotificationProviderService}\r
+ * <li>Functionality and Data model\r
+ * <li>Data Store access and modification - see {@link DataBrokerService} and\r
+ * {@link DataProviderService}\r
+ * </ul>\r
+ * \r
+ * The services are exposed via session.\r
+ * \r
+ * <h3>Session-based access</h3>\r
+ * \r
+ * The providers and consumers needs to register in order to use the\r
+ * binding-independent SAL layer and to expose functionality via SAL layer.\r
+ * \r
+ * For more information about session-based access see {@link ConsumerSession}\r
+ * and {@link ProviderSession}\r
+ * \r
+ * \r
+ * \r
+ */\r
+public interface Broker {\r
+\r
+    /**\r
+     * Registers the {@link Consumer}, which will use the SAL layer.\r
+     * \r
+     * <p>\r
+     * During the registration, the broker obtains the initial functionality\r
+     * from consumer, using the {@link Consumer#getConsumerFunctionality()}, and\r
+     * register that functionality into system and concrete infrastructure\r
+     * services.\r
+     * \r
+     * <p>\r
+     * Note that consumer could register additional functionality at later point\r
+     * by using service and functionality specific APIs.\r
+     * \r
+     * <p>\r
+     * The consumer is required to use returned session for all communication\r
+     * with broker or one of the broker services. The session is announced to\r
+     * the consumer by invoking\r
+     * {@link Consumer#onSessionInitiated(ConsumerSession)}.\r
+     * \r
+     * @param cons\r
+     *            Consumer to be registered.\r
+     * @return a session specific to consumer registration\r
+     * @throws IllegalArgumentException\r
+     *             If the consumer is <code>null</code>.\r
+     * @throws IllegalStateException\r
+     *             If the consumer is already registered.\r
+     */\r
+    ConsumerSession registerConsumer(Consumer cons);\r
+\r
+    /**\r
+     * Registers the {@link Provider}, which will use the SAL layer.\r
+     * \r
+     * <p>\r
+     * During the registration, the broker obtains the initial functionality\r
+     * from consumer, using the {@link Provider#getProviderFunctionality()}, and\r
+     * register that functionality into system and concrete infrastructure\r
+     * services.\r
+     * \r
+     * <p>\r
+     * Note that consumer could register additional functionality at later point\r
+     * by using service and functionality specific APIs (e.g.\r
+     * {@link ProviderSession#addRpcImplementation(QName, RpcImplementation)}\r
+     * \r
+     * <p>\r
+     * The consumer is <b>required to use</b> returned session for all\r
+     * communication with broker or one of the broker services. The session is\r
+     * announced to the consumer by invoking\r
+     * {@link Provider#onSessionInitiated(ProviderSession)}.\r
+     * \r
+     * \r
+     * @param prov\r
+     *            Provider to be registered.\r
+     * @return a session unique to the provider registration.\r
+     * @throws IllegalArgumentException\r
+     *             If the provider is <code>null</code>.\r
+     * @throws IllegalStateException\r
+     *             If the consumer is already registered.\r
+     */\r
+    ProviderSession registerProvider(Provider prov);\r
+\r
+    /**\r
+     * {@link Consumer} specific access to the SAL functionality.\r
+     * \r
+     * <p>\r
+     * ConsumerSession is {@link Consumer}-specific access to the SAL\r
+     * functionality and infrastructure services.\r
+     * \r
+     * <p>\r
+     * The session serves to store SAL context (e.g. registration of\r
+     * functionality) for the consumer and provides access to the SAL\r
+     * infrastructure services and other functionality provided by\r
+     * {@link Provider}s.\r
+     * \r
+\r
+     * \r
+     */\r
+    public interface ConsumerSession {\r
+\r
+        /**\r
+         * Sends an RPC to other components registered to the broker.\r
+         * \r
+         * @see RpcImplementation\r
+         * @param rpc\r
+         *            Name of RPC\r
+         * @param input\r
+         *            Input data to the RPC\r
+         * @return Result of the RPC call\r
+         */\r
+        Future<RpcResult<CompositeNode>> rpc(QName rpc, CompositeNode input);\r
+\r
+        /**\r
+         * Returns a session specific instance (implementation) of requested\r
+         * service\r
+         * \r
+         * @param service\r
+         *            Broker service\r
+         * @return Session specific implementation of service\r
+         */\r
+        <T extends BrokerService> T getService(Class<T> service);\r
+\r
+        /**\r
+         * Closes a session between consumer and broker.\r
+         * \r
+         * <p>\r
+         * The close operation unregisters a consumer and remove all registered\r
+         * functionality of the consumer from the system.\r
+         * \r
+         */\r
+        void close();\r
+    }\r
+\r
+    /**\r
+     * {@link Provider} specific access to the SAL functionality.\r
+     * \r
+     * <p>\r
+     * ProviderSession is {@link Provider}-specific access to the SAL\r
+     * functionality and infrastructure services, which also allows for exposing\r
+     * the provider's functionality to the other {@link Consumer}s.\r
+     * \r
+     * <p>\r
+     * The session serves to store SAL context (e.g. registration of\r
+     * functionality) for the providers and exposes access to the SAL\r
+     * infrastructure services, dynamic functionality registration and any other\r
+     * functionality provided by other {@link Provider}s.\r
+     * \r
+     */\r
+    public interface ProviderSession extends ConsumerSession {\r
+        /**\r
+         * Registers an implementation of the rpc.\r
+         * \r
+         * <p>\r
+         * The registered rpc functionality will be available to all other\r
+         * consumers and providers registered to the broker, which are aware of\r
+         * the {@link QName} assigned to the rpc.\r
+         * \r
+         * <p>\r
+         * There is no assumption that rpc type is in the set returned by\r
+         * invoking {@link RpcImplementation#getSupportedRpcs()}. This allows\r
+         * for dynamic rpc implementations.\r
+         * \r
+         * @param rpcType\r
+         *            Name of Rpc\r
+         * @param implementation\r
+         *            Provider's Implementation of the RPC functionality\r
+         * @throws IllegalArgumentException\r
+         *             If the name of RPC is invalid\r
+         */\r
+        void addRpcImplementation(QName rpcType,\r
+                RpcImplementation implementation)\r
+                throws IllegalArgumentException;\r
+\r
+        /**\r
+         * Unregisters an Rpc implementation\r
+         * \r
+         * @param rpcType\r
+         *            Name of Rpc\r
+         * @param implementation\r
+         *            Registered Implementation of the Rpc functionality\r
+         * @throws IllegalArgumentException\r
+         */\r
+        void removeRpcImplementation(QName rpcType,\r
+                RpcImplementation implementation)\r
+                throws IllegalArgumentException;\r
+\r
+        /**\r
+         * Closes a session between provider and SAL.\r
+         * \r
+         * <p>\r
+         * The close operation unregisters a provider and remove all registered\r
+         * functionality of the provider from the system.\r
+         */\r
+        @Override\r
+        public void close();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/BrokerService.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/BrokerService.java
new file mode 100644 (file)
index 0000000..b854188
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.api;\r
+\r
+import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;\r
+\r
+/**\r
+ * \r
+ * Session-specific instance of the broker functionality.\r
+ * \r
+ * <p>\r
+ * BrokerService is marker interface for infrastructure services provided by the\r
+ * SAL. These services are session-specific, each {@link Provider} and\r
+ * {@link Consumer} usually has own instance of the service with it's own\r
+ * context.\r
+ * \r
+ * <p>\r
+ * The consumer's (or provider's) instance of specific service could be obtained\r
+ * by invoking {@link ConsumerSession#getService(Class)} method on session\r
+ * assigned to the consumer.\r
+ * \r
+ * <p>\r
+ * {@link BrokerService} and {@link Provider} may seem similar, but provider\r
+ * provides YANG model-based functionality and {@link BrokerService} exposes the\r
+ * necessary supporting functionality to implement specific functionality of\r
+ * YANG and to reuse it in the development of {@link Consumer}s and\r
+ * {@link Provider}s.\r
+ * \r
+ * \r
+ */\r
+public interface BrokerService {\r
+\r
+    void closeSession();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/Consumer.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/Consumer.java
new file mode 100644 (file)
index 0000000..1b223f9
--- /dev/null
@@ -0,0 +1,59 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.api;\r
+\r
+import java.util.Collection;\r
+\r
+import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;\r
+\r
+/**\r
+ * \r
+ * Defines the component of controller and supplies additional metadata. A\r
+ * component of the controller or application supplies a concrete implementation\r
+ * of this interface.\r
+ * \r
+ * A user-implemented component (application) which faciliates the SAL and SAL\r
+ * services to access infrastructure services or providers' functionality.\r
+ * \r
+ * \r
+ */\r
+public interface Consumer {\r
+\r
+    /**\r
+     * Callback signaling initialization of the consumer session to the SAL.\r
+     * \r
+     * The consumer MUST use the session for all communication with SAL or\r
+     * retrieving SAL infrastructure services.\r
+     * \r
+     * This method is invoked by {@link Broker#registerConsumer(Consumer)}\r
+     * \r
+     * @param session\r
+     *            Unique session between consumer and SAL.\r
+     */\r
+    public void onSessionInitiated(ConsumerSession session);\r
+\r
+    /**\r
+     * Get a set of implementations of consumer functionality to be registered\r
+     * into system during the consumer registration to the SAL.\r
+     * \r
+     * This method is invoked by {@link Broker#registerConsumer(Consumer)}.\r
+     * \r
+     * @return Set of consumer functionality.\r
+     */\r
+    public Collection<ConsumerFunctionality> getConsumerFunctionality();\r
+\r
+    /**\r
+     * The marker interface for the interfaces describing the consumer\r
+     * functionality contracts.\r
+     * \r
+     * \r
+     */\r
+    public interface ConsumerFunctionality {\r
+\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/Provider.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/Provider.java
new file mode 100644 (file)
index 0000000..dff636f
--- /dev/null
@@ -0,0 +1,69 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.api;\r
+\r
+import java.util.Collection;\r
+\r
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;\r
+\r
+/**\r
+ * \r
+ * Defines the component of controller and supplies additional metadata. A\r
+ * component of the controller or application supplies a concrete implementation\r
+ * of this interface.\r
+ * \r
+ * <p>\r
+ * A user-implemented component (application) which faciliates the SAL and SAL\r
+ * services to access infrastructure services and to provide functionality to\r
+ * {@link Consumer}s and other providers.\r
+ * \r
+ * \r
+ */\r
+public interface Provider {\r
+\r
+    /**\r
+     * Callback signaling initialization of the provider session to the SAL.\r
+     * \r
+     * <p>\r
+     * The provider <b>MUST use the session</b> for all communication with SAL\r
+     * or retrieving SAL infrastructure services.\r
+     * \r
+     * <p>\r
+     * This method is invoked by {@link Broker#registerConsumer(Consumer)}\r
+     * \r
+     * @param session\r
+     *            Unique session between provider and SAL.\r
+     */\r
+    public void onSessionInitiated(ProviderSession session);\r
+\r
+    /**\r
+     * Gets a set of implementations of provider functionality to be registered\r
+     * into system during the provider registration to the SAL.\r
+     * \r
+     * <p>\r
+     * This method is invoked by {@link Broker#registerProvider(Provider)} to\r
+     * learn the initial provided functionality\r
+     * \r
+     * @return Set of provider's functionality.\r
+     */\r
+    public Collection<ProviderFunctionality> getProviderFunctionality();\r
+\r
+    /**\r
+     * Functionality provided by the {@link Provider}\r
+     * \r
+     * <p>\r
+     * Marker interface used to mark the interfaces describing specific\r
+     * functionality which could be exposed by providers to other components.\r
+     * \r
+\r
+     * \r
+     */\r
+    public interface ProviderFunctionality {\r
+\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcImplementation.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcImplementation.java
new file mode 100644 (file)
index 0000000..ef5aa70
--- /dev/null
@@ -0,0 +1,81 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.api;\r
+\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;\r
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.common.RpcResult;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+\r
+/**\r
+ * {@link Provider}'s implementation of rpc.\r
+ * \r
+ * In order to expose the rpc to other components, the provider MUST register\r
+ * concrete implementation of this interface\r
+ * \r
+ * The registration could be done by :\r
+ * <ul>\r
+ * <li>returning an instance of implementation in the return value of\r
+ * {@link Provider#getProviderFunctionality()}\r
+ * <li>passing an instance of implementation and {@link QName} of rpc as\r
+ * arguments to the\r
+ * {@link ProviderSession#addRpcImplementation(QName, RpcImplementation)}\r
+ * </ul>\r
+ * \r
+ * The simplified process of the invocation of rpc is following:\r
+ * \r
+ * <ol>\r
+ * <li> {@link Consumer} invokes\r
+ * {@link ConsumerSession#rpc(QName, CompositeNode)}\r
+ * <li> {@link Broker} finds registered {@link RpcImplementation}s\r
+ * <li> {@link Broker} invokes\r
+ * {@link RpcImplementation#invokeRpc(QName, CompositeNode)}\r
+ * <li> {@link RpcImplementation} processes the data and returns a\r
+ * {@link RpcResult}\r
+ * <li> {@link Broker} returns the {@link RpcResult} to {@link Consumer}\r
+ * </ol>\r
+ * \r
+ * \r
+ */\r
+public interface RpcImplementation extends Provider.ProviderFunctionality {\r
+\r
+    /**\r
+     * A set of rpc types supported by implementation.\r
+     * \r
+     * The set of rpc {@link QName}s which are supported by this implementation.\r
+     * This set is used, when {@link Provider} is registered to the SAL, to\r
+     * register and expose the implementation of the returned rpcs.\r
+     * \r
+     * @return Set of QNames identifying supported RPCs\r
+     */\r
+    Set<QName> getSupportedRpcs();\r
+\r
+    /**\r
+     * Invokes a implementation of specified rpc.\r
+     * \r
+     * \r
+     * @param rpc\r
+     *            Rpc to be invoked\r
+     * @param input\r
+     *            Input data for rpc.\r
+     * \r
+     * @throws IllegalArgumentException\r
+     *             <ul>\r
+     *             <li>If rpc is null.\r
+     *             <li>If input is not <code>null</code> and\r
+     *             <code>false == rpc.equals(input.getNodeType)</code>\r
+     *             </ul>\r
+     * @return RpcResult containing the output of rpc if was executed\r
+     *         successfully, the list of errors otherwise.\r
+     */\r
+    RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input);\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataBrokerService.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataBrokerService.java
new file mode 100644 (file)
index 0000000..f5f3938
--- /dev/null
@@ -0,0 +1,132 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.api.data;\r
+\r
+import java.util.concurrent.Future;\r
+\r
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;\r
+import org.opendaylight.controller.sal.core.api.BrokerService;\r
+import org.opendaylight.controller.sal.core.api.Consumer;\r
+import org.opendaylight.controller.sal.core.api.Provider;\r
+import org.opendaylight.controller.yang.common.RpcResult;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.CompositeNodeModification;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+\r
+\r
+/**\r
+ * DataBrokerService provides unified access to the data stores available in the\r
+ * system.\r
+ * \r
+ * \r
+ * @see DataProviderService\r
+ * \r
+ */\r
+public interface DataBrokerService extends BrokerService {\r
+\r
+    /**\r
+     * Returns a data from specified Data Store.\r
+     * \r
+     * Returns all the data visible to the consumer from specified Data Store.\r
+     * \r
+     * @param store\r
+     *            Identifier of the store, from which will be data retrieved\r
+     * @return data visible to the consumer\r
+     */\r
+    CompositeNode getData(DataStoreIdentifier store);\r
+\r
+    /**\r
+     * Returns a filtered subset of data from specified Data Store.\r
+     * \r
+     * <p>\r
+     * The filter is modeled as an hierarchy of {@link Node} starting with\r
+     * {@link CompositeNode} representing data root. The semantics of the filter\r
+     * tree is the same as filter semantics defined in the NETCONF protocol for\r
+     * rpc operations <code>get</code> and <code>get-config</code> in Section 6\r
+     * of RFC6241.\r
+     * \r
+     * \r
+     * @see http://tools.ietf.org/html/rfc6241#section-6\r
+     * @param store\r
+     *            Identifier of the store, from which will be data retrieved\r
+     * @param filter\r
+     *            Data tree filter similar to the NETCONF filter\r
+     * @return\r
+     */\r
+    CompositeNode getData(DataStoreIdentifier store, CompositeNode filter);\r
+\r
+    /**\r
+     * Returns a candidate data which are not yet commited.\r
+     * \r
+     * \r
+     * @param store\r
+     *            Identifier of the store, from which will be data retrieved\r
+     * @return\r
+     */\r
+    CompositeNode getCandidateData(DataStoreIdentifier store);\r
+\r
+    /**\r
+     * Returns a filtered subset of candidate data from specified Data Store.\r
+     * \r
+     * <p>\r
+     * The filter is modeled as an hierarchy of {@link Node} starting with\r
+     * {@link CompositeNode} representing data root. The semantics of the filter\r
+     * tree is the same as filter semantics defined in the NETCONF protocol for\r
+     * rpc operations <code>get</code> and <code>get-config</code> in Section 6\r
+     * of RFC6241.\r
+     * \r
+     * \r
+     * @see http://tools.ietf.org/html/rfc6241#section-6\r
+     * @param store\r
+     *            Identifier of the store, from which will be data retrieved\r
+     * @param filter\r
+     *            A CompositeNode filter\r
+     * @return\r
+     */\r
+    CompositeNode getCandidateData(DataStoreIdentifier store,\r
+            CompositeNode filter);\r
+\r
+    /**\r
+     * \r
+     * @param store\r
+     *            Identifier of the store, in which will be the candidate data\r
+     *            modified\r
+     * @param changeSet\r
+     *            Modification of data tree.\r
+     * @return Result object containing the modified data tree if the operation\r
+     *         was successful, otherwise list of the encountered errors.\r
+     */\r
+    RpcResult<CompositeNode> editCandidateData(DataStoreIdentifier store,\r
+            CompositeNodeModification changeSet);\r
+\r
+    /**\r
+     * Initiates a two-phase commit of candidate data.\r
+     * \r
+     * <p>\r
+     * The {@link Consumer} could initiate a commit of candidate data\r
+     * \r
+     * <p>\r
+     * The successful commit changes the state of the system and may affect\r
+     * several components.\r
+     * \r
+     * <p>\r
+     * The effects of successful commit of data are described in the\r
+     * specifications and YANG models describing the {@link Provider} components\r
+     * of controller. It is assumed that {@link Consumer} has an understanding\r
+     * of this changes.\r
+     * \r
+     * \r
+     * @see DataCommitHandler for further information how two-phase commit is\r
+     *      processed.\r
+     * @param store\r
+     *            Identifier of the store, where commit should occur.\r
+     * @return Result of the commit, containing success information or list of\r
+     *         encountered errors, if commit was not successful.\r
+     */\r
+    Future<RpcResult<Void>> commit(DataStoreIdentifier store);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataCommitHandler.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataCommitHandler.java
new file mode 100644 (file)
index 0000000..f0cc02d
--- /dev/null
@@ -0,0 +1,164 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.api.data;\r
+\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;\r
+import org.opendaylight.controller.sal.core.api.Provider;\r
+import org.opendaylight.controller.yang.common.RpcResult;\r
+\r
+\r
+/**\r
+ * Two phase commit handler (cohort) of the two-phase commit protocol of data.\r
+ * \r
+ * <p>\r
+ * The provider should expose the implementation of DataCommitHandler if it's\r
+ * functionality depends on any subset of data stored in data repositories, in\r
+ * order to participate in {@link DataBrokerService#commit(DataStoreIdentifier)\r
+ * operation.\r
+ * \r
+ * <p>\r
+ * Operations of two-phase commit handlers should not change data in data store,\r
+ * this is responsibility of the coordinator (broker or some component of the\r
+ * broker).\r
+ * \r
+ * The commit handlers are responsible for changing the internal state of the\r
+ * provider to reflect the commited changes in data.\r
+ * \r
+ * <h3>Two-phase commit</h3>\r
+ * \r
+ * <h4>Commit Request Phase</h4>\r
+ * \r
+ * <ol>\r
+ * <li> <code>Consumer</code> edits data by invocation of\r
+ * <code>DataBrokerService.editCandidateData(DataStoreIdentifier, CompositeNodeModification)</code>\r
+ * <li> <code>Consumer</code> starts a commit by invoking\r
+ * <code>DataBrokerService.commit(DataStoreIdentifier)</code>\r
+ * <li> <code>Broker</code> retrieves a list of all registered\r
+ * <code>DataCommitHandlers</code>\r
+ * <li>For each <code>DataCommitHandler</code>\r
+ * <ol>\r
+ * <li><code>Broker</code> invokes a\r
+ * <code>DataCommitHandler.requestCommit(DataStoreIdentifier)</code> operation.\r
+ * <li><code>DataCommitHandler</code> returns a <code>RpcResult</code> with\r
+ * <code>CommitTransaction</code>\r
+ * <li>If the result was successful, broker adds <code>CommitTransaction</code>\r
+ * to the list of opened transactions. If not, brokers stops a commit request\r
+ * phase and starts a rollback phase.\r
+ * </ol>\r
+ * <li><code>Broker</code> starts a commit finish phase\r
+ * </ol>\r
+ * \r
+ * <h4>Commit Finish Phase</h4>\r
+ * \r
+ * <ol>\r
+ * <li>For each <code>CommitTransaction</code> from Commit Request phase\r
+ * <ol>\r
+ * <li><code>Broker</code> broker invokes a\r
+ * <code>CommitTransaction.finish()</code>\r
+ * <li>The provider finishes a commit (applies the change) and returns an\r
+ * <code>RpcResult</code>.\r
+ * </ol>\r
+ * <li>\r
+ * <ul>\r
+ * <li>If all returned results means successful, the brokers end two-phase\r
+ * commit by returning a success commit result to the Consumer.\r
+ * <li>If error occured, the broker starts a commit rollback phase.\r
+ * </ul>\r
+ * </ol>\r
+ * \r
+ * <h4>Commit Rollback Phase</h4>\r
+ * <li>For each <code>CommitTransaction</code> from Commit Request phase\r
+ * <ol>\r
+ * <li><code>Broker</code>\r
+ * \r
+ * broker invokes a {@link CommitTransaction#finish()}\r
+ * <li>The provider rollbacks a commit and returns an {@link RpcResult} of\r
+ * rollback. </ol>\r
+ * <li>Broker returns a error result to the consumer.\r
+ * \r
+ * \r
+ * <h3>Registration of functionality</h3>\r
+ * The registration could be done by :\r
+ * <ul>\r
+ * <li>returning an instance of implementation in the return value of\r
+ * {@link Provider#getProviderFunctionality()}\r
+ * <li>passing an instance of implementation and {@link DataStoreIdentifier} of\r
+ * rpc as arguments to the\r
+ * {@link DataProviderService#addCommitHandler(DataStoreIdentifier, DataCommitHandler)}\r
+ * </ul>\r
+ * \r
+ * \r
+ */\r
+public interface DataCommitHandler extends Provider.ProviderFunctionality {\r
+\r
+    /**\r
+     * A set of Data Stores supported by implementation.\r
+     * \r
+     * The set of {@link DataStoreIdentifier}s which identifies target data\r
+     * stores which are supported by this commit handler. This set is used, when\r
+     * {@link Provider} is registered to the SAL, to register and expose the\r
+     * commit handler functionality to affected data stores.\r
+     * \r
+     * @return Set of Data Store identifiers\r
+     */\r
+    Set<DataStoreIdentifier> getSupportedDataStores();\r
+\r
+    /**\r
+     * The provider (commit handler) starts a commit transaction.\r
+     * \r
+     * <p>\r
+     * The commit handler (provider) prepares an commit scenario, rollback\r
+     * scenario and validates data.\r
+     * \r
+     * <p>\r
+     * If the provider is aware that at this point the commit would not be\r
+     * successful, the transaction is not created, but list of errors which\r
+     * prevented the start of transaction are returned.\r
+     * \r
+     * @param store\r
+     * @return Transaction object representing this commit, errors otherwise.\r
+     */\r
+    RpcResult<CommitTransaction> requestCommit(DataStoreIdentifier store);\r
+\r
+    public interface CommitTransaction {\r
+        /**\r
+         * \r
+         * @return Data store affected by the transaction\r
+         */\r
+        DataStoreIdentifier getDataStore();\r
+\r
+        /**\r
+         * Returns the handler associated with this transaction.\r
+         * \r
+         * @return Handler\r
+         */\r
+        DataCommitHandler getHandler();\r
+\r
+        /**\r
+         * \r
+         * Finishes a commit.\r
+         * \r
+         * The provider (commit handler) should apply all changes to its state\r
+         * which are a result of data change-\r
+         * \r
+         * @return\r
+         */\r
+        RpcResult<Void> finish() throws IllegalStateException;\r
+\r
+        /**\r
+         * Rollbacks a commit.\r
+         * \r
+         * @return\r
+         * @throws IllegalStateException\r
+         *             If the method is invoked after {@link #finish()}\r
+         */\r
+        RpcResult<Void> rollback() throws IllegalStateException;\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataProviderService.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataProviderService.java
new file mode 100644 (file)
index 0000000..5c5423d
--- /dev/null
@@ -0,0 +1,78 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.api.data;\r
+\r
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;\r
+import org.opendaylight.controller.sal.core.api.Provider;\r
+\r
+public interface DataProviderService extends DataBrokerService {\r
+\r
+    /**\r
+     * Adds {@link DataValidator} for specified Data Store\r
+     * \r
+     * @param store\r
+     *            Data Store\r
+     * @param validator\r
+     *            Validator\r
+     */\r
+    public void addValidator(DataStoreIdentifier store, DataValidator validator);\r
+\r
+    /**\r
+     * Removes {@link DataValidator} from specified Data Store\r
+     * \r
+     * @param store\r
+     * @param validator\r
+     *            Validator\r
+     */\r
+    public void removeValidator(DataStoreIdentifier store,\r
+            DataValidator validator);\r
+\r
+    /**\r
+     * Adds {@link DataCommitHandler} for specified data store\r
+     * \r
+     * @param store\r
+     * @param provider\r
+     */\r
+    void addCommitHandler(DataStoreIdentifier store, DataCommitHandler provider);\r
+\r
+    /**\r
+     * Removes {@link DataCommitHandler} from specified data store\r
+     * \r
+     * @param store\r
+     * @param provider\r
+     */\r
+    void removeCommitHandler(DataStoreIdentifier store,\r
+            DataCommitHandler provider);\r
+\r
+    /**\r
+     * Adds {@link DataRefresher} for specified data store\r
+     * \r
+     * @param store\r
+     * @param refresher\r
+     */\r
+    void addRefresher(DataStoreIdentifier store, DataRefresher refresher);\r
+\r
+    /**\r
+     * Removes {@link DataRefresher} from specified data store\r
+     * \r
+     * @param store\r
+     * @param refresher\r
+     */\r
+    void removeRefresher(DataStoreIdentifier store, DataRefresher refresher);\r
+\r
+    public interface DataRefresher extends Provider.ProviderFunctionality {\r
+\r
+        /**\r
+         * Fired when some component explicitly requested the data refresh.\r
+         * \r
+         * The provider which exposed the {@link DataRefresher} should republish\r
+         * its provided data by editing the data in all affected data stores.\r
+         */\r
+        void refreshData();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataValidator.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataValidator.java
new file mode 100644 (file)
index 0000000..a2105b4
--- /dev/null
@@ -0,0 +1,57 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.api.data;\r
+\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;\r
+import org.opendaylight.controller.sal.core.api.Provider;\r
+import org.opendaylight.controller.yang.common.RpcResult;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+\r
+\r
+/**\r
+ * {@link Provider}-supplied Validator of the data.\r
+ * \r
+ * <p>\r
+ * The registration could be done by :\r
+ * <ul>\r
+ * <li>returning an instance of implementation in the return value of\r
+ * {@link Provider#getProviderFunctionality()}\r
+ * <li>passing an instance of implementation and {@link DataStoreIdentifier} rpc\r
+ * as arguments to the\r
+ * {@link DataProviderService#addValidator(DataStoreIdentifier, DataValidator)}\r
+ * </ul>\r
+ * \r
+ **/\r
+public interface DataValidator extends Provider.ProviderFunctionality {\r
+\r
+    /**\r
+     * A set of Data Stores supported by implementation.\r
+     * \r
+     * The set of {@link DataStoreIdentifier}s which identifies target data\r
+     * stores which are supported by this implementation. This set is used, when\r
+     * {@link Provider} is registered to the SAL, to register and expose the\r
+     * validation functionality to affected data stores.\r
+     * \r
+     * @return Set of Data Store identifiers\r
+     */\r
+    Set<DataStoreIdentifier> getSupportedDataStores();\r
+\r
+    /**\r
+     * Performs validation on supplied data.\r
+     * \r
+     * @param toValidate\r
+     *            Data to validate\r
+     * @return Validation result. The\r
+     *         <code>{@link RpcResult#isSuccessful()} == true</code> if the data\r
+     *         passed validation, otherwise contains list of errors.\r
+     */\r
+    RpcResult<Void> validate(CompositeNode toValidate);\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/package-info.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/data/package-info.java
new file mode 100644 (file)
index 0000000..b58659a
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.api.data;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/NotificationListener.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/NotificationListener.java
new file mode 100644 (file)
index 0000000..5f72c62
--- /dev/null
@@ -0,0 +1,42 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.api.notify;\r
+\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.sal.core.api.Consumer;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+\r
+\r
+/**\r
+ * Notification listener for SAL notifications.\r
+ */\r
+public interface NotificationListener extends Consumer.ConsumerFunctionality {\r
+    /**\r
+     * A set of notification types supported by listeners.\r
+     * \r
+     * The set of notification {@link QName}s which are supported by this\r
+     * listener. This set is used, when {@link Consumer} is registered to the\r
+     * SAL, to automatically register the listener.\r
+     * \r
+     * @return Set of QNames identifying supported notifications.\r
+     */\r
+    Set<QName> getSupportedNotifications();\r
+\r
+    /**\r
+     * Fired when the notification occurs.\r
+     * \r
+     * The type of the notification could be learned by\r
+     * <code>QName type = notification.getNodeType();</code>\r
+     * \r
+     * @param notification\r
+     *            Notification content\r
+     */\r
+    void onNotification(CompositeNode notification);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/NotificationProviderService.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/NotificationProviderService.java
new file mode 100644 (file)
index 0000000..9367645
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.api.notify;\r
+\r
+import org.opendaylight.controller.sal.core.api.Broker;\r
+import org.opendaylight.controller.sal.core.api.BrokerService;\r
+import org.opendaylight.controller.sal.core.api.Provider;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+\r
+\r
+/**\r
+ * Notification Publishing Service\r
+ * \r
+ * The simplified process of the notification publishing is following:\r
+ * \r
+ * <ol>\r
+ * <li> {@link Provider} invokes {@link #sendNotification(CompositeNode)}\r
+ * <li> {@link Broker} finds {@link NotificationListener}s which subscribed for\r
+ * the notification type.\r
+ * \r
+ * <li>For each subscriber {@link Broker} invokes\r
+ * {@link NotificationListener#onNotification(CompositeNode)}\r
+ * </ol>\r
+ * \r
+ * \r
+ * \r
+ */\r
+public interface NotificationProviderService extends BrokerService {\r
+\r
+    /**\r
+     * Publishes a notification.\r
+     * \r
+     * Notification type is determined by the\r
+     * {@link CompositeNode#getNodeType()} of the\r
+     * <code>notification<code> parameter.\r
+     * \r
+     * @param notification\r
+     *            Notification to publish\r
+     */\r
+    void sendNotification(CompositeNode notification);\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/NotificationService.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/NotificationService.java
new file mode 100644 (file)
index 0000000..98a4925
--- /dev/null
@@ -0,0 +1,54 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.api.notify;\r
+\r
+import org.opendaylight.controller.sal.core.api.BrokerService;\r
+import org.opendaylight.controller.sal.core.api.Provider;\r
+import org.opendaylight.controller.sal.core.api.RpcImplementation;\r
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+\r
+/**\r
+ * NotificationService provides access to the notification functionality of the\r
+ * SAL.\r
+ * \r
+ * NotificationService allows for consumption of notifications by registering\r
+ * implementations of NotificationListener.\r
+ * \r
+ * The registration of notification listeners could be done by:\r
+ * <ul>\r
+ * <li>returning an instance of implementation in the return value of\r
+ * {@link Provider#getProviderFunctionality()}\r
+ * <li>passing an instance of implementation and {@link QName} of rpc as an\r
+ * arguments to the\r
+ * {@link ProviderSession#addRpcImplementation(QName, RpcImplementation)}\r
+ * </ul>\r
+ * \r
+ * \r
+ */\r
+public interface NotificationService extends BrokerService {\r
+\r
+    /**\r
+     * Registers a notification listener for supplied notification type.\r
+     * \r
+     * @param notification\r
+     * @param listener\r
+     */\r
+    void addNotificationListener(QName notification,\r
+            NotificationListener listener);\r
+\r
+    /**\r
+     * Removes a notification listener for supplied notification type.\r
+     * \r
+     * @param notification\r
+     * @param listener\r
+     */\r
+    void removeNotificationListener(QName notification,\r
+            NotificationListener listener);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/package-info.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/package-info.java
new file mode 100644 (file)
index 0000000..b686834
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+/**\r
+ * SAL Notification functionality\r
+ */\r
+package org.opendaylight.controller.sal.core.api.notify;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/package-info.java b/opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/package-info.java
new file mode 100644 (file)
index 0000000..a058df3
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+/**\r
+ * Core binding-independent SAL contracts and components\r
+ */\r
+package org.opendaylight.controller.sal.core.api;\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-demo/pom.xml b/opendaylight/sal/yang-prototype/sal/sal-core-demo/pom.xml
new file mode 100644 (file)
index 0000000..91dd78c
--- /dev/null
@@ -0,0 +1,30 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+       <modelVersion>4.0.0</modelVersion>\r
+       <parent>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>sal</artifactId>\r
+               <version>1.0-SNAPSHOT</version>\r
+       </parent>\r
+       <artifactId>sal-core-demo</artifactId>\r
+\r
+       <dependencies>\r
+               <dependency>\r
+               \r
+                       <groupId>org.opendaylight.controller</groupId>\r
+                       <artifactId>sal-broker-impl</artifactId>\r
+                       <version>1.0-SNAPSHOT</version>\r
+               </dependency>\r
+               <dependency>\r
+                       <groupId>org.opendaylight.controller</groupId>\r
+                       <artifactId>yang-data-util</artifactId>\r
+                       <version>1.0</version>\r
+               </dependency>\r
+               <dependency>\r
+                       <groupId>org.slf4j</groupId>\r
+                       <artifactId>slf4j-simple</artifactId>\r
+                       <version>1.7.2</version>\r
+                       <scope>runtime</scope>\r
+               </dependency>\r
+       </dependencies>
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoConsumerImpl.java b/opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoConsumerImpl.java
new file mode 100644 (file)
index 0000000..e0752dc
--- /dev/null
@@ -0,0 +1,107 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.demo;\r
+\r
+import java.util.Collection;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.sal.core.api.Consumer;\r
+import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;\r
+import org.opendaylight.controller.sal.core.api.notify.NotificationListener;\r
+import org.opendaylight.controller.sal.core.api.notify.NotificationService;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+\r
+public class DemoConsumerImpl implements Consumer {\r
+\r
+    private ConsumerSession session;\r
+    private NotificationService notificationService;\r
+    private final String name;\r
+    private static Logger log = LoggerFactory.getLogger("AlertLogger");\r
+\r
+    private boolean changeAware;\r
+\r
+    public DemoConsumerImpl(String name) {\r
+        this.name = name;\r
+    }\r
+\r
+    private NotificationListener alertLogger = new NotificationListener() {\r
+\r
+        @Override\r
+        public void onNotification(CompositeNode notification) {\r
+            System.out.println(name\r
+                    + ": Received alert: "\r
+                    + notification.getFirstSimpleByName(\r
+                            DemoUtils.contentNodeName).getValue());\r
+            log.info("AlertLogger: Received notification: " + notification);\r
+        }\r
+\r
+        @Override\r
+        public Set<QName> getSupportedNotifications() {\r
+            Set<QName> supported = new HashSet<QName>();\r
+            supported.add(DemoUtils.alertNotification);\r
+            return supported;\r
+        }\r
+    };\r
+\r
+    private NotificationListener changeLogger = new NotificationListener() {\r
+\r
+        @Override\r
+        public void onNotification(CompositeNode notification) {\r
+            System.out.println(name\r
+                    + ": Received change: "\r
+                    + notification.getFirstSimpleByName(\r
+                            DemoUtils.contentNodeName).getValue());\r
+            log.info("ChangeLogger: Received notification: " + notification);\r
+        }\r
+\r
+        @Override\r
+        public Set<QName> getSupportedNotifications() {\r
+            Set<QName> supported = new HashSet<QName>();\r
+            supported.add(DemoUtils.alertNotification);\r
+            return supported;\r
+        }\r
+    };\r
+\r
+    @Override\r
+    public void onSessionInitiated(ConsumerSession session) {\r
+        this.session = session;\r
+        this.notificationService = session\r
+                .getService(NotificationService.class);\r
+        notificationService.addNotificationListener(\r
+                DemoUtils.alertNotification, alertLogger);\r
+        if (isChangeAware()) {\r
+            notificationService.addNotificationListener(\r
+                    DemoUtils.changeNotification, changeLogger);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public Collection<ConsumerFunctionality> getConsumerFunctionality() {\r
+        Set<ConsumerFunctionality> func = new HashSet<ConsumerFunctionality>();\r
+        func.add(alertLogger);\r
+        return func;\r
+    }\r
+\r
+    public void closeSession() {\r
+        session.close();\r
+    }\r
+\r
+    public boolean isChangeAware() {\r
+        return changeAware;\r
+    }\r
+\r
+    public void setChangeAware(boolean changeAware) {\r
+        this.changeAware = changeAware;\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoProviderImpl.java b/opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoProviderImpl.java
new file mode 100644 (file)
index 0000000..2cb04e1
--- /dev/null
@@ -0,0 +1,69 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.demo;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.data.util.Nodes;\r
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;\r
+import org.opendaylight.controller.sal.core.api.notify.NotificationProviderService;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+\r
+\r
+public class DemoProviderImpl implements\r
+        org.opendaylight.controller.sal.core.api.Provider {\r
+\r
+    private ProviderSession session;\r
+    private NotificationProviderService notifier;\r
+\r
+    @Override\r
+    public void onSessionInitiated(ProviderSession session) {\r
+        this.session = session;\r
+        notifier = session.getService(NotificationProviderService.class);\r
+    }\r
+\r
+    @Override\r
+    public Collection<ProviderFunctionality> getProviderFunctionality() {\r
+        return Collections.emptySet();\r
+    }\r
+\r
+    public void sendAlertNotification(String content) {\r
+        List<Node<?>> nodes = new ArrayList<Node<?>>();\r
+        nodes.add(DemoUtils.contentNode(content));\r
+\r
+        if (notifier == null) {\r
+            System.out.println("Provider: Error: Session not available");\r
+            System.out\r
+                    .println("                 Notification Service not available");\r
+            return;\r
+        }\r
+        notifier.sendNotification(Nodes.containerNode(\r
+                DemoUtils.alertNotification, nodes));\r
+    }\r
+\r
+    public void sendChangeNotification(String content) {\r
+        List<Node<?>> nodes = new ArrayList<Node<?>>();\r
+        nodes.add(DemoUtils.contentNode(content));\r
+\r
+        if (notifier == null) {\r
+            System.out.println("Provider: Error: Session not available");\r
+            System.out\r
+                    .println("                 Notification Service not available");\r
+            return;\r
+        }\r
+        notifier.sendNotification(Nodes.containerNode(\r
+                DemoUtils.changeNotification, nodes));\r
+    }\r
+\r
+    public void closeSession() {\r
+        session.close();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoUtils.java b/opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoUtils.java
new file mode 100644 (file)
index 0000000..ffc06a5
--- /dev/null
@@ -0,0 +1,44 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.demo;\r
+\r
+import java.net.URI;\r
+import java.net.URISyntaxException;\r
+import java.util.Date;\r
+\r
+import org.opendaylight.controller.data.util.Nodes;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+\r
+\r
+public class DemoUtils {\r
+\r
+    public static final URI namespace = uri("urn:cisco:prototype:sal:demo");\r
+    public static final Date revision = new Date();\r
+\r
+    public static final QName alertNotification = qName("alert");\r
+    public static final QName changeNotification = qName("change");\r
+\r
+    public static final QName contentNodeName = qName("content");\r
+\r
+    public static URI uri(String str) {\r
+        try {\r
+            return new URI(str);\r
+        } catch (URISyntaxException e) {\r
+            throw new IllegalArgumentException(e);\r
+        }\r
+    }\r
+\r
+    public static QName qName(String str) {\r
+        return new QName(namespace, revision, str);\r
+    }\r
+\r
+    public static Node<?> contentNode(String content) {\r
+        return Nodes.leafNode(contentNodeName, content);\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/SALDemo.java b/opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/SALDemo.java
new file mode 100644 (file)
index 0000000..b582349
--- /dev/null
@@ -0,0 +1,154 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.demo;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.IOException;\r
+import java.io.InputStreamReader;\r
+\r
+import org.opendaylight.controller.sal.core.impl.BrokerImpl;\r
+import org.opendaylight.controller.sal.core.impl.notify.NotificationModule;\r
+\r
+\r
+public class SALDemo {\r
+\r
+    static BrokerImpl broker;\r
+    static DemoProviderImpl provider;\r
+    static DemoConsumerImpl consumer1;\r
+    static DemoConsumerImpl consumer2;\r
+\r
+    public static void main(String[] args) {\r
+\r
+        initialize();\r
+        initializeProvider();\r
+        displayHelp();\r
+\r
+        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));\r
+        String s;\r
+        try {\r
+            while (true) {\r
+\r
+                System.out.print("\nEnter your choice (0 - list): ");\r
+                s = in.readLine();\r
+                int choice = Integer.parseInt(s.trim());\r
+                try {\r
+                    switch (choice) {\r
+                    case 0:\r
+                        displayHelp();\r
+                        break;\r
+                    case 1:\r
+                        registerProvider();\r
+                        break;\r
+                    case 2:\r
+                        registerConsumer1();\r
+                        break;\r
+                    case 3:\r
+                        registerConsumer2();\r
+                        break;\r
+                    case 4:\r
+                        sendAlert(in);\r
+                        break;\r
+                    case 5:\r
+                        sendChange(in);\r
+                        break;\r
+                    case 6:\r
+                        unregisterConsumer1();\r
+                        break;\r
+                    case 7:\r
+                        unregisterConsumer2();\r
+                        break;\r
+                    case 8:\r
+                        unregisterProvider();\r
+                        break;\r
+                    case 9:\r
+                        return;\r
+                    default:\r
+                        System.out.println("Please enter valid input.");\r
+                        break;\r
+                    }\r
+                } catch (Exception e) {\r
+                    System.out\r
+                            .println("Operation failed. Reason exception raised: "\r
+                                    + e.getClass().getSimpleName());\r
+                    System.out.println("   Message: " + e.getMessage());\r
+                }\r
+\r
+            }\r
+        } catch (IOException e) {\r
+\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    private static void registerConsumer1() {\r
+        broker.registerConsumer(consumer1);\r
+    }\r
+\r
+    private static void registerConsumer2() {\r
+        broker.registerConsumer(consumer2);\r
+    }\r
+\r
+    private static void sendAlert(BufferedReader in) throws IOException {\r
+        System.out.print("Please enter notification content:");\r
+        String content = in.readLine();\r
+        provider.sendAlertNotification(content);\r
+    }\r
+\r
+    private static void sendChange(BufferedReader in) throws IOException {\r
+        System.out.print("Please enter notification content:");\r
+        String content = in.readLine();\r
+        provider.sendChangeNotification(content);\r
+    }\r
+\r
+    private static void unregisterConsumer1() {\r
+        consumer1.closeSession();\r
+    }\r
+\r
+    private static void unregisterConsumer2() {\r
+        consumer2.closeSession();\r
+    }\r
+\r
+    private static void unregisterProvider() {\r
+        provider.closeSession();\r
+    }\r
+\r
+    private static void displayHelp() {\r
+        System.out.println("Usage: ");\r
+        System.out.println("  0) Display Help");\r
+        System.out.println("  1) Register Provider");\r
+        System.out.println("  2) Register Consumer 1 (listening on alert)");\r
+        System.out\r
+                .println("  3) Register Consumer 2 (listening on alert,change)");\r
+        System.out.println("  4) Send Alert Notification");\r
+        System.out.println("  5) Send Change Notification");\r
+        System.out.println("  6) Unregister Consumer 1");\r
+        System.out.println("  7) Unregister Consumer 2");\r
+        System.out.println("  8) Unregister Provider");\r
+        System.out.println("  9) Exit");\r
+\r
+    }\r
+\r
+    private static void initializeProvider() {\r
+        provider = new DemoProviderImpl();\r
+    }\r
+\r
+    private static void initialize() {\r
+        System.out.println("Initializing broker");\r
+        broker = new BrokerImpl();\r
+        NotificationModule notifyModule = new NotificationModule();\r
+        broker.addModule(notifyModule);\r
+\r
+        consumer1 = new DemoConsumerImpl("Consumer 1");\r
+        consumer2 = new DemoConsumerImpl("Consumer 2");\r
+        consumer2.setChangeAware(true);\r
+    }\r
+\r
+    private static void registerProvider() {\r
+        broker.registerProvider(provider);\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/package-info.java b/opendaylight/sal/yang-prototype/sal/sal-core-demo/src/main/java/org/opendaylight/controller/sal/demo/package-info.java
new file mode 100644 (file)
index 0000000..09d4bfb
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.demo;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-spi/pom.xml b/opendaylight/sal/yang-prototype/sal/sal-core-spi/pom.xml
new file mode 100644 (file)
index 0000000..3378a36
--- /dev/null
@@ -0,0 +1,17 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>sal</artifactId>\r
+    <version>1.0-SNAPSHOT</version>\r
+  </parent>\r
+   <artifactId>sal-core-spi</artifactId>\r
+   \r
+   <dependencies>\r
+       <dependency>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>sal-core-api</artifactId>\r
+               <version>1.0-SNAPSHOT</version>\r
+       </dependency>\r
+       </dependencies>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-spi/src/main/java/org/opendaylight/controller/sal/core/spi/BrokerModule.java b/opendaylight/sal/yang-prototype/sal/sal-core-spi/src/main/java/org/opendaylight/controller/sal/core/spi/BrokerModule.java
new file mode 100644 (file)
index 0000000..99438c8
--- /dev/null
@@ -0,0 +1,27 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.spi;\r
+\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.sal.core.api.BrokerService;\r
+import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;\r
+import org.opendaylight.controller.sal.core.api.Consumer.ConsumerFunctionality;\r
+import org.opendaylight.controller.sal.core.api.Provider.ProviderFunctionality;\r
+\r
+public interface BrokerModule {\r
+\r
+    Set<Class<? extends BrokerService>> getProvidedServices();\r
+\r
+    Set<Class<? extends ConsumerFunctionality>> getSupportedConsumerFunctionality();\r
+\r
+    <T extends BrokerService> T getServiceForSession(Class<T> service,\r
+            ConsumerSession session);\r
+\r
+    Set<Class<? extends ProviderFunctionality>> getSupportedProviderFunctionality();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-core-spi/src/main/java/org/opendaylight/controller/sal/core/spi/package-info.java b/opendaylight/sal/yang-prototype/sal/sal-core-spi/src/main/java/org/opendaylight/controller/sal/core/spi/package-info.java
new file mode 100644 (file)
index 0000000..76493af
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.core.spi;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-data-api/pom.xml b/opendaylight/sal/yang-prototype/sal/sal-data-api/pom.xml
new file mode 100644 (file)
index 0000000..74230e5
--- /dev/null
@@ -0,0 +1,9 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>sal</artifactId>\r
+    <version>1.0-SNAPSHOT</version>\r
+  </parent>\r
+   <artifactId>sal-data-api</artifactId>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-schema-repository-api/.gitignore b/opendaylight/sal/yang-prototype/sal/sal-schema-repository-api/.gitignore
new file mode 100644 (file)
index 0000000..ea8c4bf
--- /dev/null
@@ -0,0 +1 @@
+/target
diff --git a/opendaylight/sal/yang-prototype/sal/sal-schema-repository-api/pom.xml b/opendaylight/sal/yang-prototype/sal/sal-schema-repository-api/pom.xml
new file mode 100644 (file)
index 0000000..db0ee84
--- /dev/null
@@ -0,0 +1,16 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>sal</artifactId>\r
+    <version>1.0-SNAPSHOT</version>\r
+  </parent>\r
+  <artifactId>sal-schema-repository-api</artifactId>\r
+  <dependencies>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>yang-model-api</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+  </dependencies>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-schema-repository-api/src/main/java/org/opendaylight/controller/sal/schema/api/SchemaContext.java b/opendaylight/sal/yang-prototype/sal/sal-schema-repository-api/src/main/java/org/opendaylight/controller/sal/schema/api/SchemaContext.java
new file mode 100644 (file)
index 0000000..009b21c
--- /dev/null
@@ -0,0 +1,30 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.schema.api;\r
+\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.Module;\r
+import org.opendaylight.controller.yang.model.api.NotificationDefinition;\r
+import org.opendaylight.controller.yang.model.api.RpcDefinition;\r
+\r
+\r
+/**\r
+ * \r
+ */\r
+public interface SchemaContext {\r
+\r
+    Set<DataSchemaNode> getDataDefinitions();\r
+\r
+    Set<Module> getModules();\r
+\r
+    Set<NotificationDefinition> getNotifications();\r
+\r
+    Set<RpcDefinition> getOperations();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-schema-repository-api/src/main/java/org/opendaylight/controller/sal/schema/api/package-info.java b/opendaylight/sal/yang-prototype/sal/sal-schema-repository-api/src/main/java/org/opendaylight/controller/sal/schema/api/package-info.java
new file mode 100644 (file)
index 0000000..39387f1
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.sal.schema.api;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/yang/pom.xml b/opendaylight/sal/yang-prototype/yang/pom.xml
new file mode 100644 (file)
index 0000000..d10366c
--- /dev/null
@@ -0,0 +1,84 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>yang</artifactId>\r
+    <version>1.0</version>\r
+    <packaging>pom</packaging>\r
+    <modules>\r
+       <module>yang-common</module>\r
+        <module>yang-data-api</module>\r
+        <module>yang-data-util</module>\r
+        <module>yang-model-api</module>\r
+        <module>yang-model-util</module>\r
+        <module>yang-binding</module>\r
+    </modules>\r
+    <dependencies>\r
+\r
+        <dependency>\r
+            <groupId>junit</groupId>\r
+            <artifactId>junit</artifactId>\r
+            <version>4.10</version>\r
+            <scope>test</scope>\r
+            <optional>true</optional>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.slf4j</groupId>\r
+            <artifactId>slf4j-api</artifactId>\r
+            <version>1.7.2</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.slf4j</groupId>\r
+            <artifactId>slf4j-simple</artifactId>\r
+            <version>1.7.2</version>\r
+        </dependency>\r
+    </dependencies>\r
+    <build>\r
+        <plugins>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-compiler-plugin</artifactId>\r
+                <version>2.0</version>\r
+                <inherited>true</inherited>\r
+                <configuration>\r
+                    <source>1.6</source>\r
+                    <target>1.6</target>\r
+                </configuration>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-javadoc-plugin</artifactId>\r
+                <version>2.8.1</version>\r
+                <configuration>\r
+                    <stylesheet>maven</stylesheet>\r
+                </configuration>\r
+                <executions>\r
+                    <execution>\r
+                        <goals>\r
+                            <goal>aggregate</goal>\r
+                        </goals>\r
+                        <phase>site</phase>\r
+                    </execution>\r
+                </executions>\r
+            </plugin>\r
+        </plugins>\r
+    </build>\r
+    <reporting>\r
+        <plugins>\r
+            <plugin>\r
+                <groupId>org.codehaus.mojo</groupId>\r
+                <artifactId>findbugs-maven-plugin</artifactId>\r
+                <version>2.4.0</version>\r
+                <configuration>\r
+                    <effort>Max</effort>\r
+                    <threshold>Low</threshold>\r
+                    <goal>site</goal>\r
+                </configuration>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.codehaus.mojo</groupId>\r
+                <artifactId>jdepend-maven-plugin</artifactId>\r
+                <version>2.0-beta-2</version>\r
+            </plugin>\r
+        </plugins>\r
+    </reporting>\r
+</project>\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-binding/pom.xml b/opendaylight/sal/yang-prototype/yang/yang-binding/pom.xml
new file mode 100644 (file)
index 0000000..3ddd4b3
--- /dev/null
@@ -0,0 +1,9 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>yang</artifactId>\r
+    <version>1.0</version>\r
+  </parent>\r
+  <artifactId>yang-binding</artifactId>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/DataRoot.java b/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/DataRoot.java
new file mode 100644 (file)
index 0000000..2f194b2
--- /dev/null
@@ -0,0 +1,16 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.binding;\r
+\r
+/**\r
+ * \r
+ * \r
+ */\r
+public interface DataRoot {\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/Notification.java b/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/Notification.java
new file mode 100644 (file)
index 0000000..9b8c1cf
--- /dev/null
@@ -0,0 +1,17 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.binding;\r
+\r
+/**\r
+ * Marker interface for YANG-defined notifications\r
+ * \r
+ * \r
+ */\r
+public interface Notification {\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/NotificationListener.java b/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/NotificationListener.java
new file mode 100644 (file)
index 0000000..a60d2f3
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.binding;\r
+\r
+/**\r
+ * Marker interface for generated notification listener interfaces\r
+ * \r
+ * \r
+ * \r
+ */\r
+public interface NotificationListener {\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/RpcService.java b/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/RpcService.java
new file mode 100644 (file)
index 0000000..20f7e78
--- /dev/null
@@ -0,0 +1,16 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.binding;\r
+\r
+/**\r
+ * Marker interface for tagging generated YANG Modules\r
+ * \r
+ */\r
+public interface RpcService {\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/package-info.java b/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/package-info.java
new file mode 100644 (file)
index 0000000..5ed5649
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.binding;
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/yang/yang-common/pom.xml b/opendaylight/sal/yang-prototype/yang/yang-common/pom.xml
new file mode 100644 (file)
index 0000000..b072ab3
--- /dev/null
@@ -0,0 +1,9 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>yang</artifactId>\r
+    <version>1.0</version>\r
+  </parent>\r
+  <artifactId>yang-common</artifactId>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/yang/yang-common/src/main/java/org/opendaylight/controller/yang/common/QName.java b/opendaylight/sal/yang-prototype/yang/yang-common/src/main/java/org/opendaylight/controller/yang/common/QName.java
new file mode 100644 (file)
index 0000000..b112720
--- /dev/null
@@ -0,0 +1,222 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.common;\r
+\r
+import java.net.URI;\r
+import java.net.URISyntaxException;\r
+\r
+import java.text.SimpleDateFormat;\r
+import java.util.Date;\r
+\r
+/**\r
+ * The QName from XML consists of local name of element and XML namespace, but\r
+ * for our use, we added module revision to it.\r
+ * \r
+ * In YANG context QName is full name of defined node, type, procedure or\r
+ * notification. QName consists of XML namespace, YANG model revision and local\r
+ * name of defined type. It is used to prevent name clashes between nodes with\r
+ * same local name, but from different schemas.\r
+ * \r
+ * <ul>\r
+ * <li><b>XMLNamespace</b> - the namespace assigned to the YANG module which\r
+ * defined element, type, procedure or notification.</li>\r
+ * <li><b>Revision</b> - the revision of the YANG module which describes the\r
+ * element</li>\r
+ * <li><b>LocalName</b> - the YANG schema identifier which were defined for this\r
+ * node in the YANG module</li>\r
+ * </ul>\r
+ * \r
+ * \r
+ */\r
+public class QName {\r
+\r
+    private SimpleDateFormat revisionFormat = new SimpleDateFormat("yyyy-MM-dd");\r
+\r
+    final URI namespace;\r
+    final String localName;\r
+    final String prefix;\r
+    final Date revision;\r
+\r
+    /**\r
+     * QName Constructor.\r
+     * \r
+     * @param namespace\r
+     *            the namespace assigned to the YANG module\r
+     * @param revision\r
+     *            the revision of the YANG module\r
+     * @param prefix\r
+     *            locally defined prefix assigned to local name\r
+     * @param localName\r
+     *            YANG schema identifier\r
+     */\r
+    public QName(URI namespace, Date revision, String prefix, String localName) {\r
+        this.namespace = namespace;\r
+        this.localName = localName;\r
+        this.revision = revision;\r
+        this.prefix = prefix;\r
+    }\r
+\r
+    /**\r
+     * QName Constructor.\r
+     * \r
+     * @param namespace\r
+     *            the namespace assigned to the YANG module\r
+     * @param localName\r
+     *            YANG schema identifier\r
+     */\r
+    public QName(URI namespace, String localName) {\r
+        this(namespace, null, "", localName);\r
+    }\r
+\r
+    /**\r
+     * QName Constructor.\r
+     * \r
+     * @param namespace\r
+     *            the namespace assigned to the YANG module\r
+     * @param revision\r
+     *            the revision of the YANG module\r
+     * @param localName\r
+     *            YANG schema identifier\r
+     */\r
+    public QName(URI namespace, Date revision, String localName) {\r
+        this(namespace, revision, null, localName);\r
+    }\r
+\r
+    public QName(QName base, String localName) {\r
+        this(base.getNamespace(), base.getRevision(), base.getPrefix(),\r
+                localName);\r
+    }\r
+\r
+    /**\r
+     * Returns XMLNamespace assigned to the YANG module.\r
+     * \r
+     * @return XMLNamespace assigned to the YANG module.\r
+     */\r
+    public URI getNamespace() {\r
+        return namespace;\r
+    }\r
+\r
+    /**\r
+     * Returns YANG schema identifier which were defined for this node in the\r
+     * YANG module\r
+     * \r
+     * @return YANG schema identifier which were defined for this node in the\r
+     *         YANG module\r
+     */\r
+    public String getLocalName() {\r
+        return localName;\r
+    }\r
+\r
+    /**\r
+     * Returns revision of the YANG module if the module has defined revision,\r
+     * otherwise returns <code>null</code>\r
+     * \r
+     * @return revision of the YANG module if the module has defined revision,\r
+     *         otherwise returns <code>null</code>\r
+     */\r
+    public Date getRevision() {\r
+        return revision;\r
+    }\r
+\r
+    /**\r
+     * Returns locally defined prefix assigned to local name\r
+     * \r
+     * @return locally defined prefix assigned to local name\r
+     */\r
+    public String getPrefix() {\r
+        return prefix;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result\r
+                + ((localName == null) ? 0 : localName.hashCode());\r
+        result = prime * result\r
+                + ((namespace == null) ? 0 : namespace.hashCode());\r
+        result = prime * result\r
+                + ((revision == null) ? 0 : revision.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj)\r
+            return true;\r
+        if (obj == null)\r
+            return false;\r
+        if (getClass() != obj.getClass())\r
+            return false;\r
+        QName other = (QName) obj;\r
+        if (localName == null) {\r
+            if (other.localName != null)\r
+                return false;\r
+        } else if (!localName.equals(other.localName))\r
+            return false;\r
+        if (namespace == null) {\r
+            if (other.namespace != null)\r
+                return false;\r
+        } else if (!namespace.equals(other.namespace))\r
+            return false;\r
+        if (revision == null) {\r
+            if (other.revision != null)\r
+                return false;\r
+        } else if (!revision.equals(other.revision))\r
+            return false;\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder sb = new StringBuilder();\r
+        if (namespace != null) {\r
+            sb.append("(" + namespace);\r
+\r
+            if (revision != null) {\r
+                sb.append("?revision=" + revisionFormat.format(revision));\r
+            }\r
+            sb.append(")");\r
+        }\r
+        sb.append(localName);\r
+        return sb.toString();\r
+    }\r
+\r
+    /**\r
+     * Returns a namespace in form defined by section 5.6.4. of {@link https\r
+     * ://tools.ietf.org/html/rfc6020}, if namespace is not correctly defined,\r
+     * the method will return <code>null</code> <br>\r
+     * example "http://example.acme.com/system?revision=2008-04-01"\r
+     * \r
+     * @return namespace in form defined by section 5.6.4. of {@link https\r
+     *         ://tools.ietf.org/html/rfc6020}, if namespace is not correctly\r
+     *         defined, the method will return <code>null</code>\r
+     * \r
+     */\r
+    URI getRevisionNamespace() {\r
+\r
+        if (namespace == null)\r
+            return null;\r
+\r
+        String query = "";\r
+        if (revision != null) {\r
+            query = "revision=" + revisionFormat.format(revision);\r
+        }\r
+\r
+        URI compositeURI = null;\r
+        try {\r
+            compositeURI = new URI(namespace.getScheme(),\r
+                    namespace.getUserInfo(), namespace.getHost(),\r
+                    namespace.getPort(), namespace.getPath(), query,\r
+                    namespace.getFragment());\r
+        } catch (URISyntaxException e) {\r
+            e.printStackTrace();\r
+        }\r
+        return compositeURI;\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-common/src/main/java/org/opendaylight/controller/yang/common/RpcError.java b/opendaylight/sal/yang-prototype/yang/yang-common/src/main/java/org/opendaylight/controller/yang/common/RpcError.java
new file mode 100644 (file)
index 0000000..cb81929
--- /dev/null
@@ -0,0 +1,32 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.common;\r
+\r
+//import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;\r
+\r
+public interface RpcError {\r
+    ErrorSeverity getSeverity();\r
+\r
+    String getTag();\r
+\r
+    String getApplicationTag();\r
+\r
+    String getMessage();\r
+\r
+    String getInfo();\r
+\r
+    // RevisionAwareXPath getPath();\r
+\r
+    public enum ErrorSeverity {\r
+        ERROR, WARNING,\r
+    }\r
+\r
+    public enum ErrorType {\r
+        TRANSPORT, RPC, PROTOCOL, APPLICATION\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-common/src/main/java/org/opendaylight/controller/yang/common/RpcResult.java b/opendaylight/sal/yang-prototype/yang/yang-common/src/main/java/org/opendaylight/controller/yang/common/RpcResult.java
new file mode 100644 (file)
index 0000000..d754cb7
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.common;\r
+\r
+import java.util.Collection;\r
+\r
+public interface RpcResult<T> {\r
+    boolean isSuccessful();\r
+\r
+    T getResult();\r
+\r
+    Collection<RpcError> getErrors();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-api/pom.xml b/opendaylight/sal/yang-prototype/yang/yang-data-api/pom.xml
new file mode 100644 (file)
index 0000000..358cabd
--- /dev/null
@@ -0,0 +1,18 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>yang</artifactId>\r
+    <version>1.0</version>\r
+  </parent>\r
+  <artifactId>yang-data-api</artifactId>\r
+  \r
+  \r
+  <dependencies>\r
+       <dependency>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>yang-common</artifactId>\r
+               <version>1.0</version>\r
+       </dependency>\r
+  </dependencies>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/CompositeNode.java b/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/CompositeNode.java
new file mode 100644 (file)
index 0000000..dfc790e
--- /dev/null
@@ -0,0 +1,48 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.api;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+/**\r
+ * Composite node represents a branch in the data tree, which could contain\r
+ * nested composite nodes or leaf nodes. In the terms of the XML the simple node\r
+ * is element which does not text data directly (CDATA or PCDATA), only other\r
+ * nodes. The composite node is the manifestation of the following data schema\r
+ * constructs in the YANG:\r
+ * \r
+ * <ul>\r
+ * <li><b>container</b> - the composite node represents the YANG container and\r
+ * could contain all children schema nodes of that container</li>\r
+ * <li><b>item</b> in the <b>list</b> - the composite node represents one item\r
+ * in the YANG list and could contain all children schema nodes of that list\r
+ * item.</li>\r
+ * <li><b>anyxml</b></li>\r
+ * </ul>\r
+ * \r
+ * \r
+ */\r
+public interface CompositeNode extends Node<List<Node<?>>> {\r
+\r
+    List<Node<?>> getChildren();\r
+\r
+    List<CompositeNode> getCompositesByName(QName children);\r
+\r
+    List<CompositeNode> getCompositesByName(String children);\r
+\r
+    List<SimpleNode<?>> getSimpleNodesByName(QName children);\r
+\r
+    List<SimpleNode<?>> getSimpleNodesByName(String children);\r
+\r
+    CompositeNode getFirstCompositeByName(QName container);\r
+\r
+    SimpleNode<?> getFirstSimpleByName(QName leaf);\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/CompositeNodeModification.java b/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/CompositeNodeModification.java
new file mode 100644 (file)
index 0000000..1772ddf
--- /dev/null
@@ -0,0 +1,110 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.api;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+/**\r
+ * For the use cases of changing the state data, the node modifications are\r
+ * modeled as part of additional metadata in data tree. The modification types\r
+ * are based on Netconf edit-config RPCs. In order to modify the configuration\r
+ * or state data tree the user must create a tree representing the modification\r
+ * of the data and apply that modification to the target tree.\r
+ * \r
+ * \r
+ * @see <a href="http://tools.ietf.org/html/rfc6241">Network Configuration\r
+ *      Protocol (NETCONF)</a>\r
+ * \r
+ */\r
+public interface CompositeNodeModification extends CompositeNode {\r
+\r
+    ModifyAction getModificationAction();\r
+\r
+    // Container Modification\r
+\r
+    /**\r
+     * The data identified by the node containing this modification is merged\r
+     * with the data at the corresponding level in the data tree\r
+     * \r
+     * @param node\r
+     *            in data tree\r
+     */\r
+    void mergeChild(CompositeNode node);\r
+\r
+    /**\r
+     * The data identified by the node containing this modification replaces any\r
+     * related data in the target data tree If no such data exists in the target\r
+     * data tree, the child node is created.\r
+     * \r
+     * @param node\r
+     *            composite node\r
+     */\r
+    void replaceChild(CompositeNode node);\r
+\r
+    /**\r
+     * Adds new composite node into data tree\r
+     * \r
+     * @param node\r
+     *            composite node\r
+     */\r
+    void addChild(CompositeNode node);\r
+\r
+    /**\r
+     * The data identified by the node containing this modification is deleted\r
+     * from the target data tree if and only if the data currently exists in the\r
+     * target data tree. If the data does not exist, an error is returned with\r
+     * an error value of "data-missing".\r
+     * \r
+     * @param node\r
+     */\r
+    void deleteChild(CompositeNode node);\r
+\r
+    /**\r
+     * The data identified by the node containing this attribute is deleted from\r
+     * the target data tree if the data currently exists in the target data\r
+     * tree. If the data does not exist, the modification is silently ignored.\r
+     * \r
+     * @param node\r
+     *            composite node\r
+     */\r
+    void removeChild(CompositeNode node);\r
+\r
+    // Leaf Modifications\r
+\r
+    /**\r
+     * The data identified by the node containing this modification replaces any\r
+     * related data in the target data tree If no such data exists in the target\r
+     * data tree, it is created.\r
+     * \r
+     * @param leaf\r
+     */\r
+    void replaceSimpleNode(SimpleNode<?> leaf);\r
+\r
+    /**\r
+     * The data identified by the node containing this modification is deleted\r
+     * from the target data tree if and only if the data currently exists in the\r
+     * target data tree. If the data does not exist, an error is returned with\r
+     * an error value of "data-missing".\r
+     * \r
+     * @param leaf\r
+     */\r
+    void deleteSimpleNode(SimpleNode<?> leaf);\r
+\r
+    /**\r
+     * The data identified by the node containing this attribute is deleted from\r
+     * the target data tree if the data currently exists in the target data\r
+     * tree. If the data does not exist, the modification is silently ignored.\r
+     * \r
+     * @param leaf\r
+     */\r
+    void removeSimpleNode(SimpleNode<?> leaf);\r
+\r
+    void removeLeaf(SimpleNode<?> leaf);\r
+\r
+    void removeLeaf(QName leaf);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/ModifyAction.java b/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/ModifyAction.java
new file mode 100644 (file)
index 0000000..fa17043
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.api;\r
+\r
+public enum ModifyAction {\r
+    MERGE, REPLACE, CREATE, DELETE, REMOVE\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/Node.java b/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/Node.java
new file mode 100644 (file)
index 0000000..341a286
--- /dev/null
@@ -0,0 +1,42 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.api;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+/**\r
+ * Base representation of node in the data tree, defines basic parameters of\r
+ * node such as a QName.\r
+ * \r
+ * \r
+ * @param <T>\r
+ */\r
+public interface Node<T> {\r
+\r
+    /**\r
+     * Returns the name of the Node\r
+     * \r
+     * @return\r
+     */\r
+    QName getNodeType();\r
+\r
+    /**\r
+     * Returns parent node\r
+     * \r
+     * @return parent node\r
+     */\r
+    CompositeNode getParent();\r
+\r
+    /**\r
+     * Returns the value that holds current node, if no value is defined method\r
+     * can return <code>null</code>\r
+     * \r
+     * @return Returns the value that holds current node.\r
+     */\r
+    T getValue();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/SimpleNode.java b/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/SimpleNode.java
new file mode 100644 (file)
index 0000000..717c722
--- /dev/null
@@ -0,0 +1,26 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.api;\r
+\r
+/**\r
+ * Simple node represents a leaf in the data tree, which does not contain any\r
+ * nested nodes, but the value of node. In the terms of the XML the simple node\r
+ * is element which contains only text data (CDATA or PCDATA). The simple node\r
+ * is the manifestation of the following data schema constructs in YANG:\r
+ * <ul>\r
+ * <li><b>leaf</b> - simple node could represent YANG leafs of all types except\r
+ * the empty type, which in XML form is similar to the empty container.</li>\r
+ * <li><b>item</b> in <b>leaf-list</b></li>\r
+ * </ul>\r
+ * \r
+ * \r
+ * @param <T>\r
+ */\r
+public interface SimpleNode<T> extends Node<T> {\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-util/pom.xml b/opendaylight/sal/yang-prototype/yang/yang-data-util/pom.xml
new file mode 100644 (file)
index 0000000..2595d5d
--- /dev/null
@@ -0,0 +1,16 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>yang</artifactId>\r
+    <version>1.0</version>\r
+  </parent>\r
+  <artifactId>yang-data-util</artifactId>\r
+  <dependencies>\r
+       <dependency>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>yang-data-api</artifactId>\r
+               <version>1.0</version>\r
+       </dependency>\r
+  </dependencies>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-util/src/main/java/org/opendaylight/controller/data/util/AbstractContainerNode.java b/opendaylight/sal/yang-prototype/yang/yang-data-util/src/main/java/org/opendaylight/controller/data/util/AbstractContainerNode.java
new file mode 100644 (file)
index 0000000..7a5cfda
--- /dev/null
@@ -0,0 +1,108 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.data.util;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+\r
+public abstract class AbstractContainerNode extends AbstractNode<List<Node<?>>>\r
+        implements CompositeNode {\r
+\r
+    public SimpleNode<?> getFirstSimpleByName(QName leaf) {\r
+        List<SimpleNode<?>> list = getSimpleNodesByName(leaf);\r
+        if (list.size() == 0)\r
+            return null;\r
+        return list.get(0);\r
+    }\r
+\r
+    protected AbstractContainerNode(QName name, CompositeNode parent) {\r
+        super(name, parent);\r
+    }\r
+\r
+    public AbstractContainerNode(QName name) {\r
+        super(name, null);\r
+    }\r
+\r
+    public List<Node<?>> getChildren() {\r
+        return getValue();\r
+    }\r
+\r
+    public List<Node<?>> getValue() {\r
+        Map<QName, List<Node<?>>> map = getNodeMap();\r
+        if (map == null)\r
+            throw new IllegalStateException("nodeMap should not be null");\r
+        List<Node<?>> ret = new ArrayList<Node<?>>();\r
+        Collection<List<Node<?>>> values = map.values();\r
+        for (List<Node<?>> list : values) {\r
+            ret.addAll(list);\r
+        }\r
+        return ret;\r
+    }\r
+\r
+    protected abstract Map<QName, List<Node<?>>> getNodeMap();\r
+\r
+    public List<CompositeNode> getCompositesByName(QName children) {\r
+        Map<QName, List<Node<?>>> map = getNodeMap();\r
+        if (map == null)\r
+            throw new IllegalStateException("nodeMap should not be null");\r
+        List<Node<?>> toFilter = map.get(children);\r
+        List<CompositeNode> list = new ArrayList<CompositeNode>();\r
+        for (Node<?> node : toFilter) {\r
+            if (node instanceof CompositeNode)\r
+                list.add((CompositeNode) node);\r
+        }\r
+        return list;\r
+    }\r
+\r
+    public List<SimpleNode<?>> getSimpleNodesByName(QName children) {\r
+        Map<QName, List<Node<?>>> map = getNodeMap();\r
+        if (map == null)\r
+            throw new IllegalStateException("nodeMap should not be null");\r
+        List<Node<?>> toFilter = map.get(children);\r
+        List<SimpleNode<?>> list = new ArrayList<SimpleNode<?>>();\r
+\r
+        for (Node<?> node : toFilter) {\r
+            if (node instanceof SimpleNode<?>)\r
+                list.add((SimpleNode<?>) node);\r
+        }\r
+        return list;\r
+    }\r
+\r
+    public CompositeNode getFirstCompositeByName(QName container) {\r
+        List<CompositeNode> list = getCompositesByName(container);\r
+        if (list.size() == 0)\r
+            return null;\r
+        return list.get(0);\r
+    }\r
+\r
+    public SimpleNode<?> getFirstLeafByName(QName leaf) {\r
+        List<SimpleNode<?>> list = getSimpleNodesByName(leaf);\r
+        if (list.size() == 0)\r
+            return null;\r
+        return list.get(0);\r
+    }\r
+\r
+    public List<CompositeNode> getCompositesByName(String children) {\r
+        return getCompositesByName(localQName(children));\r
+    }\r
+\r
+    public List<SimpleNode<?>> getSimpleNodesByName(String children) {\r
+        return getSimpleNodesByName(localQName(children));\r
+    }\r
+\r
+    private QName localQName(String str) {\r
+        return new QName(getNodeType(), str);\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-util/src/main/java/org/opendaylight/controller/data/util/AbstractNode.java b/opendaylight/sal/yang-prototype/yang/yang-data-util/src/main/java/org/opendaylight/controller/data/util/AbstractNode.java
new file mode 100644 (file)
index 0000000..1f4b6aa
--- /dev/null
@@ -0,0 +1,31 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.data.util;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+\r
+public abstract class AbstractNode<T> implements Node<T> {\r
+\r
+    private final QName nodeName;\r
+    private final CompositeNode parent;\r
+\r
+    protected AbstractNode(QName name, CompositeNode parent) {\r
+        nodeName = name;\r
+        this.parent = parent;\r
+    }\r
+\r
+    public QName getNodeType() {\r
+        return this.nodeName;\r
+    }\r
+\r
+    public CompositeNode getParent() {\r
+        return parent;\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-util/src/main/java/org/opendaylight/controller/data/util/Nodes.java b/opendaylight/sal/yang-prototype/yang/yang-data-util/src/main/java/org/opendaylight/controller/data/util/Nodes.java
new file mode 100644 (file)
index 0000000..16d5461
--- /dev/null
@@ -0,0 +1,94 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.data.util;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+\r
+public class Nodes {\r
+\r
+    private Nodes() {\r
+    }\r
+\r
+    public static <T> SimpleNode<T> leafNode(QName name, T value) {\r
+        return new SimpleNodeTO<T>(name, value, null);\r
+    }\r
+\r
+    public static CompositeNode containerNode(QName name, List<Node<?>> children) {\r
+        return containerNode(name, children, null);\r
+    }\r
+\r
+    public static CompositeNode containerNode(QName name,\r
+            List<Node<?>> children, CompositeNode parent) {\r
+        return new ContainerNodeTO(name, parent, nodeMapFromList(children));\r
+    }\r
+\r
+    public static Map<QName, List<Node<?>>> nodeMapFromList(\r
+            List<Node<?>> children) {\r
+        Map<QName, List<Node<?>>> map = new HashMap<QName, List<Node<?>>>();\r
+        for (Node<?> node : children) {\r
+\r
+            QName name = node.getNodeType();\r
+            List<Node<?>> targetList = map.get(name);\r
+            if (targetList == null) {\r
+                targetList = new ArrayList<Node<?>>();\r
+                map.put(name, targetList);\r
+            }\r
+            targetList.add(node);\r
+        }\r
+        return map;\r
+    }\r
+\r
+    private static class ContainerNodeTO extends AbstractContainerNode {\r
+\r
+        private final Map<QName, List<Node<?>>> nodeMap;\r
+\r
+        public ContainerNodeTO(QName name, Map<QName, List<Node<?>>> nodeMap) {\r
+            super(name);\r
+            this.nodeMap = nodeMap;\r
+        }\r
+\r
+        public ContainerNodeTO(QName name, CompositeNode parent,\r
+                Map<QName, List<Node<?>>> nodeMap) {\r
+            super(name, parent);\r
+            this.nodeMap = nodeMap;\r
+        }\r
+\r
+        @Override\r
+        protected Map<QName, List<Node<?>>> getNodeMap() {\r
+\r
+            return nodeMap;\r
+        }\r
+    }\r
+\r
+    private static class SimpleNodeTO<T> extends AbstractNode<T> implements\r
+            SimpleNode<T> {\r
+\r
+        private final T value;\r
+\r
+        protected SimpleNodeTO(QName name, T val, CompositeNode parent) {\r
+            super(name, parent);\r
+            value = val;\r
+\r
+        }\r
+\r
+        @Override\r
+        public T getValue() {\r
+            return value;\r
+        }\r
+\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/pom.xml b/opendaylight/sal/yang-prototype/yang/yang-model-api/pom.xml
new file mode 100644 (file)
index 0000000..bf1a4ce
--- /dev/null
@@ -0,0 +1,17 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>yang</artifactId>\r
+    <version>1.0</version>\r
+  </parent>\r
+  <artifactId>yang-model-api</artifactId>\r
+  \r
+  <dependencies>\r
+       <dependency>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>yang-common</artifactId>\r
+               <version>1.0</version>\r
+       </dependency>\r
+  </dependencies>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/BinaryTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/BinaryTypeDefinition.java
new file mode 100644 (file)
index 0000000..babceb2
--- /dev/null
@@ -0,0 +1,33 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+/**\r
+ * The binary built-in type represents any binary data, i.e., a sequence of\r
+ * octets. <br>\r
+ * <br>\r
+ * Binary values are encoded with the base64 encoding scheme (see <a\r
+ * href="https://tools.ietf.org/html/rfc4648#section-4">[RFC4648], Section\r
+ * 4</a>). <br>\r
+ * The canonical form of a binary value follows the rules in <a\r
+ * href="https://tools.ietf.org/html/rfc4648">[RFC4648]</a>.\r
+ * \r
+ * \r
+ */\r
+public interface BinaryTypeDefinition extends\r
+        TypeDefinition<BinaryTypeDefinition> {\r
+\r
+    /**\r
+     * Returns the number of octets it that binary value contains.\r
+     * \r
+     * @return the number of octets it that binary value contains.\r
+     */\r
+    public LengthConstraint getLengthConstraint();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/BitsTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/BitsTypeDefinition.java
new file mode 100644 (file)
index 0000000..84fbf59
--- /dev/null
@@ -0,0 +1,30 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.model.api.SchemaNode;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface BitsTypeDefinition extends TypeDefinition<BitsTypeDefinition> {\r
+\r
+    public List<Bit> getBits();\r
+\r
+    interface Bit extends SchemaNode {\r
+        /**\r
+         * The position value MUST be in the range 0 to 4294967295, and it MUST\r
+         * be unique within the bits type.\r
+         * \r
+         * @return The position value of bit in range from 0 to 4294967295.\r
+         */\r
+        public Long getPosition();\r
+\r
+        public String getName();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/BooleanTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/BooleanTypeDefinition.java
new file mode 100644 (file)
index 0000000..84c3e80
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface BooleanTypeDefinition extends\r
+        TypeDefinition<BooleanTypeDefinition> {\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/DecimalTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/DecimalTypeDefinition.java
new file mode 100644 (file)
index 0000000..78ca2ac
--- /dev/null
@@ -0,0 +1,31 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface DecimalTypeDefinition extends\r
+        TypeDefinition<DecimalTypeDefinition> {\r
+\r
+    List<RangeConstraint> getRangeStatements();\r
+\r
+    /**\r
+     * Returns integer between 1 and 18 inclusively. <br>\r
+     * <br>\r
+     * \r
+     * The "fraction-digits" statement controls the size of the minimum\r
+     * difference between values of a decimal64 type, by restricting the value\r
+     * space to numbers that are expressible as "i x 10^-n" where n is the\r
+     * fraction-digits argument.\r
+     * \r
+     * @return\r
+     */\r
+    Integer getFractionDigits();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/EmptyTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/EmptyTypeDefinition.java
new file mode 100644 (file)
index 0000000..77912ae
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface EmptyTypeDefinition extends\r
+        TypeDefinition<EmptyTypeDefinition> {\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/EnumTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/EnumTypeDefinition.java
new file mode 100644 (file)
index 0000000..882bb4e
--- /dev/null
@@ -0,0 +1,38 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.model.api.SchemaNode;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface EnumTypeDefinition extends TypeDefinition<EnumTypeDefinition> {\r
+\r
+    List<EnumPair> getValues();\r
+\r
+    interface EnumPair extends SchemaNode {\r
+\r
+        /**\r
+         * The name to specify each assigned name of an enumeration type.\r
+         * \r
+         * @return name of each assigned name of an enumeration type.\r
+         */\r
+        public String getName();\r
+\r
+        /**\r
+         * The "value" statement, which is optional, is used to associate an\r
+         * integer value with the assigned name for the enum. This integer value\r
+         * MUST be in the range -2147483648 to 2147483647, and it MUST be unique\r
+         * within the enumeration type.\r
+         * \r
+         * @return integer value assigned to enumeration\r
+         */\r
+        public Integer getValue();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/IdentityTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/IdentityTypeDefinition.java
new file mode 100644 (file)
index 0000000..3b8abf7
--- /dev/null
@@ -0,0 +1,17 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface IdentityTypeDefinition extends\r
+        TypeDefinition<IdentityTypeDefinition> {\r
+\r
+    public QName getIdentityName();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/IdentityrefTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/IdentityrefTypeDefinition.java
new file mode 100644 (file)
index 0000000..0508020
--- /dev/null
@@ -0,0 +1,16 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface IdentityrefTypeDefinition extends\r
+        TypeDefinition<IdentityTypeDefinition> {\r
+\r
+    public IdentityTypeDefinition getIdentity();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/InstanceIdentifierTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/InstanceIdentifierTypeDefinition.java
new file mode 100644 (file)
index 0000000..44af5e0
--- /dev/null
@@ -0,0 +1,19 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface InstanceIdentifierTypeDefinition extends\r
+        TypeDefinition<InstanceIdentifierTypeDefinition> {\r
+\r
+    public RevisionAwareXPath getPathStatement();\r
+\r
+    public boolean requireInstance();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/IntegerTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/IntegerTypeDefinition.java
new file mode 100644 (file)
index 0000000..92f3098
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface IntegerTypeDefinition extends\r
+        TypeDefinition<IntegerTypeDefinition> {\r
+\r
+    List<RangeConstraint> getRangeStatements();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/LeafrefTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/LeafrefTypeDefinition.java
new file mode 100644 (file)
index 0000000..ac61372
--- /dev/null
@@ -0,0 +1,17 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface LeafrefTypeDefinition extends\r
+        TypeDefinition<LeafrefTypeDefinition> {\r
+\r
+    public RevisionAwareXPath getPathStatement();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/LengthConstraint.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/LengthConstraint.java
new file mode 100644 (file)
index 0000000..8c9cb79
--- /dev/null
@@ -0,0 +1,17 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import org.opendaylight.controller.yang.model.api.ConstraintMetaDefinition;\r
+\r
+public interface LengthConstraint extends ConstraintMetaDefinition {\r
+\r
+    Long getMin();\r
+\r
+    Long getMax();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/PatternConstraint.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/PatternConstraint.java
new file mode 100644 (file)
index 0000000..c8d012b
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import org.opendaylight.controller.yang.model.api.ConstraintMetaDefinition;\r
+\r
+public interface PatternConstraint extends ConstraintMetaDefinition {\r
+\r
+    public String getRegularExpression();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/RangeConstraint.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/RangeConstraint.java
new file mode 100644 (file)
index 0000000..76bfb75
--- /dev/null
@@ -0,0 +1,17 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import org.opendaylight.controller.yang.model.api.ConstraintMetaDefinition;\r
+\r
+public interface RangeConstraint extends ConstraintMetaDefinition {\r
+\r
+    Long getMin();\r
+\r
+    Long getMax();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/StringTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/StringTypeDefinition.java
new file mode 100644 (file)
index 0000000..2ee6d1d
--- /dev/null
@@ -0,0 +1,20 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface StringTypeDefinition extends\r
+        TypeDefinition<StringTypeDefinition> {\r
+\r
+    List<LengthConstraint> getLengthStatements();\r
+\r
+    List<PatternConstraint> getPatterns();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/UnionTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/UnionTypeDefinition.java
new file mode 100644 (file)
index 0000000..b46e3a1
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface UnionTypeDefinition extends\r
+        TypeDefinition<UnionTypeDefinition> {\r
+\r
+    public List<TypeDefinition<?>> getTypes();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/UnknownTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/UnknownTypeDefinition.java
new file mode 100644 (file)
index 0000000..a4da8f7
--- /dev/null
@@ -0,0 +1,24 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface UnknownTypeDefinition extends\r
+        TypeDefinition<UnknownTypeDefinition> {\r
+\r
+    public List<RangeConstraint> getRangeStatements();\r
+\r
+    public List<LengthConstraint> getLengthStatements();\r
+\r
+    public List<PatternConstraint> getPatterns();\r
+\r
+    public LengthConstraint getLengthConstraint();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/UnsignedIntegerTypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/model/api/type/UnsignedIntegerTypeDefinition.java
new file mode 100644 (file)
index 0000000..821bb5e
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.api.type;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public interface UnsignedIntegerTypeDefinition extends\r
+        TypeDefinition<UnsignedIntegerTypeDefinition> {\r
+\r
+    List<RangeConstraint> getRangeStatements();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/AnyXmlSchemaNode.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/AnyXmlSchemaNode.java
new file mode 100644 (file)
index 0000000..02aaf9c
--- /dev/null
@@ -0,0 +1,24 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+/**\r
+ * The "anyxml" interface defines an interior node in the schema tree. It takes\r
+ * one argument, which is an identifier represented by QName inherited from\r
+ * {@link SchemaNode}, followed by a block of substatements that holds detailed\r
+ * anyxml information. The substatements are defined in {@link DataSchemaNode} <br>\r
+ * <br>\r
+ * This interface was modeled according to definition in <a\r
+ * href="https://tools.ietf.org/html/rfc6020#section-7.10">[RFC-6020] The anyxml\r
+ * Statement</a>\r
+ * \r
+ * \r
+ */\r
+public interface AnyXmlSchemaNode extends DataSchemaNode {\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/AugmentationSchema.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/AugmentationSchema.java
new file mode 100644 (file)
index 0000000..37bc9fe
--- /dev/null
@@ -0,0 +1,24 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+import java.util.Set;\r
+\r
+public interface AugmentationSchema extends DataNodeContainer {\r
+\r
+    String getDescription();\r
+\r
+    String getReference();\r
+\r
+    Status getStatus();\r
+\r
+    SchemaPath getTargetPath();\r
+\r
+    Set<UsesNode> getUses();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/AugmentationTarget.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/AugmentationTarget.java
new file mode 100644 (file)
index 0000000..77ab5a3
--- /dev/null
@@ -0,0 +1,19 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+import java.util.Set;\r
+\r
+public interface AugmentationTarget {\r
+    /**\r
+     * Returns a set of augmentations targeting this element.\r
+     * \r
+     * @return\r
+     */\r
+    Set<AugmentationSchema> getAvailableAugmentations();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ChoiceCaseNode.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ChoiceCaseNode.java
new file mode 100644 (file)
index 0000000..0fcbda9
--- /dev/null
@@ -0,0 +1,13 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+public interface ChoiceCaseNode extends DataSchemaNode, DataNodeContainer,\r
+        AugmentationTarget {\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ChoiceNode.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ChoiceNode.java
new file mode 100644 (file)
index 0000000..f289048
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+import java.util.Set;\r
+\r
+public interface ChoiceNode extends DataSchemaNode {\r
+\r
+    Set<ChoiceCaseNode> getCases();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ConstraintDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ConstraintDefinition.java
new file mode 100644 (file)
index 0000000..2143324
--- /dev/null
@@ -0,0 +1,24 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+import java.util.Set;\r
+\r
+public interface ConstraintDefinition {\r
+    DataSchemaNode getParent();\r
+\r
+    RevisionAwareXPath getWhenCondition();\r
+\r
+    Set<MustDefinition> getMustConstraints();\r
+\r
+    boolean isMandatory();\r
+\r
+    Integer getMinElements();\r
+\r
+    Integer getMaxElements();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ConstraintMetaDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ConstraintMetaDefinition.java
new file mode 100644 (file)
index 0000000..50f41d9
--- /dev/null
@@ -0,0 +1,19 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+public interface ConstraintMetaDefinition {\r
+\r
+    String getDescription();\r
+\r
+    String getErrorAppTag();\r
+\r
+    String getErrorMessage();\r
+\r
+    String getReference();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ContainerSchemaNode.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ContainerSchemaNode.java
new file mode 100644 (file)
index 0000000..27711c9
--- /dev/null
@@ -0,0 +1,21 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+import java.util.Set;\r
+\r
+public interface ContainerSchemaNode extends DataNodeContainer,\r
+        AugmentationTarget, DataSchemaNode {\r
+\r
+    Set<UsesNode> getUses();\r
+\r
+    boolean isPresenceContainer();\r
+\r
+    MustDefinition getMustDefinition();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/DataNodeContainer.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/DataNodeContainer.java
new file mode 100644 (file)
index 0000000..8888208
--- /dev/null
@@ -0,0 +1,28 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+public interface DataNodeContainer {\r
+\r
+    Set<TypeDefinition<?>> getTypeDefinitions();\r
+\r
+    Set<DataSchemaNode> getChildNodes();\r
+\r
+    Set<GroupingDefinition> getGroupings();\r
+\r
+    DataSchemaNode getDataChildByName(QName name);\r
+\r
+    DataSchemaNode getDataChildByName(String name);\r
+\r
+    Set<UsesNode> getUses();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/DataSchemaNode.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/DataSchemaNode.java
new file mode 100644 (file)
index 0000000..25208aa
--- /dev/null
@@ -0,0 +1,36 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+public interface DataSchemaNode extends SchemaNode {\r
+\r
+    /**\r
+     * Returns <code>true</code> if the data node was added by augmentation,\r
+     * otherwise returns <code>false</code>\r
+     * \r
+     * @return <code>true</code> if the data node was added by augmentation,\r
+     *         otherwise returns <code>false</code>\r
+     */\r
+    boolean isAugmenting();\r
+\r
+    /**\r
+     * Returns <code>true</code> if the data represents configuration data,\r
+     * otherwise returns <code>false</code>\r
+     * \r
+     * @return <code>true</code> if the data represents configuration data,\r
+     *         otherwise returns <code>false</code>\r
+     */\r
+    boolean isConfiguration();\r
+\r
+    /**\r
+     * Returns the constraints associated with Data Schema Node\r
+     * \r
+     * @return the constraints associated with Data Schema Node\r
+     */\r
+    ConstraintDefinition getConstraints();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Deviation.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Deviation.java
new file mode 100644 (file)
index 0000000..83510ba
--- /dev/null
@@ -0,0 +1,24 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+public interface Deviation {\r
+\r
+    MustDefinition getMustDefinition();\r
+\r
+    enum Deviate {\r
+        NOT_SUPPORTED, ADD, REPLACE, DELETE\r
+    }\r
+\r
+    SchemaPath getTargetPath();\r
+\r
+    Deviate getDeviate();\r
+\r
+    String getReference();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ExtensionDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ExtensionDefinition.java
new file mode 100644 (file)
index 0000000..8b2ed86
--- /dev/null
@@ -0,0 +1,44 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+public interface ExtensionDefinition extends SchemaNode {\r
+\r
+    /**\r
+     * Returns the <code>String</code> that is the name of argument to the\r
+     * Keyword. If no argument statement is present the method will return\r
+     * <code>null</code> <br>\r
+     * The argument statement is defined in <a\r
+     * href="https://tools.ietf.org/html/rfc6020#section-7.17.2">[RFC-6020] The\r
+     * argument Statement</a>\r
+     * \r
+     * @return the <code>String</code> that is the name of argument to the\r
+     *         Keyword. If no argument statement is present the method will\r
+     *         return <code>null</code>\r
+     */\r
+    public String getArgument();\r
+\r
+    /**\r
+     * This statement indicates if the argument is mapped to an XML element in\r
+     * YIN or to an XML attribute.<br>\r
+     * By contract if implementation of ExtensionDefinition does not specify the\r
+     * yin-element statement the return value is by default set to\r
+     * <code>false</code>\r
+     * \r
+     * <br>\r
+     * <br>\r
+     * For more specific definition please look into <a\r
+     * href="https://tools.ietf.org/html/rfc6020#section-7.17.2.2">[RFC-6020]\r
+     * The yin-element Statement</a>\r
+     * \r
+     * @return <code>true</code> if the argument is mapped to an XML element in\r
+     *         YIN or returns <code>false</code> if the argument is mapped to an\r
+     *         XML attribute.\r
+     */\r
+    public boolean isYinElement();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/FeatureDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/FeatureDefinition.java
new file mode 100644 (file)
index 0000000..efd0e18
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+public interface FeatureDefinition extends SchemaNode {\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/GroupingDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/GroupingDefinition.java
new file mode 100644 (file)
index 0000000..5e94f3b
--- /dev/null
@@ -0,0 +1,16 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+import java.util.Set;\r
+\r
+public interface GroupingDefinition extends DataNodeContainer, SchemaNode {\r
+\r
+    Set<UsesNode> getUses();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/KeyDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/KeyDefinition.java
new file mode 100644 (file)
index 0000000..5e8b2c7
--- /dev/null
@@ -0,0 +1,14 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+public interface KeyDefinition extends SchemaNode {\r
+\r
+    TypeDefinition<? extends TypeDefinition<?>> getType();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/LeafListSchemaNode.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/LeafListSchemaNode.java
new file mode 100644 (file)
index 0000000..2c41e19
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+public interface LeafListSchemaNode extends DataSchemaNode {\r
+\r
+    TypeDefinition<? extends TypeDefinition<?>> getType();\r
+\r
+    boolean isUserOrdered();\r
+\r
+    MustDefinition getMustDefinition();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/LeafSchemaNode.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/LeafSchemaNode.java
new file mode 100644 (file)
index 0000000..ccb075f
--- /dev/null
@@ -0,0 +1,14 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+public interface LeafSchemaNode extends DataSchemaNode {\r
+    TypeDefinition getType();\r
+\r
+    MustDefinition getMustDefinition();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ListSchemaNode.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ListSchemaNode.java
new file mode 100644 (file)
index 0000000..824afb7
--- /dev/null
@@ -0,0 +1,21 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+public interface ListSchemaNode extends DataNodeContainer, AugmentationTarget,\r
+        DataSchemaNode {\r
+\r
+    public List<QName> getKeyDefinition();\r
+\r
+    boolean isUserOrdered();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Module.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Module.java
new file mode 100644 (file)
index 0000000..6731844
--- /dev/null
@@ -0,0 +1,46 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+import java.net.URI;\r
+import java.util.Date;\r
+import java.util.Set;\r
+\r
+public interface Module extends DataNodeContainer {\r
+\r
+    URI getNamespace();\r
+\r
+    String getName();\r
+\r
+    Date getRevision();\r
+\r
+    String getPrefix();\r
+\r
+    String getYangVersion();\r
+\r
+    String getDescription();\r
+\r
+    String getReference();\r
+\r
+    String getOrganization();\r
+\r
+    String getContact();\r
+\r
+    Set<ModuleImport> getImports();\r
+\r
+    Set<FeatureDefinition> getFeatures();\r
+\r
+    Set<NotificationDefinition> getNotifications();\r
+\r
+    Set<AugmentationSchema> getAugmentations();\r
+\r
+    Set<RpcDefinition> getRpcs();\r
+\r
+    Set<Deviation> getDeviations();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ModuleImport.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ModuleImport.java
new file mode 100644 (file)
index 0000000..37237dd
--- /dev/null
@@ -0,0 +1,19 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+import java.util.Date;\r
+\r
+public interface ModuleImport {\r
+\r
+    String getModuleName();\r
+\r
+    Date getRevision();\r
+\r
+    String getPrefix();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/MustDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/MustDefinition.java
new file mode 100644 (file)
index 0000000..42dc392
--- /dev/null
@@ -0,0 +1,13 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+public interface MustDefinition extends ConstraintMetaDefinition {\r
+\r
+    RevisionAwareXPath getXpath();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/NotificationDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/NotificationDefinition.java
new file mode 100644 (file)
index 0000000..ecb25fc
--- /dev/null
@@ -0,0 +1,14 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+import java.util.Set;\r
+\r
+public interface NotificationDefinition extends SchemaNode, DataNodeContainer {\r
+    Set<UsesNode> getUses();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/RevisionAwareXPath.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/RevisionAwareXPath.java
new file mode 100644 (file)
index 0000000..df360eb
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+public interface RevisionAwareXPath {\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/RpcDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/RpcDefinition.java
new file mode 100644 (file)
index 0000000..a4c784e
--- /dev/null
@@ -0,0 +1,21 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+import java.util.Set;\r
+\r
+public interface RpcDefinition extends SchemaNode {\r
+\r
+    Set<TypeDefinition<?>> getTypeDefinitions();\r
+\r
+    Set<GroupingDefinition> getGroupings();\r
+\r
+    ContainerSchemaNode getInput();\r
+\r
+    ContainerSchemaNode getOutput();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/SchemaNode.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/SchemaNode.java
new file mode 100644 (file)
index 0000000..97ca6a9
--- /dev/null
@@ -0,0 +1,27 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+public interface SchemaNode {\r
+\r
+    public QName getQName();\r
+\r
+    public SchemaPath getPath();\r
+\r
+    public String getDescription();\r
+\r
+    public String getReference();\r
+\r
+    public Status getStatus();\r
+\r
+    public List<ExtensionDefinition> getExtensionSchemaNodes();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/SchemaPath.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/SchemaPath.java
new file mode 100644 (file)
index 0000000..90a5d5b
--- /dev/null
@@ -0,0 +1,74 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+public class SchemaPath {\r
+\r
+    final List<QName> path;\r
+    final boolean absolute;\r
+\r
+    public SchemaPath(final List<QName> path, boolean absolute) {\r
+        this.path = Collections.unmodifiableList(new ArrayList<QName>(path));\r
+        this.absolute = absolute;\r
+    }\r
+\r
+    public List<QName> getPath() {\r
+        return path;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result + (absolute ? 1231 : 1237);\r
+        result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        SchemaPath other = (SchemaPath) obj;\r
+        if (absolute != other.absolute) {\r
+            return false;\r
+        }\r
+        if (path == null) {\r
+            if (other.path != null) {\r
+                return false;\r
+            }\r
+        } else if (!path.equals(other.path)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("SchemaPath [path=");\r
+        builder.append(path);\r
+        builder.append(", absolute=");\r
+        builder.append(absolute);\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Status.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Status.java
new file mode 100644 (file)
index 0000000..0cb3f14
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+public enum Status {\r
+    CURRENT, DEPRECATED, OBSOLOTE\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/TypeDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/TypeDefinition.java
new file mode 100644 (file)
index 0000000..acc8a34
--- /dev/null
@@ -0,0 +1,17 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+public interface TypeDefinition<T extends TypeDefinition<T>> extends SchemaNode {\r
+\r
+    T getBaseType();\r
+\r
+    String getUnits();\r
+\r
+    Object getDefaultValue();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/UsesNode.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/UsesNode.java
new file mode 100644 (file)
index 0000000..61a6d69
--- /dev/null
@@ -0,0 +1,13 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
+public interface UsesNode {\r
+    SchemaPath getGroupingPath();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/package-info.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/package-info.java
new file mode 100644 (file)
index 0000000..77bcd95
--- /dev/null
@@ -0,0 +1,312 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+\r
+/**\r
+ * Definition of structures and DOM Like API of processed YANG schema\r
+ * \r
+ * <h3>YANG Statement mapping</h3>\r
+ * \r
+ * <dl>\r
+ * <dt>anyxml\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.AnyXmlSchemaNode}\r
+ * \r
+ * <dt>argument\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ExtensionDefinition#getArgumentName()}\r
+ * \r
+ * \r
+ * <dt>augment\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.AugmentationSchema}\r
+ * \r
+ * <dt>base\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.IdentityrefTypeDefinition#getIdentity()}\r
+ * \r
+ * <dt>belongs-to\r
+ *   <dd>\r
+ * \r
+ * <dt>bit\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.BitsTypeDefinition.Bit}\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.BitsTypeDefinition#getBits()}\r
+ * \r
+ * <dt>case\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ChoiceCaseNode}\r
+ * \r
+ * <dt>choice\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ChoiceNode}\r
+ * \r
+ * <dt>config\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.DataSchemaNode#isConfiguration()}\r
+ * \r
+ * <dt>contact\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.Module#getContact()}\r
+ * \r
+ * <dt>container\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ContainerSchemaNode}\r
+ * \r
+ * <dt>default\r
+ *   <dd>\r
+ * \r
+ * <dt>description\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.SchemaNode#getDescription()}\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ConstraintMetaDefinition#getDescription()}\r
+ * \r
+ * <dt>enum\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.EnumTypeDefinition.EnumPair}\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.EnumTypeDefinition#getValues()}\r
+ * \r
+ * <dt>error-app-tag\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ConstraintMetaDefinition#getErrorAppTag()}\r
+ * \r
+ * <dt>error-message\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ConstraintMetaDefinition#getErrorMessage()}\r
+ * \r
+ * <dt>extension\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ExtensionDefinition}\r
+ * \r
+ * <dt>deviation\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.Deviation}\r
+ * \r
+ * <dt>deviate\r
+ *   <dd>\r
+ * \r
+ * <dt>feature\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.FeatureDefinition}\r
+ * \r
+ * <dt>fraction-digits\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.DecimalTypeDefinition#getFractionDigits()}\r
+ * \r
+ * <dt>grouping\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.GroupingDefinition}\r
+ * \r
+ * <dt>identity\r
+ *   <dd>\r
+ * \r
+ * <dt>if-feature\r
+ *   <dd>\r
+ * \r
+ * <dt>import\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ModuleImport}\r
+ * \r
+ * <dt>include\r
+ *   <dd>\r
+ * \r
+ * <dt>input\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.RpcDefinition#getInput()}\r
+ * \r
+ * <dt>key\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ListSchemaNode#getKeyDefinition()}\r
+ * \r
+ * <dt>leaf\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.LeafSchemaNode}\r
+ * \r
+ * <dt>leaf-list\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.LeafListSchemaNode}\r
+ * \r
+ * <dt>length\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.LengthConstraint}\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.StringTypeDefinition#getLengthStatements()}\r
+ * \r
+ * <dt>list\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ListSchemaNode}\r
+ * \r
+ * <dt>mandatory\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ConstraintDefinition#isMandatory()}\r
+ * \r
+ * <dt>max-elements\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ConstraintDefinition#getMinElements()}\r
+ * \r
+ * <dt>min-elements\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ConstraintDefinition#getMaxElements()}\r
+ * \r
+ * <dt>module\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.Module}\r
+ * \r
+ * <dt>must\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ConstraintDefinition#getMustConstraints()}\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.MustDefinition}\r
+ * \r
+ * <dt>namespace\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.Module#getNamespace()}\r
+ * \r
+ * <dt>notification\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.NotificationDefinition}\r
+ * \r
+ * <dt>ordered-by\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ListSchemaNode#isUserOrdered()}\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.LeafListSchemaNode#isUserOrdered()}\r
+ * \r
+ * <dt>organization\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.Module#getOrganization()}\r
+ * \r
+ * <dt>output\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.RpcDefinition#getOutput()}\r
+ * \r
+ * <dt>path\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.LeafrefTypeDefinition#getPathStatement()}\r
+ * \r
+ * <dt>pattern\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.base.type.api.PatternConstraint}\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.StringTypeDefinition}\r
+ * \r
+ * <dt>position\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.BitsTypeDefinition.Bit#getPosition()}\r
+ * \r
+ * <dt>prefix\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.Module#getPrefix()}\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ModuleImport#getPrefix()}\r
+ * \r
+ * <dt>presence\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ContainerSchemaNode#isPresenceContainer()}\r
+ * \r
+ * <dt>range\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.RangeConstraint}\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.IntegerTypeDefinition#getRangeStatements()}\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.UnsignedIntegerTypeDefinition#getRangeStatements()}\r
+ * \r
+ * <dt>reference\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.SchemaNode#getReference()}\r
+ * \r
+ * <dt>refine\r
+ *   <dd>\r
+ * \r
+ * <dt>require-instance\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.InstanceIdentifierTypeDefinition#requireInstance()}\r
+ * \r
+ * <dt>revision\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.Module#getRevision()}\r
+ * \r
+ * <dt>revision-date\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ModuleImport#getRevision()}\r
+ * \r
+ * <dt>rpc\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.RpcDefinition}\r
+ * \r
+ * <dt>status\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.SchemaNode#getStatus()}\r
+ * \r
+ * <dt>submodule\r
+ *   <dd>\r
+ * \r
+ * <dt>type\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.TypeDefinition}\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.LeafSchemaNode#getType()}\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.LeafListSchemaNode#getType()}\r
+ * \r
+ * <dt>typedef\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.TypeDefinition}\r
+ * \r
+ * <dt>unique\r
+ *   <dd>\r
+ * \r
+ * <dt>units\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.TypeDefinition#getUnits()}\r
+ * \r
+ * <dt>uses\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.UsesNode}\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.DataNodeContainere#getUses()}\r
+ * \r
+ * <dt>value\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.EnumTypeDefinition.EnumPair#getValue()}\r
+ * \r
+ * <dt>when\r
+ *   <dd>{@link org.opendaylight.controller.yang.model.api.ConstraintDefinition#getWhenCondition()}\r
+ * \r
+ * <dt>yang-version\r
+ * \r
+ * <dt>yin-element\r
+ *   <dd>\r
+ * \r
+ * \r
+ * \r
+ * \r
+ * <dt>add\r
+ *   <dd>\r
+ * \r
+ * <dt>current\r
+ *   <dd>\r
+ * \r
+ * <dt>delete\r
+ *   <dd>\r
+ * \r
+ * <dt>deprecated\r
+ *   <dd>\r
+ * \r
+ * <dt>false\r
+ *   <dd>\r
+ * \r
+ * <dt>max\r
+ *   <dd>\r
+ * \r
+ * <dt>min\r
+ *   <dd>\r
+ * \r
+ * <dt>not-supported\r
+ *   <dd>\r
+ * \r
+ * <dt>obsolete\r
+ *   <dd>\r
+ * \r
+ * <dt>replace\r
+ *   <dd>\r
+ * \r
+ * <dt>system\r
+ *   <dd>\r
+ * \r
+ * <dt>true\r
+ *   <dd>\r
+ * \r
+ * <dt>unbounded\r
+ *   <dd>\r
+ * \r
+ * <dt>user\r
+ *   <dd>\r
+ * </dl>\r
+ * \r
+ * \r
+ * <h3>YANG Base Type Mapping</h3>\r
+ * \r
+ * \r
+ * <dl>\r
+ * <dt>Integer built-in type\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.IntegerTypeDefinition}\r
+ * \r
+ * <dt>Unsigned integer built-in type\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.UnsignedIntegerTypeDefinition}\r
+ * \r
+ * <dt>Decimal64 built-ib type\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.DecimalTypeDefinition}\r
+ * \r
+ * <dt>Boolean built-in type\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.BooleanTypeDefinition}\r
+ *   \r
+ * <dt>Enumeration built-in type\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.EnumTypeDefinition}\r
+ *   \r
+ * <dt>Bits Built-In Type\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.BitsTypeDefinition}\r
+ * \r
+ * <dt>The binary Built-In Type\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.BinaryTypeDefinition}\r
+ *   \r
+ * <dt>The leafref Built-In Type\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.LeafrefTypeDefinition}\r
+ * \r
+ * <dt>The identityref Built-In Type\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.IdentityrefTypeDefinition}\r
+ *   \r
+ * <dt>The empty Built-In Type\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.EmptyTypeDefinition}\r
+ *   \r
+ * <dt>The union Built-In Type\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.UnionTypeDefinition}\r
+ * <dt>The instance-identifier Built-In Type\r
+ *   <dd>{@link org.opendaylight.controller.model.api.type.InstanceIdentifierTypeDefinition}\r
+ * \r
+ * </dl>\r
+ */\r
+package org.opendaylight.controller.yang.model.api;\r
+\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/pom.xml b/opendaylight/sal/yang-prototype/yang/yang-model-util/pom.xml
new file mode 100644 (file)
index 0000000..47a14e1
--- /dev/null
@@ -0,0 +1,16 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>yang</artifactId>\r
+    <version>1.0</version>\r
+  </parent>\r
+  <artifactId>yang-model-util</artifactId>\r
+  <dependencies>\r
+      <dependency>\r
+          <groupId>org.opendaylight.controller</groupId>\r
+          <artifactId>yang-model-api</artifactId>\r
+          <version>1.0</version>\r
+      </dependency>\r
+  </dependencies>\r
+</project>\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/AbstractInteger.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/AbstractInteger.java
new file mode 100644 (file)
index 0000000..5804022
--- /dev/null
@@ -0,0 +1,210 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.IntegerTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+public abstract class AbstractInteger implements IntegerTypeDefinition {\r
+\r
+    private final QName name;\r
+    private final SchemaPath path;\r
+\r
+    private final String description;\r
+    private final String reference;\r
+\r
+    private String units = "";\r
+    private final List<RangeConstraint> rangeStatements;\r
+\r
+    public AbstractInteger(final QName name, final String description,\r
+            final String reference) {\r
+        super();\r
+        this.name = name;\r
+        this.description = description;\r
+        this.reference = reference;\r
+        this.path = BaseTypes.schemaPath(name);\r
+\r
+        final List<? extends RangeConstraint> emptyContstraints = Collections\r
+                .emptyList();\r
+        this.rangeStatements = Collections.unmodifiableList(emptyContstraints);\r
+    }\r
+\r
+    public AbstractInteger(QName name, String description, String reference,\r
+            List<RangeConstraint> rangeStatements) {\r
+        super();\r
+        this.name = name;\r
+        this.description = description;\r
+        this.reference = reference;\r
+        this.rangeStatements = rangeStatements;\r
+        this.path = BaseTypes.schemaPath(name);\r
+    }\r
+\r
+    public AbstractInteger(QName name, String description, String reference,\r
+            String units) {\r
+        super();\r
+        this.name = name;\r
+        this.description = description;\r
+        this.reference = reference;\r
+        this.units = units;\r
+        this.path = BaseTypes.schemaPath(name);\r
+\r
+        final List<? extends RangeConstraint> emptyContstraints = Collections\r
+                .emptyList();\r
+        this.rangeStatements = Collections.unmodifiableList(emptyContstraints);\r
+    }\r
+\r
+    public AbstractInteger(QName name, String description, String reference,\r
+            String units, List<RangeConstraint> rangeStatements) {\r
+        super();\r
+        this.name = name;\r
+        this.description = description;\r
+        this.reference = reference;\r
+        this.units = units;\r
+        this.rangeStatements = rangeStatements;\r
+        this.path = BaseTypes.schemaPath(name);\r
+    }\r
+\r
+    @Override\r
+    public String getUnits() {\r
+        return units;\r
+    }\r
+\r
+    @Override\r
+    public QName getQName() {\r
+        return name;\r
+    }\r
+\r
+    @Override\r
+    public SchemaPath getPath() {\r
+        return path;\r
+    }\r
+\r
+    @Override\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    @Override\r
+    public String getReference() {\r
+        return reference;\r
+    }\r
+\r
+    @Override\r
+    public Status getStatus() {\r
+        return Status.CURRENT;\r
+    }\r
+\r
+    @Override\r
+    public List<RangeConstraint> getRangeStatements() {\r
+        return rangeStatements;\r
+    }\r
+\r
+    @Override\r
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+        return Collections.emptyList();\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result\r
+                + ((description == null) ? 0 : description.hashCode());\r
+        result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+        result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+        result = prime * result\r
+                + ((rangeStatements == null) ? 0 : rangeStatements.hashCode());\r
+        result = prime * result\r
+                + ((reference == null) ? 0 : reference.hashCode());\r
+        result = prime * result + ((units == null) ? 0 : units.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        AbstractInteger other = (AbstractInteger) obj;\r
+        if (description == null) {\r
+            if (other.description != null) {\r
+                return false;\r
+            }\r
+        } else if (!description.equals(other.description)) {\r
+            return false;\r
+        }\r
+        if (name == null) {\r
+            if (other.name != null) {\r
+                return false;\r
+            }\r
+        } else if (!name.equals(other.name)) {\r
+            return false;\r
+        }\r
+        if (path == null) {\r
+            if (other.path != null) {\r
+                return false;\r
+            }\r
+        } else if (!path.equals(other.path)) {\r
+            return false;\r
+        }\r
+        if (rangeStatements == null) {\r
+            if (other.rangeStatements != null) {\r
+                return false;\r
+            }\r
+        } else if (!rangeStatements.equals(other.rangeStatements)) {\r
+            return false;\r
+        }\r
+        if (reference == null) {\r
+            if (other.reference != null) {\r
+                return false;\r
+            }\r
+        } else if (!reference.equals(other.reference)) {\r
+            return false;\r
+        }\r
+        if (units == null) {\r
+            if (other.units != null) {\r
+                return false;\r
+            }\r
+        } else if (!units.equals(other.units)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("AbstractInteger [name=");\r
+        builder.append(name);\r
+        builder.append(", path=");\r
+        builder.append(path);\r
+        builder.append(", description=");\r
+        builder.append(description);\r
+        builder.append(", reference=");\r
+        builder.append(reference);\r
+        builder.append(", units=");\r
+        builder.append(units);\r
+        builder.append(", rangeStatements=");\r
+        builder.append(rangeStatements);\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BaseConstraints.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BaseConstraints.java
new file mode 100644 (file)
index 0000000..881a3e8
--- /dev/null
@@ -0,0 +1,451 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import org.opendaylight.controller.model.api.type.LengthConstraint;\r
+import org.opendaylight.controller.model.api.type.PatternConstraint;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+\r
+public final class BaseConstraints {\r
+\r
+    private BaseConstraints() {\r
+    }\r
+\r
+    public static LengthConstraint lengthConstraint(final long min,\r
+            final long max, final String description, final String reference) {\r
+        return new LengthConstraintImpl(min, max, description, reference);\r
+    }\r
+\r
+    public static RangeConstraint rangeConstraint(final long min,\r
+            final long max, final String description, final String reference) {\r
+        return new RangeConstraintImpl(min, max, description, reference);\r
+    }\r
+\r
+    public static PatternConstraint patternConstraint(final String pattern,\r
+            final String description, final String reference) {\r
+        return new PatternConstraintImpl(pattern, description, reference);\r
+    }\r
+\r
+    private static final class LengthConstraintImpl implements LengthConstraint {\r
+\r
+        private final long min;\r
+        private final long max;\r
+\r
+        private final String description;\r
+        private final String reference;\r
+\r
+        private final String errorAppTag;\r
+        private final String errorMessage;\r
+\r
+        public LengthConstraintImpl(long min, long max,\r
+                final String description, final String reference) {\r
+            super();\r
+            this.min = min;\r
+            this.max = max;\r
+            this.description = description;\r
+            this.reference = reference;\r
+\r
+            this.errorAppTag = "length-out-of-specified-bounds";\r
+            this.errorMessage = "The argument is out of bounds <" + min + ", "\r
+                    + max + ">";\r
+        }\r
+\r
+        @Override\r
+        public String getDescription() {\r
+            return description;\r
+        }\r
+\r
+        @Override\r
+        public String getErrorAppTag() {\r
+            return errorAppTag;\r
+        }\r
+\r
+        @Override\r
+        public String getErrorMessage() {\r
+            return errorMessage;\r
+        }\r
+\r
+        @Override\r
+        public String getReference() {\r
+            return reference;\r
+        }\r
+\r
+        @Override\r
+        public Long getMin() {\r
+            return min;\r
+        }\r
+\r
+        @Override\r
+        public Long getMax() {\r
+            return max;\r
+        }\r
+\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result\r
+                    + ((description == null) ? 0 : description.hashCode());\r
+            result = prime * result\r
+                    + ((errorAppTag == null) ? 0 : errorAppTag.hashCode());\r
+            result = prime * result\r
+                    + ((errorMessage == null) ? 0 : errorMessage.hashCode());\r
+            result = prime * result + (int) (max ^ (max >>> 32));\r
+            result = prime * result + (int) (min ^ (min >>> 32));\r
+            result = prime * result\r
+                    + ((reference == null) ? 0 : reference.hashCode());\r
+            return result;\r
+        }\r
+\r
+        @Override\r
+        public boolean equals(final Object obj) {\r
+            if (this == obj) {\r
+                return true;\r
+            }\r
+            if (obj == null) {\r
+                return false;\r
+            }\r
+            if (getClass() != obj.getClass()) {\r
+                return false;\r
+            }\r
+            final LengthConstraintImpl other = (LengthConstraintImpl) obj;\r
+            if (description == null) {\r
+                if (other.description != null) {\r
+                    return false;\r
+                }\r
+            } else if (!description.equals(other.description)) {\r
+                return false;\r
+            }\r
+            if (errorAppTag == null) {\r
+                if (other.errorAppTag != null) {\r
+                    return false;\r
+                }\r
+            } else if (!errorAppTag.equals(other.errorAppTag)) {\r
+                return false;\r
+            }\r
+            if (errorMessage == null) {\r
+                if (other.errorMessage != null) {\r
+                    return false;\r
+                }\r
+            } else if (!errorMessage.equals(other.errorMessage)) {\r
+                return false;\r
+            }\r
+            if (max != other.max) {\r
+                return false;\r
+            }\r
+            if (min != other.min) {\r
+                return false;\r
+            }\r
+            if (reference == null) {\r
+                if (other.reference != null) {\r
+                    return false;\r
+                }\r
+            } else if (!reference.equals(other.reference)) {\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            StringBuilder builder = new StringBuilder();\r
+            builder.append("LengthConstraintImpl [min=");\r
+            builder.append(min);\r
+            builder.append(", max=");\r
+            builder.append(max);\r
+            builder.append(", description=");\r
+            builder.append(description);\r
+            builder.append(", errorAppTag=");\r
+            builder.append(errorAppTag);\r
+            builder.append(", reference=");\r
+            builder.append(reference);\r
+            builder.append(", errorMessage=");\r
+            builder.append(errorMessage);\r
+            builder.append("]");\r
+            return builder.toString();\r
+        }\r
+    }\r
+\r
+    private final static class RangeConstraintImpl implements RangeConstraint {\r
+        private final Long min;\r
+        private final Long max;\r
+\r
+        private final String description;\r
+        private final String reference;\r
+\r
+        private final String errorAppTag;\r
+        private final String errorMessage;\r
+\r
+        public RangeConstraintImpl(Long min, Long max, String description,\r
+                String reference) {\r
+            super();\r
+            this.min = min;\r
+            this.max = max;\r
+            this.description = description;\r
+            this.reference = reference;\r
+\r
+            this.errorAppTag = "range-out-of-specified-bounds";\r
+            this.errorMessage = "The argument is out of bounds <" + min + ", "\r
+                    + max + ">";\r
+        }\r
+\r
+        @Override\r
+        public String getDescription() {\r
+            return description;\r
+        }\r
+\r
+        @Override\r
+        public String getErrorAppTag() {\r
+            return errorAppTag;\r
+        }\r
+\r
+        @Override\r
+        public String getErrorMessage() {\r
+            return errorMessage;\r
+        }\r
+\r
+        @Override\r
+        public String getReference() {\r
+            return reference;\r
+        }\r
+\r
+        @Override\r
+        public Long getMin() {\r
+            return min;\r
+        }\r
+\r
+        @Override\r
+        public Long getMax() {\r
+            return max;\r
+        }\r
+\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result\r
+                    + ((description == null) ? 0 : description.hashCode());\r
+            result = prime * result\r
+                    + ((errorAppTag == null) ? 0 : errorAppTag.hashCode());\r
+            result = prime * result\r
+                    + ((errorMessage == null) ? 0 : errorMessage.hashCode());\r
+            result = prime * result + ((max == null) ? 0 : max.hashCode());\r
+            result = prime * result + ((min == null) ? 0 : min.hashCode());\r
+            result = prime * result\r
+                    + ((reference == null) ? 0 : reference.hashCode());\r
+            return result;\r
+        }\r
+\r
+        @Override\r
+        public boolean equals(final Object obj) {\r
+            if (this == obj) {\r
+                return true;\r
+            }\r
+            if (obj == null) {\r
+                return false;\r
+            }\r
+            if (getClass() != obj.getClass()) {\r
+                return false;\r
+            }\r
+            final RangeConstraintImpl other = (RangeConstraintImpl) obj;\r
+            if (description == null) {\r
+                if (other.description != null) {\r
+                    return false;\r
+                }\r
+            } else if (!description.equals(other.description)) {\r
+                return false;\r
+            }\r
+            if (errorAppTag == null) {\r
+                if (other.errorAppTag != null) {\r
+                    return false;\r
+                }\r
+            } else if (!errorAppTag.equals(other.errorAppTag)) {\r
+                return false;\r
+            }\r
+            if (errorMessage == null) {\r
+                if (other.errorMessage != null) {\r
+                    return false;\r
+                }\r
+            } else if (!errorMessage.equals(other.errorMessage)) {\r
+                return false;\r
+            }\r
+            if (max == null) {\r
+                if (other.max != null) {\r
+                    return false;\r
+                }\r
+            } else if (!max.equals(other.max)) {\r
+                return false;\r
+            }\r
+            if (min == null) {\r
+                if (other.min != null) {\r
+                    return false;\r
+                }\r
+            } else if (!min.equals(other.min)) {\r
+                return false;\r
+            }\r
+            if (reference == null) {\r
+                if (other.reference != null) {\r
+                    return false;\r
+                }\r
+            } else if (!reference.equals(other.reference)) {\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            final StringBuilder builder = new StringBuilder();\r
+            builder.append("RangeConstraintImpl [min=");\r
+            builder.append(min);\r
+            builder.append(", max=");\r
+            builder.append(max);\r
+            builder.append(", description=");\r
+            builder.append(description);\r
+            builder.append(", reference=");\r
+            builder.append(reference);\r
+            builder.append(", errorAppTag=");\r
+            builder.append(errorAppTag);\r
+            builder.append(", errorMessage=");\r
+            builder.append(errorMessage);\r
+            builder.append("]");\r
+            return builder.toString();\r
+        }\r
+    }\r
+\r
+    private final static class PatternConstraintImpl implements\r
+            PatternConstraint {\r
+\r
+        private final String regex;\r
+        private final String description;\r
+        private final String reference;\r
+\r
+        private final String errorAppTag;\r
+        private final String errorMessage;\r
+\r
+        public PatternConstraintImpl(final String regex,\r
+                final String description, final String reference) {\r
+            super();\r
+            this.regex = regex;\r
+            this.description = description;\r
+            this.reference = reference;\r
+\r
+            errorAppTag = "invalid-regular-expression";\r
+            // TODO: add erro message\r
+            errorMessage = "";\r
+        }\r
+\r
+        @Override\r
+        public String getDescription() {\r
+            return description;\r
+        }\r
+\r
+        @Override\r
+        public String getErrorAppTag() {\r
+            return errorAppTag;\r
+        }\r
+\r
+        @Override\r
+        public String getErrorMessage() {\r
+            return errorMessage;\r
+        }\r
+\r
+        @Override\r
+        public String getReference() {\r
+            return reference;\r
+        }\r
+\r
+        @Override\r
+        public String getRegularExpression() {\r
+            return regex;\r
+        }\r
+\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result\r
+                    + ((description == null) ? 0 : description.hashCode());\r
+            result = prime * result\r
+                    + ((errorAppTag == null) ? 0 : errorAppTag.hashCode());\r
+            result = prime * result\r
+                    + ((errorMessage == null) ? 0 : errorMessage.hashCode());\r
+            result = prime * result\r
+                    + ((reference == null) ? 0 : reference.hashCode());\r
+            result = prime * result + ((regex == null) ? 0 : regex.hashCode());\r
+            return result;\r
+        }\r
+\r
+        @Override\r
+        public boolean equals(final Object obj) {\r
+            if (this == obj) {\r
+                return true;\r
+            }\r
+            if (obj == null) {\r
+                return false;\r
+            }\r
+            if (getClass() != obj.getClass()) {\r
+                return false;\r
+            }\r
+            final PatternConstraintImpl other = (PatternConstraintImpl) obj;\r
+            if (description == null) {\r
+                if (other.description != null) {\r
+                    return false;\r
+                }\r
+            } else if (!description.equals(other.description)) {\r
+                return false;\r
+            }\r
+            if (errorAppTag == null) {\r
+                if (other.errorAppTag != null) {\r
+                    return false;\r
+                }\r
+            } else if (!errorAppTag.equals(other.errorAppTag)) {\r
+                return false;\r
+            }\r
+            if (errorMessage == null) {\r
+                if (other.errorMessage != null) {\r
+                    return false;\r
+                }\r
+            } else if (!errorMessage.equals(other.errorMessage)) {\r
+                return false;\r
+            }\r
+            if (reference == null) {\r
+                if (other.reference != null) {\r
+                    return false;\r
+                }\r
+            } else if (!reference.equals(other.reference)) {\r
+                return false;\r
+            }\r
+            if (regex == null) {\r
+                if (other.regex != null) {\r
+                    return false;\r
+                }\r
+            } else if (!regex.equals(other.regex)) {\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            StringBuilder builder = new StringBuilder();\r
+            builder.append("PatternConstraintImpl [regex=");\r
+            builder.append(regex);\r
+            builder.append(", description=");\r
+            builder.append(description);\r
+            builder.append(", reference=");\r
+            builder.append(reference);\r
+            builder.append(", errorAppTag=");\r
+            builder.append(errorAppTag);\r
+            builder.append(", errorMessage=");\r
+            builder.append(errorMessage);\r
+            builder.append("]");\r
+            return builder.toString();\r
+        }\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BaseTypes.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BaseTypes.java
new file mode 100644 (file)
index 0000000..e02173c
--- /dev/null
@@ -0,0 +1,34 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.net.URI;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+\r
+public final class BaseTypes {\r
+\r
+    private BaseTypes() {\r
+    }\r
+\r
+    public static final URI BaseTypesNamespace = URI\r
+            .create("urn:ietf:params:xml:ns:yang:1");\r
+\r
+    public static final QName constructQName(final String typeName) {\r
+        return new QName(BaseTypesNamespace, typeName);\r
+    }\r
+\r
+    public static final SchemaPath schemaPath(final QName typeName) {\r
+        final List<QName> pathList = new ArrayList<QName>();\r
+        pathList.add(typeName);\r
+        return new SchemaPath(pathList, true);\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BinaryType.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BinaryType.java
new file mode 100644 (file)
index 0000000..99a9489
--- /dev/null
@@ -0,0 +1,247 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.BinaryTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.LengthConstraint;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+public class BinaryType implements BinaryTypeDefinition {\r
+\r
+    private final QName name = BaseTypes.constructQName("binary");\r
+    private final SchemaPath path = BaseTypes.schemaPath(name);\r
+    private final String description = "";\r
+    private final String reference = "";\r
+\r
+    private List<Byte> bytes;\r
+    private final LengthConstraint lengthConstraint;\r
+    private String units = "";\r
+\r
+    public BinaryType() {\r
+        super();\r
+\r
+        lengthConstraint = BaseConstraints.lengthConstraint(0L, Long.MAX_VALUE,\r
+                null, null);\r
+        bytes = Collections.emptyList();\r
+        bytes = Collections.unmodifiableList(bytes);\r
+    }\r
+\r
+    public BinaryType(final List<Byte> bytes,\r
+            final LengthConstraint lengthConstraint, final String units) {\r
+        super();\r
+        this.bytes = bytes;\r
+        this.lengthConstraint = lengthConstraint;\r
+        this.units = units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public BinaryTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getUnits()\r
+     */\r
+    @Override\r
+    public String getUnits() {\r
+        return units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return bytes;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getQName()\r
+     */\r
+    @Override\r
+    public QName getQName() {\r
+        return name;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getPath()\r
+     */\r
+    @Override\r
+    public SchemaPath getPath() {\r
+        return path;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getDescription()\r
+     */\r
+    @Override\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getReference()\r
+     */\r
+    @Override\r
+    public String getReference() {\r
+        return reference;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getStatus()\r
+     */\r
+    @Override\r
+    public Status getStatus() {\r
+        return Status.CURRENT;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * org.opendaylight.controller.yang.model.base.type.api.BinaryTypeDefinition#getLengthConstraint\r
+     * ()\r
+     */\r
+    @Override\r
+    public LengthConstraint getLengthConstraint() {\r
+        return lengthConstraint;\r
+    }\r
+\r
+    @Override\r
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+        return Collections.emptyList();\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result + ((bytes == null) ? 0 : bytes.hashCode());\r
+        result = prime * result\r
+                + ((description == null) ? 0 : description.hashCode());\r
+        result = prime\r
+                * result\r
+                + ((lengthConstraint == null) ? 0 : lengthConstraint.hashCode());\r
+        result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+        result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+        result = prime * result\r
+                + ((reference == null) ? 0 : reference.hashCode());\r
+        result = prime * result + ((units == null) ? 0 : units.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        BinaryType other = (BinaryType) obj;\r
+        if (bytes == null) {\r
+            if (other.bytes != null) {\r
+                return false;\r
+            }\r
+        } else if (!bytes.equals(other.bytes)) {\r
+            return false;\r
+        }\r
+        if (description == null) {\r
+            if (other.description != null) {\r
+                return false;\r
+            }\r
+        } else if (!description.equals(other.description)) {\r
+            return false;\r
+        }\r
+        if (lengthConstraint == null) {\r
+            if (other.lengthConstraint != null) {\r
+                return false;\r
+            }\r
+        } else if (!lengthConstraint.equals(other.lengthConstraint)) {\r
+            return false;\r
+        }\r
+        if (name == null) {\r
+            if (other.name != null) {\r
+                return false;\r
+            }\r
+        } else if (!name.equals(other.name)) {\r
+            return false;\r
+        }\r
+        if (path == null) {\r
+            if (other.path != null) {\r
+                return false;\r
+            }\r
+        } else if (!path.equals(other.path)) {\r
+            return false;\r
+        }\r
+        if (reference == null) {\r
+            if (other.reference != null) {\r
+                return false;\r
+            }\r
+        } else if (!reference.equals(other.reference)) {\r
+            return false;\r
+        }\r
+        if (units == null) {\r
+            if (other.units != null) {\r
+                return false;\r
+            }\r
+        } else if (!units.equals(other.units)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("BinaryType [name=");\r
+        builder.append(name);\r
+        builder.append(", path=");\r
+        builder.append(path);\r
+        builder.append(", description=");\r
+        builder.append(description);\r
+        builder.append(", reference=");\r
+        builder.append(reference);\r
+        builder.append(", bytes=");\r
+        builder.append(bytes);\r
+        builder.append(", lengthConstraint=");\r
+        builder.append(lengthConstraint);\r
+        builder.append(", units=");\r
+        builder.append(units);\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BitsType.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BitsType.java
new file mode 100644 (file)
index 0000000..57deb07
--- /dev/null
@@ -0,0 +1,239 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.BitsTypeDefinition;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+public class BitsType implements BitsTypeDefinition {\r
+\r
+    private final QName name = BaseTypes.constructQName("bits");\r
+    private final SchemaPath path = BaseTypes.schemaPath(name);\r
+    private final String description = "";\r
+    private final String reference = "";\r
+\r
+    private final List<Bit> bits;\r
+    private String units = "";\r
+\r
+    /**\r
+     * Default constructor. <br>\r
+     * Instantiates Bits type as empty bits list.\r
+     * \r
+     */\r
+    public BitsType() {\r
+        super();\r
+        bits = Collections.emptyList();\r
+    }\r
+\r
+    /**\r
+     * Overloaded constructor with explicit definition of bits assigned to\r
+     * BitsType.\r
+     * \r
+     * @param bits\r
+     *            The bits assigned for Bits Type\r
+     */\r
+    public BitsType(final List<Bit> bits) {\r
+        super();\r
+        this.bits = Collections.unmodifiableList(bits);\r
+        this.units = "";\r
+    }\r
+\r
+    public BitsType(List<Bit> bits, String units) {\r
+        super();\r
+        this.bits = Collections.unmodifiableList(bits);\r
+        ;\r
+        this.units = units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public BitsTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getUnits()\r
+     */\r
+    @Override\r
+    public String getUnits() {\r
+        return units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return bits;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getQName()\r
+     */\r
+    @Override\r
+    public QName getQName() {\r
+        return name;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getPath()\r
+     */\r
+    @Override\r
+    public SchemaPath getPath() {\r
+        return path;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getDescription()\r
+     */\r
+    @Override\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getReference()\r
+     */\r
+    @Override\r
+    public String getReference() {\r
+        return reference;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getStatus()\r
+     */\r
+    @Override\r
+    public Status getStatus() {\r
+        return Status.CURRENT;\r
+    }\r
+\r
+    @Override\r
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+        return Collections.emptyList();\r
+    }\r
+\r
+    @Override\r
+    public List<Bit> getBits() {\r
+        return bits;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result + ((bits == null) ? 0 : bits.hashCode());\r
+        result = prime * result\r
+                + ((description == null) ? 0 : description.hashCode());\r
+        result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+        result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+        result = prime * result\r
+                + ((reference == null) ? 0 : reference.hashCode());\r
+        result = prime * result + ((units == null) ? 0 : units.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        BitsType other = (BitsType) obj;\r
+        if (bits == null) {\r
+            if (other.bits != null) {\r
+                return false;\r
+            }\r
+        } else if (!bits.equals(other.bits)) {\r
+            return false;\r
+        }\r
+        if (description == null) {\r
+            if (other.description != null) {\r
+                return false;\r
+            }\r
+        } else if (!description.equals(other.description)) {\r
+            return false;\r
+        }\r
+        if (name == null) {\r
+            if (other.name != null) {\r
+                return false;\r
+            }\r
+        } else if (!name.equals(other.name)) {\r
+            return false;\r
+        }\r
+        if (path == null) {\r
+            if (other.path != null) {\r
+                return false;\r
+            }\r
+        } else if (!path.equals(other.path)) {\r
+            return false;\r
+        }\r
+        if (reference == null) {\r
+            if (other.reference != null) {\r
+                return false;\r
+            }\r
+        } else if (!reference.equals(other.reference)) {\r
+            return false;\r
+        }\r
+        if (units == null) {\r
+            if (other.units != null) {\r
+                return false;\r
+            }\r
+        } else if (!units.equals(other.units)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("BitsType [name=");\r
+        builder.append(name);\r
+        builder.append(", path=");\r
+        builder.append(path);\r
+        builder.append(", description=");\r
+        builder.append(description);\r
+        builder.append(", reference=");\r
+        builder.append(reference);\r
+        builder.append(", bits=");\r
+        builder.append(bits);\r
+        builder.append(", units=");\r
+        builder.append(units);\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BooleanType.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/BooleanType.java
new file mode 100644 (file)
index 0000000..361ef56
--- /dev/null
@@ -0,0 +1,235 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.BooleanTypeDefinition;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+public class BooleanType implements BooleanTypeDefinition {\r
+\r
+    private final QName name = BaseTypes.constructQName("boolean");\r
+    private final SchemaPath path = BaseTypes.schemaPath(name);\r
+    private final String description = "";\r
+    private final String reference = "";\r
+\r
+    private final Boolean defaultValue;\r
+    private String units = "";\r
+\r
+    /**\r
+     * Default constructor with default value set to "false".\r
+     */\r
+    public BooleanType() {\r
+        super();\r
+        defaultValue = false;\r
+    }\r
+\r
+    /**\r
+     * \r
+     * \r
+     * @param defaultValue\r
+     */\r
+    public BooleanType(final Boolean defaultValue) {\r
+        super();\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    /**\r
+     * \r
+     * \r
+     * @param defaultValue\r
+     * @param units\r
+     */\r
+    public BooleanType(final Boolean defaultValue, final String units) {\r
+        super();\r
+        this.defaultValue = defaultValue;\r
+        this.units = units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public BooleanTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getUnits()\r
+     */\r
+    @Override\r
+    public String getUnits() {\r
+        return units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return defaultValue;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getQName()\r
+     */\r
+    @Override\r
+    public QName getQName() {\r
+        return name;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getPath()\r
+     */\r
+    @Override\r
+    public SchemaPath getPath() {\r
+        return path;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getDescription()\r
+     */\r
+    @Override\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getReference()\r
+     */\r
+    @Override\r
+    public String getReference() {\r
+        return reference;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getStatus()\r
+     */\r
+    @Override\r
+    public Status getStatus() {\r
+        return Status.CURRENT;\r
+    }\r
+\r
+    @Override\r
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+        return Collections.emptyList();\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result\r
+                + ((defaultValue == null) ? 0 : defaultValue.hashCode());\r
+        result = prime * result\r
+                + ((description == null) ? 0 : description.hashCode());\r
+        result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+        result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+        result = prime * result\r
+                + ((reference == null) ? 0 : reference.hashCode());\r
+        result = prime * result + ((units == null) ? 0 : units.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        BooleanType other = (BooleanType) obj;\r
+        if (defaultValue == null) {\r
+            if (other.defaultValue != null) {\r
+                return false;\r
+            }\r
+        } else if (!defaultValue.equals(other.defaultValue)) {\r
+            return false;\r
+        }\r
+        if (description == null) {\r
+            if (other.description != null) {\r
+                return false;\r
+            }\r
+        } else if (!description.equals(other.description)) {\r
+            return false;\r
+        }\r
+        if (name == null) {\r
+            if (other.name != null) {\r
+                return false;\r
+            }\r
+        } else if (!name.equals(other.name)) {\r
+            return false;\r
+        }\r
+        if (path == null) {\r
+            if (other.path != null) {\r
+                return false;\r
+            }\r
+        } else if (!path.equals(other.path)) {\r
+            return false;\r
+        }\r
+        if (reference == null) {\r
+            if (other.reference != null) {\r
+                return false;\r
+            }\r
+        } else if (!reference.equals(other.reference)) {\r
+            return false;\r
+        }\r
+        if (units == null) {\r
+            if (other.units != null) {\r
+                return false;\r
+            }\r
+        } else if (!units.equals(other.units)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("BooleanType [name=");\r
+        builder.append(name);\r
+        builder.append(", path=");\r
+        builder.append(path);\r
+        builder.append(", description=");\r
+        builder.append(description);\r
+        builder.append(", reference=");\r
+        builder.append(reference);\r
+        builder.append(", defaultValue=");\r
+        builder.append(defaultValue);\r
+        builder.append(", units=");\r
+        builder.append(units);\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Decimal64.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Decimal64.java
new file mode 100644 (file)
index 0000000..5c6eac1
--- /dev/null
@@ -0,0 +1,125 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.math.BigDecimal;\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.DecimalTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+public class Decimal64 implements DecimalTypeDefinition {\r
+\r
+    private final QName name = BaseTypes.constructQName("decimal64");\r
+    private final SchemaPath path;\r
+    private String units = "";\r
+    private BigDecimal defaultValue = null;\r
+\r
+    private final String description = "The decimal64 type represents a subset of the real numbers, which can "\r
+            + "be represented by decimal numerals.  The value space of decimal64 is the set of numbers that can "\r
+            + "be obtained by multiplying a 64-bit signed integer by a negative power of ten, i.e., expressible as "\r
+            + "'i x 10^-n' where i is an integer64 and n is an integer between 1 and 18, inclusively.";\r
+\r
+    private final String reference = "https://tools.ietf.org/html/rfc6020#section-9.3";\r
+\r
+    private final List<RangeConstraint> rangeStatements;\r
+    private final Integer fractionDigits;\r
+\r
+    public Decimal64(final Integer fractionDigits) {\r
+        super();\r
+        this.fractionDigits = fractionDigits;\r
+        rangeStatements = new ArrayList<RangeConstraint>();\r
+        this.path = BaseTypes.schemaPath(name);\r
+    }\r
+\r
+    public Decimal64(final List<RangeConstraint> rangeStatements,\r
+            Integer fractionDigits) {\r
+        super();\r
+        this.rangeStatements = rangeStatements;\r
+        this.fractionDigits = fractionDigits;\r
+        this.path = BaseTypes.schemaPath(name);\r
+    }\r
+\r
+    public Decimal64(final String units, final BigDecimal defaultValue,\r
+            final List<RangeConstraint> rangeStatements,\r
+            final Integer fractionDigits) {\r
+        super();\r
+        this.units = units;\r
+        this.defaultValue = defaultValue;\r
+        this.rangeStatements = rangeStatements;\r
+        this.fractionDigits = fractionDigits;\r
+        this.path = BaseTypes.schemaPath(name);\r
+    }\r
+\r
+    @Override\r
+    public DecimalTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    @Override\r
+    public String getUnits() {\r
+        return units;\r
+    }\r
+\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return defaultValue;\r
+    }\r
+\r
+    @Override\r
+    public QName getQName() {\r
+        return name;\r
+    }\r
+\r
+    @Override\r
+    public SchemaPath getPath() {\r
+        return path;\r
+    }\r
+\r
+    @Override\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    @Override\r
+    public String getReference() {\r
+        return reference;\r
+    }\r
+\r
+    @Override\r
+    public Status getStatus() {\r
+        return Status.CURRENT;\r
+    }\r
+\r
+    @Override\r
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+        return Collections.emptyList();\r
+    }\r
+\r
+    @Override\r
+    public List<RangeConstraint> getRangeStatements() {\r
+        return rangeStatements;\r
+    }\r
+\r
+    @Override\r
+    public Integer getFractionDigits() {\r
+        return fractionDigits;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        return Decimal64.class.getSimpleName() + "[qname=" + name\r
+                + ", fractionDigits=" + fractionDigits + "]";\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/EnumerationType.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/EnumerationType.java
new file mode 100644 (file)
index 0000000..34d7459
--- /dev/null
@@ -0,0 +1,241 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.EnumTypeDefinition;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+public class EnumerationType implements EnumTypeDefinition {\r
+\r
+    private final QName name = BaseTypes.constructQName("enumeration");\r
+    private final SchemaPath path = BaseTypes.schemaPath(name);\r
+    private final String description = "The enumeration built-in type represents values from a set of assigned names.";\r
+    private final String reference = "https://tools.ietf.org/html/rfc6020#section-9.6";\r
+\r
+    private final List<EnumPair> defaultEnum;\r
+    private final List<EnumPair> enums;\r
+    private String units = "";\r
+\r
+    public EnumerationType(final List<EnumPair> enums) {\r
+        super();\r
+        this.enums = enums;\r
+\r
+        defaultEnum = Collections.emptyList();\r
+    }\r
+\r
+    public EnumerationType(final List<EnumPair> defaultEnum,\r
+            final List<EnumPair> enums, final String units) {\r
+        super();\r
+        this.defaultEnum = defaultEnum;\r
+        this.enums = enums;\r
+        this.units = units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public EnumTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getUnits()\r
+     */\r
+    @Override\r
+    public String getUnits() {\r
+        return units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return defaultEnum;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getQName()\r
+     */\r
+    @Override\r
+    public QName getQName() {\r
+        return name;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getPath()\r
+     */\r
+    @Override\r
+    public SchemaPath getPath() {\r
+        return path;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getDescription()\r
+     */\r
+    @Override\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getReference()\r
+     */\r
+    @Override\r
+    public String getReference() {\r
+        return reference;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getStatus()\r
+     */\r
+    @Override\r
+    public Status getStatus() {\r
+        return Status.CURRENT;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.base.type.api.EnumTypeDefinition#getValues()\r
+     */\r
+    @Override\r
+    public List<EnumPair> getValues() {\r
+        return enums;\r
+    }\r
+\r
+    @Override\r
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+        return Collections.emptyList();\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result\r
+                + ((defaultEnum == null) ? 0 : defaultEnum.hashCode());\r
+        result = prime * result\r
+                + ((description == null) ? 0 : description.hashCode());\r
+        result = prime * result + ((enums == null) ? 0 : enums.hashCode());\r
+        result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+        result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+        result = prime * result\r
+                + ((reference == null) ? 0 : reference.hashCode());\r
+        result = prime * result + ((units == null) ? 0 : units.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        EnumerationType other = (EnumerationType) obj;\r
+        if (defaultEnum == null) {\r
+            if (other.defaultEnum != null) {\r
+                return false;\r
+            }\r
+        } else if (!defaultEnum.equals(other.defaultEnum)) {\r
+            return false;\r
+        }\r
+        if (description == null) {\r
+            if (other.description != null) {\r
+                return false;\r
+            }\r
+        } else if (!description.equals(other.description)) {\r
+            return false;\r
+        }\r
+        if (enums == null) {\r
+            if (other.enums != null) {\r
+                return false;\r
+            }\r
+        } else if (!enums.equals(other.enums)) {\r
+            return false;\r
+        }\r
+        if (name == null) {\r
+            if (other.name != null) {\r
+                return false;\r
+            }\r
+        } else if (!name.equals(other.name)) {\r
+            return false;\r
+        }\r
+        if (path == null) {\r
+            if (other.path != null) {\r
+                return false;\r
+            }\r
+        } else if (!path.equals(other.path)) {\r
+            return false;\r
+        }\r
+        if (reference == null) {\r
+            if (other.reference != null) {\r
+                return false;\r
+            }\r
+        } else if (!reference.equals(other.reference)) {\r
+            return false;\r
+        }\r
+        if (units == null) {\r
+            if (other.units != null) {\r
+                return false;\r
+            }\r
+        } else if (!units.equals(other.units)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("EnumerationType [name=");\r
+        builder.append(name);\r
+        builder.append(", path=");\r
+        builder.append(path);\r
+        builder.append(", description=");\r
+        builder.append(description);\r
+        builder.append(", reference=");\r
+        builder.append(reference);\r
+        builder.append(", defaultEnum=");\r
+        builder.append(defaultEnum);\r
+        builder.append(", enums=");\r
+        builder.append(enums);\r
+        builder.append(", units=");\r
+        builder.append(units);\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/ExtendedType.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/ExtendedType.java
new file mode 100644 (file)
index 0000000..44ca804
--- /dev/null
@@ -0,0 +1,256 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public class ExtendedType implements TypeDefinition {\r
+\r
+    private final QName typeName;\r
+    private final TypeDefinition<?> baseType;\r
+    private final SchemaPath path;\r
+    private final String description;\r
+    private final String reference;\r
+    private final List<ExtensionDefinition> extensions;\r
+\r
+    private Status status;\r
+    private String units;\r
+    private Object defaultValue;\r
+\r
+    public static class Builder {\r
+        private final QName typeName;\r
+        private final TypeDefinition<?> baseType;\r
+\r
+        private final SchemaPath path;\r
+        private final String description;\r
+        private final String reference;\r
+\r
+        private List<ExtensionDefinition> extensions = Collections.emptyList();;\r
+        private Status status = Status.CURRENT;\r
+        private String units = "";\r
+        private Object defaultValue = null;\r
+\r
+        public Builder(final QName typeName, TypeDefinition<?> baseType,\r
+                final String description, final String reference) {\r
+            this.typeName = typeName;\r
+            this.baseType = baseType;\r
+            this.path = BaseTypes.schemaPath(typeName);\r
+            this.description = description;\r
+            this.reference = reference;\r
+        }\r
+\r
+        public Builder status(Status status) {\r
+            this.status = status;\r
+            return this;\r
+        }\r
+\r
+        public Builder units(String units) {\r
+            this.units = units;\r
+            return this;\r
+        }\r
+\r
+        public Builder defaultValue(final Object defaultValue) {\r
+            this.defaultValue = defaultValue;\r
+            return this;\r
+        }\r
+\r
+        public Builder extensions(final List<ExtensionDefinition> extensions) {\r
+            this.extensions = extensions;\r
+            return this;\r
+        }\r
+\r
+        public ExtendedType build() {\r
+            return new ExtendedType(this);\r
+        }\r
+    }\r
+\r
+    private ExtendedType(Builder builder) {\r
+        this.typeName = builder.typeName;\r
+        this.baseType = builder.baseType;\r
+        this.path = builder.path;\r
+        this.description = builder.description;\r
+        this.reference = builder.reference;\r
+        this.extensions = builder.extensions;\r
+        this.status = builder.status;\r
+        this.units = builder.units;\r
+        this.defaultValue = builder.defaultValue;\r
+    }\r
+\r
+    @Override\r
+    public TypeDefinition<?> getBaseType() {\r
+        return baseType;\r
+    }\r
+\r
+    @Override\r
+    public String getUnits() {\r
+        return units;\r
+    }\r
+\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return defaultValue;\r
+    }\r
+\r
+    @Override\r
+    public QName getQName() {\r
+        return typeName;\r
+    }\r
+\r
+    @Override\r
+    public SchemaPath getPath() {\r
+        return path;\r
+    }\r
+\r
+    @Override\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    @Override\r
+    public String getReference() {\r
+        return reference;\r
+    }\r
+\r
+    @Override\r
+    public Status getStatus() {\r
+        return status;\r
+    }\r
+\r
+    @Override\r
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+        return extensions;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result\r
+                + ((baseType == null) ? 0 : baseType.hashCode());\r
+        result = prime * result\r
+                + ((defaultValue == null) ? 0 : defaultValue.hashCode());\r
+        result = prime * result\r
+                + ((description == null) ? 0 : description.hashCode());\r
+        result = prime * result\r
+                + ((extensions == null) ? 0 : extensions.hashCode());\r
+        result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+        result = prime * result\r
+                + ((reference == null) ? 0 : reference.hashCode());\r
+        result = prime * result + ((status == null) ? 0 : status.hashCode());\r
+        result = prime * result\r
+                + ((typeName == null) ? 0 : typeName.hashCode());\r
+        result = prime * result + ((units == null) ? 0 : units.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        ExtendedType other = (ExtendedType) obj;\r
+        if (baseType == null) {\r
+            if (other.baseType != null) {\r
+                return false;\r
+            }\r
+        } else if (!baseType.equals(other.baseType)) {\r
+            return false;\r
+        }\r
+        if (defaultValue == null) {\r
+            if (other.defaultValue != null) {\r
+                return false;\r
+            }\r
+        } else if (!defaultValue.equals(other.defaultValue)) {\r
+            return false;\r
+        }\r
+        if (description == null) {\r
+            if (other.description != null) {\r
+                return false;\r
+            }\r
+        } else if (!description.equals(other.description)) {\r
+            return false;\r
+        }\r
+        if (extensions == null) {\r
+            if (other.extensions != null) {\r
+                return false;\r
+            }\r
+        } else if (!extensions.equals(other.extensions)) {\r
+            return false;\r
+        }\r
+        if (path == null) {\r
+            if (other.path != null) {\r
+                return false;\r
+            }\r
+        } else if (!path.equals(other.path)) {\r
+            return false;\r
+        }\r
+        if (reference == null) {\r
+            if (other.reference != null) {\r
+                return false;\r
+            }\r
+        } else if (!reference.equals(other.reference)) {\r
+            return false;\r
+        }\r
+        if (status != other.status) {\r
+            return false;\r
+        }\r
+        if (typeName == null) {\r
+            if (other.typeName != null) {\r
+                return false;\r
+            }\r
+        } else if (!typeName.equals(other.typeName)) {\r
+            return false;\r
+        }\r
+        if (units == null) {\r
+            if (other.units != null) {\r
+                return false;\r
+            }\r
+        } else if (!units.equals(other.units)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder2 = new StringBuilder();\r
+        builder2.append("ExtendedType [typeName=");\r
+        builder2.append(typeName);\r
+        builder2.append(", baseType=");\r
+        builder2.append(baseType);\r
+        builder2.append(", path=");\r
+        builder2.append(path);\r
+        builder2.append(", description=");\r
+        builder2.append(description);\r
+        builder2.append(", reference=");\r
+        builder2.append(reference);\r
+        builder2.append(", extensions=");\r
+        builder2.append(extensions);\r
+        builder2.append(", status=");\r
+        builder2.append(status);\r
+        builder2.append(", units=");\r
+        builder2.append(units);\r
+        builder2.append(", defaultValue=");\r
+        builder2.append(defaultValue);\r
+        builder2.append("]");\r
+        return builder2.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/IdentityType.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/IdentityType.java
new file mode 100644 (file)
index 0000000..2c10206
--- /dev/null
@@ -0,0 +1,223 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.IdentityTypeDefinition;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+public class IdentityType implements IdentityTypeDefinition {\r
+\r
+    private final QName name = BaseTypes.constructQName("identity");\r
+    private final SchemaPath path = BaseTypes.schemaPath(name);\r
+    private final String description = "";\r
+    private final String reference = "";\r
+\r
+    private String units = "";\r
+    private final QName identityName;\r
+\r
+    public IdentityType(QName identityName) {\r
+        super();\r
+        this.identityName = identityName;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public IdentityTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getUnits()\r
+     */\r
+    @Override\r
+    public String getUnits() {\r
+        return units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getQName()\r
+     */\r
+    @Override\r
+    public QName getQName() {\r
+        // TODO Auto-generated method stub\r
+        return null;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getPath()\r
+     */\r
+    @Override\r
+    public SchemaPath getPath() {\r
+        return path;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getDescription()\r
+     */\r
+    @Override\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getReference()\r
+     */\r
+    @Override\r
+    public String getReference() {\r
+        return reference;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getStatus()\r
+     */\r
+    @Override\r
+    public Status getStatus() {\r
+        return Status.CURRENT;\r
+    }\r
+\r
+    @Override\r
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+        return Collections.emptyList();\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * org.opendaylight.controller.yang.model.base.type.api.IdentityTypeDefinition#getIdentityName\r
+     * ()\r
+     */\r
+    @Override\r
+    public QName getIdentityName() {\r
+        return identityName;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result\r
+                + ((description == null) ? 0 : description.hashCode());\r
+        result = prime * result\r
+                + ((identityName == null) ? 0 : identityName.hashCode());\r
+        result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+        result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+        result = prime * result\r
+                + ((reference == null) ? 0 : reference.hashCode());\r
+        result = prime * result + ((units == null) ? 0 : units.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        IdentityType other = (IdentityType) obj;\r
+        if (description == null) {\r
+            if (other.description != null) {\r
+                return false;\r
+            }\r
+        } else if (!description.equals(other.description)) {\r
+            return false;\r
+        }\r
+        if (identityName == null) {\r
+            if (other.identityName != null) {\r
+                return false;\r
+            }\r
+        } else if (!identityName.equals(other.identityName)) {\r
+            return false;\r
+        }\r
+        if (name == null) {\r
+            if (other.name != null) {\r
+                return false;\r
+            }\r
+        } else if (!name.equals(other.name)) {\r
+            return false;\r
+        }\r
+        if (path == null) {\r
+            if (other.path != null) {\r
+                return false;\r
+            }\r
+        } else if (!path.equals(other.path)) {\r
+            return false;\r
+        }\r
+        if (reference == null) {\r
+            if (other.reference != null) {\r
+                return false;\r
+            }\r
+        } else if (!reference.equals(other.reference)) {\r
+            return false;\r
+        }\r
+        if (units == null) {\r
+            if (other.units != null) {\r
+                return false;\r
+            }\r
+        } else if (!units.equals(other.units)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("IdentityType [name=");\r
+        builder.append(name);\r
+        builder.append(", path=");\r
+        builder.append(path);\r
+        builder.append(", description=");\r
+        builder.append(description);\r
+        builder.append(", reference=");\r
+        builder.append(reference);\r
+        builder.append(", units=");\r
+        builder.append(units);\r
+        builder.append(", identityName=");\r
+        builder.append(identityName);\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Identityref.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Identityref.java
new file mode 100644 (file)
index 0000000..c4040c1
--- /dev/null
@@ -0,0 +1,224 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.IdentityTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.IdentityrefTypeDefinition;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+public class Identityref implements IdentityrefTypeDefinition {\r
+\r
+    private final QName name = BaseTypes.constructQName("identityref");\r
+    private final SchemaPath path = BaseTypes.schemaPath(name);\r
+    private final String description = "";\r
+    private final String reference = "";\r
+\r
+    private final IdentityTypeDefinition identity;\r
+\r
+    private String units = "";\r
+\r
+    public Identityref(IdentityTypeDefinition identity) {\r
+        super();\r
+        this.identity = identity;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public IdentityTypeDefinition getBaseType() {\r
+        return identity;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getUnits()\r
+     */\r
+    @Override\r
+    public String getUnits() {\r
+        return units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return identity;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getQName()\r
+     */\r
+    @Override\r
+    public QName getQName() {\r
+        return name;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getPath()\r
+     */\r
+    @Override\r
+    public SchemaPath getPath() {\r
+        return path;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getDescription()\r
+     */\r
+    @Override\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getReference()\r
+     */\r
+    @Override\r
+    public String getReference() {\r
+        return reference;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getStatus()\r
+     */\r
+    @Override\r
+    public Status getStatus() {\r
+        return Status.CURRENT;\r
+    }\r
+\r
+    @Override\r
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+        return Collections.emptyList();\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * org.opendaylight.controller.yang.model.base.type.api.IdentityrefTypeDefinition#getIdentityName\r
+     * ()\r
+     */\r
+    @Override\r
+    public IdentityTypeDefinition getIdentity() {\r
+        return identity;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result\r
+                + ((description == null) ? 0 : description.hashCode());\r
+        result = prime * result\r
+                + ((identity == null) ? 0 : identity.hashCode());\r
+        result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+        result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+        result = prime * result\r
+                + ((reference == null) ? 0 : reference.hashCode());\r
+        result = prime * result + ((units == null) ? 0 : units.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        Identityref other = (Identityref) obj;\r
+        if (description == null) {\r
+            if (other.description != null) {\r
+                return false;\r
+            }\r
+        } else if (!description.equals(other.description)) {\r
+            return false;\r
+        }\r
+        if (identity == null) {\r
+            if (other.identity != null) {\r
+                return false;\r
+            }\r
+        } else if (!identity.equals(other.identity)) {\r
+            return false;\r
+        }\r
+        if (name == null) {\r
+            if (other.name != null) {\r
+                return false;\r
+            }\r
+        } else if (!name.equals(other.name)) {\r
+            return false;\r
+        }\r
+        if (path == null) {\r
+            if (other.path != null) {\r
+                return false;\r
+            }\r
+        } else if (!path.equals(other.path)) {\r
+            return false;\r
+        }\r
+        if (reference == null) {\r
+            if (other.reference != null) {\r
+                return false;\r
+            }\r
+        } else if (!reference.equals(other.reference)) {\r
+            return false;\r
+        }\r
+        if (units == null) {\r
+            if (other.units != null) {\r
+                return false;\r
+            }\r
+        } else if (!units.equals(other.units)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("IdentityrefType [name=");\r
+        builder.append(name);\r
+        builder.append(", path=");\r
+        builder.append(path);\r
+        builder.append(", description=");\r
+        builder.append(description);\r
+        builder.append(", reference=");\r
+        builder.append(reference);\r
+        builder.append(", identity=");\r
+        builder.append(identity);\r
+        builder.append(", units=");\r
+        builder.append(units);\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/InstanceIdentifier.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/InstanceIdentifier.java
new file mode 100644 (file)
index 0000000..8376d9b
--- /dev/null
@@ -0,0 +1,151 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.InstanceIdentifierTypeDefinition;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+public class InstanceIdentifier implements InstanceIdentifierTypeDefinition {\r
+\r
+    private static final QName name = BaseTypes\r
+            .constructQName("instance-identifier");\r
+    private static final String description = "";\r
+    private static final String reference = "";\r
+\r
+    private final transient SchemaPath path = BaseTypes.schemaPath(name);\r
+    private final RevisionAwareXPath xpath;\r
+    private final String units = "";\r
+\r
+    private final boolean requireInstance;\r
+\r
+    public InstanceIdentifier(RevisionAwareXPath xpath, boolean requireInstance) {\r
+        super();\r
+        this.xpath = xpath;\r
+        this.requireInstance = requireInstance;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public InstanceIdentifierTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getUnits()\r
+     */\r
+    @Override\r
+    public String getUnits() {\r
+        return units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return xpath;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getQName()\r
+     */\r
+    @Override\r
+    public QName getQName() {\r
+        return name;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getPath()\r
+     */\r
+    @Override\r
+    public SchemaPath getPath() {\r
+        return path;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getDescription()\r
+     */\r
+    @Override\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getReference()\r
+     */\r
+    @Override\r
+    public String getReference() {\r
+        return reference;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getStatus()\r
+     */\r
+    @Override\r
+    public Status getStatus() {\r
+        return Status.CURRENT;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getExtensionSchemaNodes()\r
+     */\r
+    @Override\r
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+        return Collections.emptyList();\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.type.InstanceIdentifierTypeDefinition#\r
+     * getPathStatement()\r
+     */\r
+    @Override\r
+    public RevisionAwareXPath getPathStatement() {\r
+        return xpath;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.type.InstanceIdentifierTypeDefinition#\r
+     * requireInstance()\r
+     */\r
+    @Override\r
+    public boolean requireInstance() {\r
+        return requireInstance;\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Int16.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Int16.java
new file mode 100644 (file)
index 0000000..49ac4d1
--- /dev/null
@@ -0,0 +1,100 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.IntegerTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+public class Int16 extends AbstractInteger {\r
+\r
+    private static final QName name = BaseTypes.constructQName("int16");\r
+    private Short defaultValue = null;\r
+    private static final String description = "";\r
+    private static final String reference = "";\r
+\r
+    public Int16() {\r
+        super(name, description, reference);\r
+    }\r
+\r
+    public Int16(final Short defaultValue) {\r
+        super(name, description, reference);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Int16(final List<RangeConstraint> rangeStatements,\r
+            final Short defaultValue) {\r
+        super(name, description, reference, rangeStatements);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Int16(final String units, final Short defaultValue) {\r
+        super(name, description, reference, units);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Int16(final List<RangeConstraint> rangeStatements,\r
+            final String units, final Short defaultValue) {\r
+        super(name, description, reference, units, rangeStatements);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    @Override\r
+    public IntegerTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return defaultValue;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = super.hashCode();\r
+        result = prime * result\r
+                + ((defaultValue == null) ? 0 : defaultValue.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (!super.equals(obj)) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        Int16 other = (Int16) obj;\r
+        if (defaultValue == null) {\r
+            if (other.defaultValue != null) {\r
+                return false;\r
+            }\r
+        } else if (!defaultValue.equals(other.defaultValue)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("Int16 [defaultValue=");\r
+        builder.append(defaultValue);\r
+        builder.append(", AbstractInteger=");\r
+        builder.append(super.toString());\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Int32.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Int32.java
new file mode 100644 (file)
index 0000000..1890875
--- /dev/null
@@ -0,0 +1,110 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.IntegerTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+public class Int32 extends AbstractInteger {\r
+\r
+    private static final QName name = BaseTypes.constructQName("int32");\r
+    private Integer defaultValue = null;\r
+    private static final String description = "";\r
+    private static final String reference = "";\r
+\r
+    public Int32() {\r
+        super(name, description, reference);\r
+    }\r
+\r
+    public Int32(final Integer defaultValue) {\r
+        super(name, description, reference);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Int32(final List<RangeConstraint> rangeStatements,\r
+            final Integer defaultValue) {\r
+        super(name, description, reference, rangeStatements);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Int32(final String units, final Integer defaultValue) {\r
+        super(name, description, reference, units);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Int32(final List<RangeConstraint> rangeStatements,\r
+            final String units, final Integer defaultValue) {\r
+        super(name, description, reference, units, rangeStatements);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public IntegerTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return defaultValue;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = super.hashCode();\r
+        result = prime * result\r
+                + ((defaultValue == null) ? 0 : defaultValue.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (!super.equals(obj)) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        Int32 other = (Int32) obj;\r
+        if (defaultValue == null) {\r
+            if (other.defaultValue != null) {\r
+                return false;\r
+            }\r
+        } else if (!defaultValue.equals(other.defaultValue)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("Int32 [defaultValue=");\r
+        builder.append(defaultValue);\r
+        builder.append(", AbstractInteger=");\r
+        builder.append(super.toString());\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Int64.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Int64.java
new file mode 100644 (file)
index 0000000..c03c6b7
--- /dev/null
@@ -0,0 +1,110 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.IntegerTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+public class Int64 extends AbstractInteger {\r
+\r
+    private static final QName name = BaseTypes.constructQName("int64");\r
+    private Long defaultValue = null;\r
+    private static final String description = "";\r
+    private static final String reference = "";\r
+\r
+    public Int64() {\r
+        super(name, description, reference);\r
+    }\r
+\r
+    public Int64(final Long defaultValue) {\r
+        super(name, description, reference);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Int64(final List<RangeConstraint> rangeStatements,\r
+            final Long defaultValue) {\r
+        super(name, description, reference, rangeStatements);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Int64(final String units, final Long defaultValue) {\r
+        super(name, description, reference, units);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Int64(final List<RangeConstraint> rangeStatements,\r
+            final String units, final Long defaultValue) {\r
+        super(name, description, reference, units, rangeStatements);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public IntegerTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return defaultValue;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = super.hashCode();\r
+        result = prime * result\r
+                + ((defaultValue == null) ? 0 : defaultValue.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (!super.equals(obj)) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        Int64 other = (Int64) obj;\r
+        if (defaultValue == null) {\r
+            if (other.defaultValue != null) {\r
+                return false;\r
+            }\r
+        } else if (!defaultValue.equals(other.defaultValue)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("Int64 [defaultValue=");\r
+        builder.append(defaultValue);\r
+        builder.append(", AbstractInteger=");\r
+        builder.append(super.toString());\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Int8.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Int8.java
new file mode 100644 (file)
index 0000000..ebb5fa7
--- /dev/null
@@ -0,0 +1,110 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.IntegerTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+public class Int8 extends AbstractInteger {\r
+\r
+    private static final QName name = BaseTypes.constructQName("int8");\r
+    private Byte defaultValue = null;\r
+    private static final String description = "";\r
+    private static final String reference = "";\r
+\r
+    public Int8() {\r
+        super(name, description, reference);\r
+    }\r
+\r
+    public Int8(final Byte defaultValue) {\r
+        super(name, description, reference);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Int8(final List<RangeConstraint> rangeStatements,\r
+            final Byte defaultValue) {\r
+        super(name, description, reference, rangeStatements);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Int8(final String units, final Byte defaultValue) {\r
+        super(name, description, reference, units);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Int8(final List<RangeConstraint> rangeStatements,\r
+            final String units, final Byte defaultValue) {\r
+        super(name, description, reference, units, rangeStatements);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public IntegerTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return defaultValue;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = super.hashCode();\r
+        result = prime * result\r
+                + ((defaultValue == null) ? 0 : defaultValue.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (!super.equals(obj)) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        Int8 other = (Int8) obj;\r
+        if (defaultValue == null) {\r
+            if (other.defaultValue != null) {\r
+                return false;\r
+            }\r
+        } else if (!defaultValue.equals(other.defaultValue)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("Int8 [defaultValue=");\r
+        builder.append(defaultValue);\r
+        builder.append(", AbstractInteger=");\r
+        builder.append(super.toString());\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Leafref.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Leafref.java
new file mode 100644 (file)
index 0000000..53c2c82
--- /dev/null
@@ -0,0 +1,192 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.LeafrefTypeDefinition;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+public class Leafref implements LeafrefTypeDefinition {\r
+    private static final QName name = BaseTypes.constructQName("leafref");\r
+    private static final String description = "";\r
+    private static final String reference = "";\r
+    private final SchemaPath path = BaseTypes.schemaPath(name);\r
+    private final RevisionAwareXPath xpath;\r
+    private final String units = "";\r
+\r
+    public Leafref(RevisionAwareXPath xpath) {\r
+        super();\r
+        this.xpath = xpath;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public LeafrefTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getUnits()\r
+     */\r
+    @Override\r
+    public String getUnits() {\r
+        return units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getQName()\r
+     */\r
+    @Override\r
+    public QName getQName() {\r
+        return name;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getPath()\r
+     */\r
+    @Override\r
+    public SchemaPath getPath() {\r
+        return path;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getDescription()\r
+     */\r
+    @Override\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getReference()\r
+     */\r
+    @Override\r
+    public String getReference() {\r
+        return reference;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getStatus()\r
+     */\r
+    @Override\r
+    public Status getStatus() {\r
+        return Status.CURRENT;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getExtensionSchemaNodes()\r
+     */\r
+    @Override\r
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+        return Collections.emptyList();\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * org.opendaylight.controller.yang.model.api.type.LeafrefTypeDefinition#getPathStatement()\r
+     */\r
+    @Override\r
+    public RevisionAwareXPath getPathStatement() {\r
+        return xpath;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+        result = prime * result + ((units == null) ? 0 : units.hashCode());\r
+        result = prime * result + ((xpath == null) ? 0 : xpath.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        Leafref other = (Leafref) obj;\r
+        if (path == null) {\r
+            if (other.path != null) {\r
+                return false;\r
+            }\r
+        } else if (!path.equals(other.path)) {\r
+            return false;\r
+        }\r
+        if (units == null) {\r
+            if (other.units != null) {\r
+                return false;\r
+            }\r
+        } else if (!units.equals(other.units)) {\r
+            return false;\r
+        }\r
+        if (xpath == null) {\r
+            if (other.xpath != null) {\r
+                return false;\r
+            }\r
+        } else if (!xpath.equals(other.xpath)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("Leafref [path=");\r
+        builder.append(path);\r
+        builder.append(", xpath=");\r
+        builder.append(xpath);\r
+        builder.append(", units=");\r
+        builder.append(units);\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/StringType.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/StringType.java
new file mode 100644 (file)
index 0000000..f640831
--- /dev/null
@@ -0,0 +1,282 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.LengthConstraint;\r
+import org.opendaylight.controller.model.api.type.PatternConstraint;\r
+import org.opendaylight.controller.model.api.type.StringTypeDefinition;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+public class StringType implements StringTypeDefinition {\r
+\r
+    private final QName name = BaseTypes.constructQName("string");;\r
+    private final SchemaPath path;\r
+    private String defaultValue = "";\r
+    private final String description = "";\r
+    private final String reference = "";\r
+    private final List<LengthConstraint> lengthStatements;\r
+    private final List<PatternConstraint> patterns;\r
+    private String units = "";\r
+\r
+    public StringType() {\r
+        super();\r
+        path = BaseTypes.schemaPath(name);\r
+        this.lengthStatements = Collections.emptyList();\r
+        this.patterns = Collections.emptyList();\r
+    }\r
+\r
+    public StringType(List<LengthConstraint> lengthStatements,\r
+            List<PatternConstraint> patterns) {\r
+        super();\r
+        path = BaseTypes.schemaPath(name);\r
+        this.lengthStatements = Collections.unmodifiableList(lengthStatements);\r
+        this.patterns = Collections.unmodifiableList(patterns);\r
+    }\r
+\r
+    public StringType(final String defaultValue,\r
+            final List<LengthConstraint> lengthStatements,\r
+            final List<PatternConstraint> patterns, final String units) {\r
+        super();\r
+        path = BaseTypes.schemaPath(name);\r
+        this.defaultValue = defaultValue;\r
+        this.lengthStatements = lengthStatements;\r
+        this.patterns = patterns;\r
+        this.units = units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public StringTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getUnits()\r
+     */\r
+    @Override\r
+    public String getUnits() {\r
+        return units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return defaultValue;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getQName()\r
+     */\r
+    @Override\r
+    public QName getQName() {\r
+        return name;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getPath()\r
+     */\r
+    @Override\r
+    public SchemaPath getPath() {\r
+        return path;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getDescription()\r
+     */\r
+    @Override\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getReference()\r
+     */\r
+    @Override\r
+    public String getReference() {\r
+        return reference;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getStatus()\r
+     */\r
+    @Override\r
+    public Status getStatus() {\r
+        return Status.CURRENT;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * com.csico.yang.model.base.type.api.StringTypeDefinition#getLengthStatements\r
+     * ()\r
+     */\r
+    @Override\r
+    public List<LengthConstraint> getLengthStatements() {\r
+        return lengthStatements;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * com.csico.yang.model.base.type.api.StringTypeDefinition#getPatterns()\r
+     */\r
+    @Override\r
+    public List<PatternConstraint> getPatterns() {\r
+        return patterns;\r
+    }\r
+\r
+    @Override\r
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+        return Collections.emptyList();\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result\r
+                + ((defaultValue == null) ? 0 : defaultValue.hashCode());\r
+        result = prime * result\r
+                + ((description == null) ? 0 : description.hashCode());\r
+        result = prime\r
+                * result\r
+                + ((lengthStatements == null) ? 0 : lengthStatements.hashCode());\r
+        result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+        result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+        result = prime * result\r
+                + ((patterns == null) ? 0 : patterns.hashCode());\r
+        result = prime * result\r
+                + ((reference == null) ? 0 : reference.hashCode());\r
+        result = prime * result + ((units == null) ? 0 : units.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        StringType other = (StringType) obj;\r
+        if (defaultValue == null) {\r
+            if (other.defaultValue != null) {\r
+                return false;\r
+            }\r
+        } else if (!defaultValue.equals(other.defaultValue)) {\r
+            return false;\r
+        }\r
+        if (description == null) {\r
+            if (other.description != null) {\r
+                return false;\r
+            }\r
+        } else if (!description.equals(other.description)) {\r
+            return false;\r
+        }\r
+        if (lengthStatements == null) {\r
+            if (other.lengthStatements != null) {\r
+                return false;\r
+            }\r
+        } else if (!lengthStatements.equals(other.lengthStatements)) {\r
+            return false;\r
+        }\r
+        if (name == null) {\r
+            if (other.name != null) {\r
+                return false;\r
+            }\r
+        } else if (!name.equals(other.name)) {\r
+            return false;\r
+        }\r
+        if (path == null) {\r
+            if (other.path != null) {\r
+                return false;\r
+            }\r
+        } else if ((path != null) && (other.path != null)) {\r
+            if (!path.getPath().equals(other.path.getPath())) {\r
+                return false;\r
+            }\r
+        }\r
+        if (patterns == null) {\r
+            if (other.patterns != null) {\r
+                return false;\r
+            }\r
+        } else if (!patterns.equals(other.patterns)) {\r
+            return false;\r
+        }\r
+        if (reference == null) {\r
+            if (other.reference != null) {\r
+                return false;\r
+            }\r
+        } else if (!reference.equals(other.reference)) {\r
+            return false;\r
+        }\r
+        if (units == null) {\r
+            if (other.units != null) {\r
+                return false;\r
+            }\r
+        } else if (!units.equals(other.units)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("StringType [name=");\r
+        builder.append(name);\r
+        builder.append(", path=");\r
+        builder.append(path);\r
+        builder.append(", defaultValue=");\r
+        builder.append(defaultValue);\r
+        builder.append(", description=");\r
+        builder.append(description);\r
+        builder.append(", reference=");\r
+        builder.append(reference);\r
+        builder.append(", lengthStatements=");\r
+        builder.append(lengthStatements);\r
+        builder.append(", patterns=");\r
+        builder.append(patterns);\r
+        builder.append(", units=");\r
+        builder.append(units);\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Uint16.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Uint16.java
new file mode 100644 (file)
index 0000000..5094d77
--- /dev/null
@@ -0,0 +1,104 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.IntegerTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+public class Uint16 extends AbstractInteger {\r
+\r
+    private static final QName name = BaseTypes.constructQName("uint16");\r
+    private Integer defaultValue = null;\r
+    private static final String description = "";\r
+    private static final String reference = "";\r
+\r
+    public Uint16() {\r
+        super(name, description, reference);\r
+    }\r
+\r
+    public Uint16(final Integer defaultValue) {\r
+        super(name, description, reference);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Uint16(final List<RangeConstraint> rangeStatements,\r
+            final Integer defaultValue) {\r
+        super(name, description, reference, rangeStatements);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Uint16(final String units, final Integer defaultValue) {\r
+        super(name, description, reference, units);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public IntegerTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return defaultValue;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = super.hashCode();\r
+        result = prime * result\r
+                + ((defaultValue == null) ? 0 : defaultValue.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (!super.equals(obj)) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        Uint16 other = (Uint16) obj;\r
+        if (defaultValue == null) {\r
+            if (other.defaultValue != null) {\r
+                return false;\r
+            }\r
+        } else if (!defaultValue.equals(other.defaultValue)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("Uint16 [defaultValue=");\r
+        builder.append(defaultValue);\r
+        builder.append(", AbstractInteger=");\r
+        builder.append(super.toString());\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Uint32.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Uint32.java
new file mode 100644 (file)
index 0000000..48c6a47
--- /dev/null
@@ -0,0 +1,104 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.IntegerTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+public class Uint32 extends AbstractInteger {\r
+\r
+    private static final QName name = BaseTypes.constructQName("uint32");\r
+    private Long defaultValue = null;\r
+    private static final String description = "";\r
+    private static final String reference = "";\r
+\r
+    public Uint32() {\r
+        super(name, description, reference);\r
+    }\r
+\r
+    public Uint32(final Long defaultValue) {\r
+        super(name, description, reference);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Uint32(final List<RangeConstraint> rangeStatements,\r
+            final Long defaultValue) {\r
+        super(name, description, reference, rangeStatements);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Uint32(final String units, final Long defaultValue) {\r
+        super(name, description, reference, units);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public IntegerTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return defaultValue;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = super.hashCode();\r
+        result = prime * result\r
+                + ((defaultValue == null) ? 0 : defaultValue.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (!super.equals(obj)) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        Uint32 other = (Uint32) obj;\r
+        if (defaultValue == null) {\r
+            if (other.defaultValue != null) {\r
+                return false;\r
+            }\r
+        } else if (!defaultValue.equals(other.defaultValue)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("Uint32 [defaultValue=");\r
+        builder.append(defaultValue);\r
+        builder.append(", AbstractInteger=");\r
+        builder.append(super.toString());\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Uint64.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Uint64.java
new file mode 100644 (file)
index 0000000..8ac7c39
--- /dev/null
@@ -0,0 +1,105 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.math.BigInteger;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.IntegerTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+public class Uint64 extends AbstractInteger {\r
+\r
+    private static final QName name = BaseTypes.constructQName("uint32");\r
+    private BigInteger defaultValue = null;\r
+    private static final String description = "";\r
+    private static final String reference = "";\r
+\r
+    public Uint64() {\r
+        super(name, description, reference);\r
+    }\r
+\r
+    public Uint64(final BigInteger defaultValue) {\r
+        super(name, description, reference);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Uint64(final List<RangeConstraint> rangeStatements,\r
+            final BigInteger defaultValue) {\r
+        super(name, description, reference, rangeStatements);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Uint64(final String units, final BigInteger defaultValue) {\r
+        super(name, description, reference, units);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public IntegerTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return defaultValue;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = super.hashCode();\r
+        result = prime * result\r
+                + ((defaultValue == null) ? 0 : defaultValue.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (!super.equals(obj)) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        Uint64 other = (Uint64) obj;\r
+        if (defaultValue == null) {\r
+            if (other.defaultValue != null) {\r
+                return false;\r
+            }\r
+        } else if (!defaultValue.equals(other.defaultValue)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("Uint64 [defaultValue=");\r
+        builder.append(defaultValue);\r
+        builder.append(", AbstractInteger=");\r
+        builder.append(super.toString());\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Uint8.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/Uint8.java
new file mode 100644 (file)
index 0000000..39314fe
--- /dev/null
@@ -0,0 +1,110 @@
+/*\r
+  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+  *\r
+  * This program and the accompanying materials are made available under the\r
+  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.IntegerTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+import org.opendaylight.controller.yang.common.QName;\r
+\r
+public class Uint8 extends AbstractInteger {\r
+\r
+    private static final QName name = BaseTypes.constructQName("uint8");\r
+    private Short defaultValue = null;\r
+    private static final String description = "";\r
+    private static final String reference = "";\r
+\r
+    public Uint8() {\r
+        super(name, description, reference);\r
+    }\r
+\r
+    public Uint8(final Short defaultValue) {\r
+        super(name, description, reference);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Uint8(final List<RangeConstraint> rangeStatements,\r
+            final Short defaultValue) {\r
+        super(name, description, reference, rangeStatements);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Uint8(final String units, final Short defaultValue) {\r
+        super(name, description, reference, units);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Uint8(final List<RangeConstraint> rangeStatements,\r
+            final String units, final Short defaultValue) {\r
+        super(name, description, reference, units, rangeStatements);\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public IntegerTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return defaultValue;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = super.hashCode();\r
+        result = prime * result\r
+                + ((defaultValue == null) ? 0 : defaultValue.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (!super.equals(obj)) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        Uint8 other = (Uint8) obj;\r
+        if (defaultValue == null) {\r
+            if (other.defaultValue != null) {\r
+                return false;\r
+            }\r
+        } else if (!defaultValue.equals(other.defaultValue)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("Uint8 [defaultValue=");\r
+        builder.append(defaultValue);\r
+        builder.append(", AbstractInteger=");\r
+        builder.append(super.toString());\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/UnknownType.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/UnknownType.java
new file mode 100644 (file)
index 0000000..b1e1082
--- /dev/null
@@ -0,0 +1,440 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.model.api.type.LengthConstraint;\r
+import org.opendaylight.controller.model.api.type.PatternConstraint;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+import org.opendaylight.controller.model.api.type.UnknownTypeDefinition;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+\r
+public class UnknownType implements UnknownTypeDefinition {\r
+\r
+    private final QName name;\r
+    private final SchemaPath path;\r
+    private final String description;\r
+    private final String reference;\r
+\r
+    private final List<LengthConstraint> lengthStatements;\r
+    private final List<PatternConstraint> patterns;\r
+    private final List<RangeConstraint> rangeStatements;\r
+    private final List<ExtensionDefinition> extensions;\r
+    private final LengthConstraint lengthConstraint;\r
+\r
+    private final Status status;\r
+    private final String units;\r
+    private final Object defaultValue;\r
+\r
+    public static class Builder {\r
+\r
+        private final QName name;\r
+        private final SchemaPath path;\r
+        private String description;\r
+        private String reference;\r
+\r
+        private List<LengthConstraint> lengthStatements = Collections\r
+                .emptyList();\r
+        private List<PatternConstraint> patterns = Collections.emptyList();\r
+        private List<RangeConstraint> rangeStatements = Collections.emptyList();\r
+        private List<ExtensionDefinition> extensions = Collections.emptyList();\r
+        private LengthConstraint lengthConstraint = null;\r
+\r
+        private Status status = Status.CURRENT;\r
+        private String units = "";\r
+        private Object defaultValue = null;\r
+\r
+        public Builder(final QName name, final String description,\r
+                final String reference) {\r
+            this.name = name;\r
+            this.path = BaseTypes.schemaPath(name);\r
+            this.description = description;\r
+            this.reference = reference;\r
+        }\r
+\r
+        public Builder(final QName name) {\r
+            this.name = name;\r
+            this.path = BaseTypes.schemaPath(name);\r
+        }\r
+\r
+        public Builder description(String description) {\r
+            this.description = description;\r
+            return this;\r
+        }\r
+\r
+        public Builder reference(String reference) {\r
+            this.reference = reference;\r
+            return this;\r
+        }\r
+\r
+        public Builder lengthStatements(\r
+                final List<LengthConstraint> lengthStatements) {\r
+            this.lengthStatements = lengthStatements;\r
+            return this;\r
+        }\r
+\r
+        public Builder patterns(final List<PatternConstraint> patterns) {\r
+            this.patterns = patterns;\r
+            return this;\r
+        }\r
+\r
+        public Builder rangeStatements(\r
+                final List<RangeConstraint> rangeStatements) {\r
+            this.rangeStatements = rangeStatements;\r
+            return this;\r
+        }\r
+\r
+        public Builder extensions(final List<ExtensionDefinition> extensions) {\r
+            this.extensions = extensions;\r
+            return this;\r
+        }\r
+\r
+        public Builder lengthConstraint(final LengthConstraint lengthConstraint) {\r
+            this.lengthConstraint = lengthConstraint;\r
+            return this;\r
+        }\r
+\r
+        public Builder status(Status status) {\r
+            this.status = status;\r
+            return this;\r
+        }\r
+\r
+        public Builder units(String units) {\r
+            this.units = units;\r
+            return this;\r
+        }\r
+\r
+        public Builder defaultValue(final Object defaultValue) {\r
+            this.defaultValue = defaultValue;\r
+            return this;\r
+        }\r
+\r
+        public UnknownTypeDefinition build() {\r
+            return new UnknownType(this);\r
+        }\r
+    }\r
+\r
+    private UnknownType(Builder builder) {\r
+        this.name = builder.name;\r
+        this.path = builder.path;\r
+        this.description = builder.description;\r
+        this.reference = builder.reference;\r
+        this.lengthStatements = builder.lengthStatements;\r
+        this.patterns = builder.patterns;\r
+        this.rangeStatements = builder.rangeStatements;\r
+        this.extensions = builder.extensions;\r
+        this.lengthConstraint = builder.lengthConstraint;\r
+        this.status = builder.status;\r
+        this.units = builder.units;\r
+        this.defaultValue = builder.defaultValue;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()\r
+     */\r
+    @Override\r
+    public UnknownTypeDefinition getBaseType() {\r
+        return this;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getUnits()\r
+     */\r
+    @Override\r
+    public String getUnits() {\r
+        return units;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue\r
+     * ()\r
+     */\r
+    @Override\r
+    public Object getDefaultValue() {\r
+        return defaultValue;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getQName()\r
+     */\r
+    @Override\r
+    public QName getQName() {\r
+        return name;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getPath()\r
+     */\r
+    @Override\r
+    public SchemaPath getPath() {\r
+        return path;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * org.opendaylight.controller.yang.model.api.SchemaNode#getDescription()\r
+     */\r
+    @Override\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getReference()\r
+     */\r
+    @Override\r
+    public String getReference() {\r
+        return reference;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.opendaylight.controller.yang.model.api.SchemaNode#getStatus()\r
+     */\r
+    @Override\r
+    public Status getStatus() {\r
+        return status;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * org.opendaylight.controller.yang.model.api.SchemaNode#getExtensionSchemaNodes\r
+     * ()\r
+     */\r
+    @Override\r
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
+        return extensions;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * org.opendaylight.controller.yang.model.api.type.UnknownTypeDefinition\r
+     * #getRangeStatements()\r
+     */\r
+    @Override\r
+    public List<RangeConstraint> getRangeStatements() {\r
+        return rangeStatements;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * org.opendaylight.controller.yang.model.api.type.UnknownTypeDefinition\r
+     * #getLengthStatements()\r
+     */\r
+    @Override\r
+    public List<LengthConstraint> getLengthStatements() {\r
+        return lengthStatements;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * org.opendaylight.controller.yang.model.api.type.UnknownTypeDefinition\r
+     * #getPatterns()\r
+     */\r
+    @Override\r
+    public List<PatternConstraint> getPatterns() {\r
+        return patterns;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * org.opendaylight.controller.yang.model.api.type.UnknownTypeDefinition\r
+     * #getLengthConstraint()\r
+     */\r
+    @Override\r
+    public LengthConstraint getLengthConstraint() {\r
+        return lengthConstraint;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result\r
+                + ((defaultValue == null) ? 0 : defaultValue.hashCode());\r
+        result = prime * result\r
+                + ((description == null) ? 0 : description.hashCode());\r
+        result = prime * result\r
+                + ((extensions == null) ? 0 : extensions.hashCode());\r
+        result = prime\r
+                * result\r
+                + ((lengthConstraint == null) ? 0 : lengthConstraint.hashCode());\r
+        result = prime\r
+                * result\r
+                + ((lengthStatements == null) ? 0 : lengthStatements.hashCode());\r
+        result = prime * result + ((name == null) ? 0 : name.hashCode());\r
+        result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+        result = prime * result\r
+                + ((patterns == null) ? 0 : patterns.hashCode());\r
+        result = prime * result\r
+                + ((rangeStatements == null) ? 0 : rangeStatements.hashCode());\r
+        result = prime * result\r
+                + ((reference == null) ? 0 : reference.hashCode());\r
+        result = prime * result + ((status == null) ? 0 : status.hashCode());\r
+        result = prime * result + ((units == null) ? 0 : units.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        UnknownType other = (UnknownType) obj;\r
+        if (defaultValue == null) {\r
+            if (other.defaultValue != null) {\r
+                return false;\r
+            }\r
+        } else if (!defaultValue.equals(other.defaultValue)) {\r
+            return false;\r
+        }\r
+        if (description == null) {\r
+            if (other.description != null) {\r
+                return false;\r
+            }\r
+        } else if (!description.equals(other.description)) {\r
+            return false;\r
+        }\r
+        if (extensions == null) {\r
+            if (other.extensions != null) {\r
+                return false;\r
+            }\r
+        } else if (!extensions.equals(other.extensions)) {\r
+            return false;\r
+        }\r
+        if (lengthConstraint == null) {\r
+            if (other.lengthConstraint != null) {\r
+                return false;\r
+            }\r
+        } else if (!lengthConstraint.equals(other.lengthConstraint)) {\r
+            return false;\r
+        }\r
+        if (lengthStatements == null) {\r
+            if (other.lengthStatements != null) {\r
+                return false;\r
+            }\r
+        } else if (!lengthStatements.equals(other.lengthStatements)) {\r
+            return false;\r
+        }\r
+        if (name == null) {\r
+            if (other.name != null) {\r
+                return false;\r
+            }\r
+        } else if (!name.equals(other.name)) {\r
+            return false;\r
+        }\r
+        if (path == null) {\r
+            if (other.path != null) {\r
+                return false;\r
+            }\r
+        } else if (!path.equals(other.path)) {\r
+            return false;\r
+        }\r
+        if (patterns == null) {\r
+            if (other.patterns != null) {\r
+                return false;\r
+            }\r
+        } else if (!patterns.equals(other.patterns)) {\r
+            return false;\r
+        }\r
+        if (rangeStatements == null) {\r
+            if (other.rangeStatements != null) {\r
+                return false;\r
+            }\r
+        } else if (!rangeStatements.equals(other.rangeStatements)) {\r
+            return false;\r
+        }\r
+        if (reference == null) {\r
+            if (other.reference != null) {\r
+                return false;\r
+            }\r
+        } else if (!reference.equals(other.reference)) {\r
+            return false;\r
+        }\r
+        if (status != other.status) {\r
+            return false;\r
+        }\r
+        if (units == null) {\r
+            if (other.units != null) {\r
+                return false;\r
+            }\r
+        } else if (!units.equals(other.units)) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder2 = new StringBuilder();\r
+        builder2.append("UnknownType [name=");\r
+        builder2.append(name);\r
+        builder2.append(", path=");\r
+        builder2.append(path);\r
+        builder2.append(", description=");\r
+        builder2.append(description);\r
+        builder2.append(", reference=");\r
+        builder2.append(reference);\r
+        builder2.append(", lengthStatements=");\r
+        builder2.append(lengthStatements);\r
+        builder2.append(", patterns=");\r
+        builder2.append(patterns);\r
+        builder2.append(", rangeStatements=");\r
+        builder2.append(rangeStatements);\r
+        builder2.append(", extensions=");\r
+        builder2.append(extensions);\r
+        builder2.append(", lengthConstraint=");\r
+        builder2.append(lengthConstraint);\r
+        builder2.append(", status=");\r
+        builder2.append(status);\r
+        builder2.append(", units=");\r
+        builder2.append(units);\r
+        builder2.append(", defaultValue=");\r
+        builder2.append(defaultValue);\r
+        builder2.append("]");\r
+        return builder2.toString();\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/YangTypesConverter.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/model/util/YangTypesConverter.java
new file mode 100644 (file)
index 0000000..1ab1dc6
--- /dev/null
@@ -0,0 +1,115 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.model.util;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.model.api.type.BinaryTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.BitsTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.BooleanTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.DecimalTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.IntegerTypeDefinition;\r
+import org.opendaylight.controller.model.api.type.RangeConstraint;\r
+import org.opendaylight.controller.model.api.type.StringTypeDefinition;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+\r
+public class YangTypesConverter {\r
+\r
+    private static final Map<String, TypeDefinition<? extends TypeDefinition<?>>> baseYangTypeMap = new HashMap<String, TypeDefinition<? extends TypeDefinition<?>>>();\r
+    private static final Set<String> baseYangTypes = new HashSet<String>();\r
+\r
+    private static final TypeDefinition<BinaryTypeDefinition> BINARY = new BinaryType();\r
+    private static final TypeDefinition<BitsTypeDefinition> BITS = new BitsType();\r
+    private static final TypeDefinition<BooleanTypeDefinition> BOOLEAN_TYPE = new BooleanType();\r
+    private static final TypeDefinition<IntegerTypeDefinition> INT8_TYPE = new Int8();\r
+    private static final TypeDefinition<IntegerTypeDefinition> INT16_TYPE = new Int16();\r
+    private static final TypeDefinition<IntegerTypeDefinition> INT32_TYPE = new Int32();\r
+    private static final TypeDefinition<IntegerTypeDefinition> INT64_TYPE = new Int64();\r
+    private static final TypeDefinition<StringTypeDefinition> STRING_TYPE = new StringType();\r
+    private static final TypeDefinition<IntegerTypeDefinition> UINT8_TYPE = new Uint8();\r
+    private static final TypeDefinition<IntegerTypeDefinition> UINT16_TYPE = new Int16();\r
+    private static final TypeDefinition<IntegerTypeDefinition> UINT32_TYPE = new Int32();\r
+    private static final TypeDefinition<IntegerTypeDefinition> UINT64_TYPE = new Int64();\r
+\r
+    static {\r
+        baseYangTypeMap.put("binary", BINARY);\r
+        baseYangTypeMap.put("bits", BITS);\r
+        baseYangTypeMap.put("boolean", BOOLEAN_TYPE);\r
+        baseYangTypeMap.put("int8", INT8_TYPE);\r
+        baseYangTypeMap.put("int16", INT16_TYPE);\r
+        baseYangTypeMap.put("int32", INT32_TYPE);\r
+        baseYangTypeMap.put("int64", INT64_TYPE);\r
+        baseYangTypeMap.put("string", STRING_TYPE);\r
+        baseYangTypeMap.put("uint8", UINT8_TYPE);\r
+        baseYangTypeMap.put("uint16", UINT16_TYPE);\r
+        baseYangTypeMap.put("uint32", UINT32_TYPE);\r
+        baseYangTypeMap.put("uint64", UINT64_TYPE);\r
+\r
+        baseYangTypes.add("binary");\r
+        baseYangTypes.add("bits");\r
+        baseYangTypes.add("boolean");\r
+        baseYangTypes.add("decimal64");\r
+        baseYangTypes.add("enumeration");\r
+        baseYangTypes.add("int8");\r
+        baseYangTypes.add("int16");\r
+        baseYangTypes.add("int32");\r
+        baseYangTypes.add("int64");\r
+        baseYangTypes.add("string");\r
+        baseYangTypes.add("uint8");\r
+        baseYangTypes.add("uint16");\r
+        baseYangTypes.add("uint32");\r
+        baseYangTypes.add("uint64");\r
+    }\r
+\r
+    public static boolean isBaseYangType(String type) {\r
+        return baseYangTypes.contains(type);\r
+    }\r
+\r
+    public static TypeDefinition<?> javaTypeForBaseYangType(QName typeQName) {\r
+        TypeDefinition<?> type = baseYangTypeMap.get(typeQName.getLocalName());\r
+        return type;\r
+    }\r
+\r
+    public static TypeDefinition<?> javaTypeForBaseYangType(String typeName) {\r
+        TypeDefinition<?> type = baseYangTypeMap.get(typeName);\r
+        return type;\r
+    }\r
+\r
+    public static TypeDefinition<IntegerTypeDefinition> javaTypeForBaseYangIntegerType(\r
+            String typeName, List<RangeConstraint> ranges) {\r
+        if (typeName.equals("int8")) {\r
+            return new Int8(ranges, null);\r
+        } else if (typeName.equals("int16")) {\r
+            return new Int16(ranges, null);\r
+        } else if (typeName.equals("int32")) {\r
+            return new Int32(ranges, null);\r
+        } else if (typeName.equals("int64")) {\r
+            return new Int64(ranges, null);\r
+        } else if (typeName.equals("uint8")) {\r
+            return new Uint8(ranges, null);\r
+        } else if (typeName.equals("uint16")) {\r
+            return new Uint16(ranges, null);\r
+        } else if (typeName.equals("uint32")) {\r
+            return new Uint32(ranges, null);\r
+        } else if (typeName.equals("uint64")) {\r
+            return new Uint64(ranges, null);\r
+        }\r
+        return null;\r
+    }\r
+\r
+    public static TypeDefinition<DecimalTypeDefinition> javaTypeForBaseYangDecimal64Type(\r
+            List<RangeConstraint> rangeStatements, int fractionDigits) {\r
+        return new Decimal64(rangeStatements, fractionDigits);\r
+    }\r
+\r
+}\r
diff --git a/sitebuildsettings-pom.xml b/sitebuildsettings-pom.xml
new file mode 100644 (file)
index 0000000..7b144d5
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <prerequisites>
+    <maven>3.0</maven>
+  </prerequisites>
+  <groupId>sitebuildsettings</groupId>
+  <artifactId>sitebuildsettings</artifactId>
+  <version>1.0.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+  <properties>
+    <sonar.host.url>https://sonar.opendaylight.org/</sonar.host.url>
+    <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
+    <sitedeploy>dav:http://nexus.opendaylight.org/content/sites/site</sitedeploy>
+    <thirdpartyID>thirdparty</thirdpartyID>
+    <opendaylightID>opendaylight</opendaylightID>
+  </properties>
+</project>
diff --git a/third-party/commons/thirdparty/pom.xml b/third-party/commons/thirdparty/pom.xml
new file mode 100644 (file)
index 0000000..28a6827
--- /dev/null
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <prerequisites>
+    <maven>3.0</maven>
+  </prerequisites>
+  <!-- The sitebuildsettings-pom.xml contains the specific settings
+       for a site on which the build can be performed so it will
+       contain for instance reference to the local Maven proxy/host
+       server or the local sonar etc. -->
+  <parent>
+    <groupId>sitebuildsettings</groupId>
+    <artifactId>sitebuildsettings</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <relativePath>../../../sitebuildsettings-pom.xml</relativePath>
+  </parent>
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>commons.thirdparty</artifactId>
+  <version>1.1.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+  <properties>
+    <siteplugin>3.2</siteplugin>
+    <projectinfo>2.6</projectinfo>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <compiler.version>2.3.2</compiler.version>
+    <surefire.version>2.13</surefire.version>
+  </properties>
+
+  <pluginRepositories>
+    <pluginRepository>
+      <id>central2</id>
+      <name>central2</name>
+      <url>${nexusproxy}/repositories/central2/</url>
+    </pluginRepository>
+  </pluginRepositories>
+
+  <profiles>
+    <profile>
+      <id>fastreassembly</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-dependency-plugin</artifactId>
+            <version>2.4</version>
+            <executions>
+              <execution>
+                <id>copyfastreassembly</id>
+                <phase>install</phase>
+                <goals>
+                  <goal>copy</goal>
+                </goals>
+                <configuration>
+                  <artifactItems>
+                    <artifactItem>
+                      <groupId>${project.groupId}</groupId>
+                      <artifactId>${project.artifactId}</artifactId>
+                      <version>${project.version}</version>
+                      <destFileName>${project.groupId}.${project.artifactId}-${project.version}.jar</destFileName>
+                    </artifactItem>
+                  </artifactItems>
+                  <outputDirectory>${fastreassembly.directory}</outputDirectory>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>com.googlecode.maven-java-formatter-plugin</groupId>
+        <artifactId>maven-java-formatter-plugin</artifactId>
+        <version>0.3.1</version>
+        <configuration>
+          <excludes>
+            <exclude>**/*</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+    </plugins>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-site-plugin</artifactId>
+          <version>${siteplugin}</version>
+          <configuration>
+            <reportPlugins>
+              <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <version>${projectinfo}</version>
+                <configuration>
+                  <dependencyDetailsEnabled>false</dependencyDetailsEnabled>
+                  <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
+                </configuration>
+                <reports>
+                  <report>index</report>
+                  <report>project-team</report>
+                  <report>license</report>
+                  <report>mailing-list</report>
+                  <report>plugin-management</report>
+                  <report>cim</report>
+                  <report>issue-tracking</report>
+                  <report>scm</report>
+                  <report>summary</report>
+                </reports>
+              </plugin>
+              <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <version>2.10</version>
+              </plugin>
+              <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>2.8.1</version>
+                <configuration>
+                  <doclet>org.jboss.apiviz.APIviz</doclet>
+                  <docletArtifact>
+                    <groupId>org.jboss.apiviz</groupId>
+                    <artifactId>apiviz</artifactId>
+                    <version>1.3.2.GA</version>
+                  </docletArtifact>
+                  <finalName>${project.artifactId}-${build.suffix}</finalName>
+                  <useStandardDocletOptions>true</useStandardDocletOptions>
+                  <charset>UTF-8</charset>
+                  <encoding>UTF-8</encoding>
+                  <docencoding>UTF-8</docencoding>
+                  <breakiterator>true</breakiterator>
+                  <version>true</version>
+                  <author>true</author>
+                  <keywords>true</keywords>
+                  <excludePackageNames>net.sf.jnetlib.*:cern.*:corejava</excludePackageNames>
+                </configuration>
+              </plugin>
+              <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jxr-plugin</artifactId>
+                <version>2.3</version>
+                <configuration>
+                  <aggregate>true</aggregate>
+                  <linkJavadoc>true</linkJavadoc>
+                </configuration>
+              </plugin>
+            </reportPlugins>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+
+  <repositories>
+    <!-- Maven repo2 mirror -->
+    <repository>
+      <id>central2</id>
+      <name>central2</name>
+      <url>${nexusproxy}/repositories/central2/</url>
+    </repository>
+    <!-- Maven repo1 mirror -->
+    <repository>
+      <id>central</id>
+      <name>central</name>
+      <url>${nexusproxy}/repositories/central/</url>
+    </repository>
+    <!-- Third Packages hosted in local maven because not available in
+         other places -->
+    <repository>
+      <id>${thirdpartyID}</id>
+      <name>thirdparty</name>
+      <url>${nexusproxy}/repositories/thirdparty</url>
+    </repository>
+  </repositories>
+  <distributionManagement>
+    <!-- Third-party Released artifact -->
+    <repository>
+      <id>${thirdpartyID}</id>
+      <url>${nexusproxy}/repositories/thirdparty</url>
+    </repository>
+    <!-- Third-party Snapshot artifact -->
+    <snapshotRepository>
+      <id>${thirdpartyID}-snapshot</id>
+      <url>${nexusproxy}/repositories/thirdparty-snapshot</url>
+    </snapshotRepository>
+    <!-- Site deployment -->
+    <site>
+      <id>website</id>
+      <url>${sitedeploy}</url>
+    </site>
+  </distributionManagement>
+</project>
diff --git a/third-party/jersey-servlet/pom.xml b/third-party/jersey-servlet/pom.xml
new file mode 100644 (file)
index 0000000..dfb8968
--- /dev/null
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <!-- Get some common settings for the project we are using it in -->
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.thirdparty</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <relativePath>../commons/thirdparty</relativePath>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.opendaylight.controller.thirdparty</groupId>
+  <artifactId>com.sun.jersey.jersey-servlet</artifactId>
+  <version>1.17-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>2.3.6</version>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Embed-Dependency>*;scope=!provided;type=!pom;inline=false</Embed-Dependency>
+            <Embed-Transitive>false</Embed-Transitive>
+            <Export-Package>
+              com.sun.jersey.api.core.servlet,
+              com.sun.jersey.spi.container.servlet,
+              com.sun.jersey.spi.scanning.servlet,
+              com.sun.jersey.server.impl.container.servlet
+            </Export-Package>
+            <Import-Package>
+              com.sun.jersey.api.container,
+              com.sun.jersey.api.core,
+              com.sun.jersey.api.model,
+              com.sun.jersey.api.representation,
+              com.sun.jersey.api.uri,
+              com.sun.jersey.api.view,
+              com.sun.jersey.core.header,
+              com.sun.jersey.core.reflection,
+              com.sun.jersey.core.spi.component,
+              com.sun.jersey.core.spi.component.ioc,
+              com.sun.jersey.core.spi.scanning,
+              com.sun.jersey.core.util,
+              com.sun.jersey.server.impl,
+              com.sun.jersey.server.impl.application,
+              com.sun.jersey.server.impl.inject,
+              com.sun.jersey.server.impl.monitoring,
+              com.sun.jersey.server.probes,
+              com.sun.jersey.server.spi.component,
+              com.sun.jersey.spi,
+              com.sun.jersey.spi.container,
+              com.sun.jersey.spi.dispatch,
+              com.sun.jersey.spi.inject,
+              com.sun.jersey.spi.service,
+              com.sun.jersey.spi.template,
+              javax.naming,
+              javax.ws.rs,
+              javax.ws.rs.core,
+              javax.ws.rs.ext,
+              *;resolution:=optional
+            </Import-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-servlet</artifactId>
+      <version>1.17</version>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>javax.servlet</artifactId>
+      <version>3.0.0.v201112011016</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/third-party/net.sf.jung2/pom.xml b/third-party/net.sf.jung2/pom.xml
new file mode 100644 (file)
index 0000000..bfe59c5
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <!-- Get some common settings for the project we are using it in -->
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.thirdparty</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <relativePath>../commons/thirdparty</relativePath>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.opendaylight.controller.thirdparty</groupId>
+  <artifactId>net.sf.jung2</artifactId>
+  <version>2.0.1-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>2.3.6</version>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Embed-Dependency>*;scope=compile|runtime;type=!pom;inline=false</Embed-Dependency>
+            <Embed-Transitive>false</Embed-Transitive>
+            <Export-Package>
+              org.apache.commons*,
+              edu.uci.ics.jung.algorithms.blockmodel,
+              edu.uci.ics.jung.algorithms.cluster,
+              edu.uci.ics.jung.algorithms.filters,
+              edu.uci.ics.jung.algorithms.flows,
+              edu.uci.ics.jung.algorithms.generators,
+              edu.uci.ics.jung.algorithms.generators.random,
+              edu.uci.ics.jung.algorithms.layout,
+              edu.uci.ics.jung.algorithms.layout.util,
+              edu.uci.ics.jung.algorithms.metrics,
+              edu.uci.ics.jung.algorithms.scoring,
+              edu.uci.ics.jung.algorithms.scoring.util,
+              edu.uci.ics.jung.algorithms.shortestpath,
+              edu.uci.ics.jung.algorithms.transformation,
+              edu.uci.ics.jung.algorithms.util,
+              edu.uci.ics.jung.graph;-split-package:=merge-first,
+              edu.uci.ics.jung.graph.event,
+              edu.uci.ics.jung.graph.util;-split-package:=merge-first
+            </Export-Package>
+            <Import-Package>
+              !*
+            </Import-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>net.sf.jung</groupId>
+      <artifactId>jung-api</artifactId>
+      <version>2.0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>net.sf.jung</groupId>
+      <artifactId>jung-graph-impl</artifactId>
+      <version>2.0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>net.sourceforge.collections</groupId>
+      <artifactId>collections-generic</artifactId>
+      <version>4.01</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/blockmodel/StructurallyEquivalent.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/blockmodel/StructurallyEquivalent.java
new file mode 100644 (file)
index 0000000..a9d4573
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2004, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ * Created on Jan 28, 2004
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.blockmodel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections15.CollectionUtils;
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.Pair;
+
+/**
+ * Identifies sets of structurally equivalent vertices in a graph. Vertices <i>
+ * i</i> and <i>j</i> are structurally equivalent iff the set of <i>i</i>'s
+ * neighbors is identical to the set of <i>j</i>'s neighbors, with the
+ * exception of <i>i</i> and <i>j</i> themselves. This algorithm finds all
+ * sets of equivalent vertices in O(V^2) time.
+ * 
+ * <p>You can extend this class to have a different definition of equivalence (by
+ * overriding <code>isStructurallyEquivalent</code>), and may give it hints for
+ * accelerating the process by overriding <code>canPossiblyCompare</code>. 
+ * (For example, in a bipartite graph, <code>canPossiblyCompare</code> may 
+ * return <code>false</code> for vertices in
+ * different partitions. This function should be fast.)
+ * 
+ * @author Danyel Fisher
+ */
+public class StructurallyEquivalent<V,E> implements Transformer<Graph<V,E>, VertexPartition<V,E>> 
+{
+       public VertexPartition<V,E> transform(Graph<V,E> g) 
+       {
+           Set<Pair<V>> vertex_pairs = getEquivalentPairs(g);
+           
+           Set<Set<V>> rv = new HashSet<Set<V>>();
+        Map<V, Set<V>> intermediate = new HashMap<V, Set<V>>();
+        for (Pair<V> p : vertex_pairs)
+        {
+            Set<V> res = intermediate.get(p.getFirst());
+            if (res == null)
+                res = intermediate.get(p.getSecond());
+            if (res == null)  // we haven't seen this one before
+                res = new HashSet<V>();
+            res.add(p.getFirst());
+            res.add(p.getSecond());
+            intermediate.put(p.getFirst(), res);
+            intermediate.put(p.getSecond(), res);
+        }
+        rv.addAll(intermediate.values());
+
+        // pick up the vertices which don't appear in intermediate; they are
+        // singletons (equivalence classes of size 1)
+        Collection<V> singletons = CollectionUtils.subtract(g.getVertices(),
+                intermediate.keySet());
+        for (V v : singletons)
+        {
+            Set<V> v_set = Collections.singleton(v);
+            intermediate.put(v, v_set);
+            rv.add(v_set);
+        }
+
+        return new VertexPartition<V, E>(g, intermediate, rv);
+       }
+
+       /**
+        * For each vertex pair v, v1 in G, checks whether v and v1 are fully
+        * equivalent: meaning that they connect to the exact same vertices. (Is
+        * this regular equivalence, or whathaveyou?)
+        * 
+        * Returns a Set of Pairs of vertices, where all the vertices in the inner
+        * Pairs are equivalent.
+        * 
+        * @param g
+        */
+       protected Set<Pair<V>> getEquivalentPairs(Graph<V,?> g) {
+
+               Set<Pair<V>> rv = new HashSet<Pair<V>>();
+               Set<V> alreadyEquivalent = new HashSet<V>();
+
+               List<V> l = new ArrayList<V>(g.getVertices());
+
+               for (V v1 : l)
+               {
+                       if (alreadyEquivalent.contains(v1))
+                               continue;
+
+                       for (Iterator<V> iterator = l.listIterator(l.indexOf(v1) + 1); iterator.hasNext();) {
+                           V v2 = iterator.next();
+
+                               if (alreadyEquivalent.contains(v2))
+                                       continue;
+
+                               if (!canPossiblyCompare(v1, v2))
+                                       continue;
+
+                               if (isStructurallyEquivalent(g, v1, v2)) {
+                                       Pair<V> p = new Pair<V>(v1, v2);
+                                       alreadyEquivalent.add(v2);
+                                       rv.add(p);
+                               }
+                       }
+               }
+               
+               return rv;
+       }
+
+       /**
+        * Checks whether a pair of vertices are structurally equivalent.
+        * Specifically, whether v1's predecessors are equal to v2's predecessors,
+        * and same for successors.
+        * 
+        * @param g the graph in which the structural equivalence comparison is to take place
+        * @param v1 the vertex to check for structural equivalence to v2
+        * @param v2 the vertex to check for structural equivalence to v1
+        */
+       protected boolean isStructurallyEquivalent(Graph<V,?> g, V v1, V v2) {
+               
+               if( g.degree(v1) != g.degree(v2)) {
+                       return false;
+               }
+
+               Set<V> n1 = new HashSet<V>(g.getPredecessors(v1));
+               n1.remove(v2);
+               n1.remove(v1);
+               Set<V> n2 = new HashSet<V>(g.getPredecessors(v2));
+               n2.remove(v1);
+               n2.remove(v2);
+
+               Set<V> o1 = new HashSet<V>(g.getSuccessors(v1));
+               Set<V> o2 = new HashSet<V>(g.getSuccessors(v2));
+               o1.remove(v1);
+               o1.remove(v2);
+               o2.remove(v1);
+               o2.remove(v2);
+
+               // this neglects self-loops and directed edges from 1 to other
+               boolean b = (n1.equals(n2) && o1.equals(o2));
+               if (!b)
+                       return b;
+               
+               // if there's a directed edge v1->v2 then there's a directed edge v2->v1
+               b &= ( g.isSuccessor(v1, v2) == g.isSuccessor(v2, v1));
+               
+               // self-loop check
+               b &= ( g.isSuccessor(v1, v1) == g.isSuccessor(v2, v2));
+
+               return b;
+
+       }
+
+       /**
+        * This is a space for optimizations. For example, for a bipartite graph,
+        * vertices from different partitions cannot possibly be compared.
+        * 
+        * @param v1
+        * @param v2
+        */
+       protected boolean canPossiblyCompare(V v1, V v2) {
+               return true;
+       }
+
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/blockmodel/VertexPartition.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/blockmodel/VertexPartition.java
new file mode 100644 (file)
index 0000000..b5ec583
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+/*
+ * Created on Feb 3, 2004
+ */
+package edu.uci.ics.jung.algorithms.blockmodel;
+
+import java.util.*;
+
+import edu.uci.ics.jung.graph.Graph;
+
+
+/**
+ * Maintains information about a vertex partition of a graph.
+ * This can be built from a map from vertices to vertex sets 
+ * or from a collection of (disjoint) vertex sets,
+ * such as those created by various clustering methods.
+ */
+public class VertexPartition<V,E> 
+{
+       private Map<V,Set<V>> vertex_partition_map;
+       private Collection<Set<V>> vertex_sets;
+       private Graph<V,E> graph;
+       
+       /**
+        * Creates an instance based on the specified graph and mapping from vertices
+        * to vertex sets, and generates a set of partitions based on this mapping.
+        * @param g the graph over which the vertex partition is defined
+        * @param partition_map the mapping from vertices to vertex sets (partitions)
+        */
+       public VertexPartition(Graph<V,E> g, Map<V, Set<V>> partition_map) 
+       {
+               this.vertex_partition_map = Collections.unmodifiableMap(partition_map);
+               this.graph = g;
+       }
+
+       /**
+     * Creates an instance based on the specified graph, vertex-set mapping, 
+     * and set of disjoint vertex sets.  The vertex-set mapping and vertex 
+     * partitions must be consistent; that is, the mapping must reflect the 
+     * division of vertices into partitions, and each vertex must appear in 
+     * exactly one partition.
+     * @param g the graph over which the vertex partition is defined
+     * @param partition_map the mapping from vertices to vertex sets (partitions)
+        * @param vertex_sets the set of disjoint vertex sets 
+        */
+    public VertexPartition(Graph<V,E> g, Map<V, Set<V>> partition_map, 
+               Collection<Set<V>> vertex_sets) 
+    {
+        this.vertex_partition_map = Collections.unmodifiableMap(partition_map);
+        this.vertex_sets = vertex_sets;
+        this.graph = g;
+    }
+
+    /**
+     * Creates an instance based on the specified graph and set of disjoint vertex sets, 
+     * and generates a vertex-to-partition map based on these sets.
+     * @param g the graph over which the vertex partition is defined
+     * @param vertex_sets the set of disjoint vertex sets
+     */
+    public VertexPartition(Graph<V,E> g, Collection<Set<V>> vertex_sets)
+    {
+        this.vertex_sets = vertex_sets;
+        this.graph = g;
+    }
+       
+    /**
+     * Returns the graph on which the partition is defined.
+     * @return the graph on which the partition is defined
+     */
+       public Graph<V,E> getGraph() 
+       {
+               return graph;
+       }
+
+       /**
+        * Returns a map from each vertex in the input graph to its partition.
+        * This map is generated if it does not already exist.
+        * @return a map from each vertex in the input graph to a vertex set
+        */
+       public Map<V,Set<V>> getVertexToPartitionMap() 
+       {
+               if (vertex_partition_map == null)
+               {
+               this.vertex_partition_map = new HashMap<V, Set<V>>();
+               for (Set<V> set : this.vertex_sets)
+                   for (V v : set)
+                       this.vertex_partition_map.put(v, set);
+               }
+               return vertex_partition_map;
+       }
+       
+       /**
+        * Returns a collection of vertex sets, where each vertex in the 
+        * input graph is in exactly one set.
+        * This collection is generated based on the vertex-to-partition map 
+        * if it does not already exist.
+        * @return a collection of vertex sets such that each vertex in the 
+        * instance's graph is in exactly one set
+        */
+       public Collection<Set<V>> getVertexPartitions() 
+       {
+               if (vertex_sets == null)
+               {
+                       this.vertex_sets = new HashSet<Set<V>>();
+                       this.vertex_sets.addAll(vertex_partition_map.values());
+               }
+           return vertex_sets;
+       }
+
+       /**
+        * Returns the number of partitions.
+        */
+       public int numPartitions() 
+       {
+               return vertex_sets.size();
+       }
+       
+       @Override
+       public String toString() 
+       {
+               return "Partitions: " + vertex_partition_map;
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/blockmodel/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/blockmodel/package.html
new file mode 100644 (file)
index 0000000..d1cb06a
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+-->
+</head>
+<body>
+
+Support for establishing and maintaining graph element equivalence (such as in blockmodeling).
+<P/>
+In blockmodeling, groups of vertices are clustered together by similarity 
+(as if members of a "block" appearing on the diagonal of the graph's adjacency 
+matrix).
+<p/>
+This support currently includes:
+<ul>
+<li/><code>VertexPartition</code>: A class that maintains information on a 
+division of the vertices of a graph into disjoint sets.
+<li/><code>StructurallyEquivalent</code>: An algorithm that finds sets of vertices that are 
+structurally equivalent.
+</ul> 
+
+<p/>
+</body>
+</html>
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/BicomponentClusterer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/BicomponentClusterer.java
new file mode 100644 (file)
index 0000000..aa697c7
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.cluster;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.graph.UndirectedGraph;
+
+/**
+ * Finds all biconnected components (bicomponents) of an undirected graph.  
+ * A graph is a biconnected component if 
+ * at least 2 vertices must be removed in order to disconnect the graph.  (Graphs 
+ * consisting of one vertex, or of two connected vertices, are also biconnected.)  Biconnected
+ * components of three or more vertices have the property that every pair of vertices in the component
+ * are connected by two or more vertex-disjoint paths.
+ * <p>
+ * Running time: O(|V| + |E|) where |V| is the number of vertices and |E| is the number of edges
+ * @see "Depth first search and linear graph algorithms by R. E. Tarjan (1972), SIAM J. Comp."
+ * 
+ * @author Joshua O'Madadhain
+ */
+public class BicomponentClusterer<V,E> implements Transformer<UndirectedGraph<V,E>, Set<Set<V>>> 
+{
+    protected Map<V,Number> dfs_num;
+    protected Map<V,Number> high;
+    protected Map<V,V> parents;
+    protected Stack<E> stack;
+    protected int converse_depth;
+
+    /**
+     * Constructs a new bicomponent finder
+     */
+    public BicomponentClusterer() {
+    }
+
+    /**
+    * Extracts the bicomponents from the graph.
+    * @param theGraph the graph whose bicomponents are to be extracted
+    * @return the <code>ClusterSet</code> of bicomponents
+    */
+    public Set<Set<V>> transform(UndirectedGraph<V,E> theGraph) 
+    {
+       Set<Set<V>> bicomponents = new LinkedHashSet<Set<V>>();
+
+        if (theGraph.getVertices().isEmpty())
+            return bicomponents;
+
+        // initialize DFS number for each vertex to 0
+        dfs_num = new HashMap<V,Number>();
+        for (V v : theGraph.getVertices())
+        {
+               dfs_num.put(v, 0);
+        }
+
+        for (V v : theGraph.getVertices())
+        {
+            if (dfs_num.get(v).intValue() == 0) // if we haven't hit this vertex yet...
+            {
+                high = new HashMap<V,Number>();
+                stack = new Stack<E>();
+                parents = new HashMap<V,V>();
+                converse_depth = theGraph.getVertexCount();
+                // find the biconnected components for this subgraph, starting from v
+                findBiconnectedComponents(theGraph, v, bicomponents);
+                
+                // if we only visited one vertex, this method won't have
+                // ID'd it as a biconnected component, so mark it as one
+                if (theGraph.getVertexCount() - converse_depth == 1)
+                {
+                    Set<V> s = new HashSet<V>();
+                    s.add(v);
+                    bicomponents.add(s);
+                }
+            }
+        }
+        
+        return bicomponents;
+    }
+
+    /**
+     * <p>Stores, in <code>bicomponents</code>, all the biconnected
+     * components that are reachable from <code>v</code>.</p>
+     * 
+     * <p>The algorithm basically proceeds as follows: do a depth-first
+     * traversal starting from <code>v</code>, marking each vertex with
+     * a value that indicates the order in which it was encountered (dfs_num), 
+     * and with
+     * a value that indicates the highest point in the DFS tree that is known
+     * to be reachable from this vertex using non-DFS edges (high).  (Since it
+     * is measured on non-DFS edges, "high" tells you how far back in the DFS
+     * tree you can reach by two distinct paths, hence biconnectivity.) 
+     * Each time a new vertex w is encountered, push the edge just traversed
+     * on a stack, and call this method recursively.  If w.high is no greater than
+     * v.dfs_num, then the contents of the stack down to (v,w) is a 
+     * biconnected component (and v is an articulation point, that is, a 
+     * component boundary).  In either case, set v.high to max(v.high, w.high), 
+     * and continue.  If w has already been encountered but is 
+     * not v's parent, set v.high max(v.high, w.dfs_num) and continue. 
+     * 
+     * <p>(In case anyone cares, the version of this algorithm on p. 224 of 
+     * Udi Manber's "Introduction to Algorithms: A Creative Approach" seems to be
+     * wrong: the stack should be initialized outside this method, 
+     * (v,w) should only be put on the stack if w hasn't been seen already,
+     * and there's no real benefit to putting v on the stack separately: just
+     * check for (v,w) on the stack rather than v.  Had I known this, I could
+     * have saved myself a few days.  JRTOM)</p>
+     * 
+     */
+    protected void findBiconnectedComponents(UndirectedGraph<V,E> g, V v, Set<Set<V>> bicomponents)
+    {
+        int v_dfs_num = converse_depth;
+        dfs_num.put(v, v_dfs_num);
+        converse_depth--;
+        high.put(v, v_dfs_num);
+
+        for (V w : g.getNeighbors(v))
+        {
+            int w_dfs_num = dfs_num.get(w).intValue();//get(w, dfs_num);
+            E vw = g.findEdge(v,w);
+            if (w_dfs_num == 0) // w hasn't yet been visited
+            {
+                parents.put(w, v); // v is w's parent in the DFS tree
+                stack.push(vw);
+                findBiconnectedComponents(g, w, bicomponents);
+                int w_high = high.get(w).intValue();//get(w, high);
+                if (w_high <= v_dfs_num)
+                {
+                    // v disconnects w from the rest of the graph,
+                    // i.e., v is an articulation point
+                    // thus, everything between the top of the stack and
+                    // v is part of a single biconnected component
+                    Set<V> bicomponent = new HashSet<V>();
+                    E e;
+                    do
+                    {
+                        e = stack.pop();
+                        bicomponent.addAll(g.getIncidentVertices(e));
+                    }
+                    while (e != vw);
+                    bicomponents.add(bicomponent);
+                }
+                high.put(v, Math.max(w_high, high.get(v).intValue()));
+            }
+            else if (w != parents.get(v)) // (v,w) is a back or a forward edge
+               high.put(v, Math.max(w_dfs_num, high.get(v).intValue()));
+        }
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/EdgeBetweennessClusterer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/EdgeBetweennessClusterer.java
new file mode 100644 (file)
index 0000000..59e4605
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.cluster;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.scoring.BetweennessCentrality;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.Pair;
+
+
+/**
+ * An algorithm for computing clusters (community structure) in graphs based on edge betweenness.
+ * The betweenness of an edge is defined as the extent to which that edge lies along 
+ * shortest paths between all pairs of nodes.
+ *
+ * This algorithm works by iteratively following the 2 step process:
+ * <ul>
+ * <li> Compute edge betweenness for all edges in current graph
+ * <li> Remove edge with highest betweenness
+ * </ul>
+ * <p>
+ * Running time is: O(kmn) where k is the number of edges to remove, m is the total number of edges, and
+ * n is the total number of vertices. For very sparse graphs the running time is closer to O(kn^2) and for
+ * graphs with strong community structure, the complexity is even lower.
+ * <p>
+ * This algorithm is a slight modification of the algorithm discussed below in that the number of edges
+ * to be removed is parameterized.
+ * @author Scott White
+ * @author Tom Nelson (converted to jung2)
+ * @see "Community structure in social and biological networks by Michelle Girvan and Mark Newman"
+ */
+public class EdgeBetweennessClusterer<V,E> implements Transformer<Graph<V,E>,Set<Set<V>>> {
+    private int mNumEdgesToRemove;
+    private Map<E, Pair<V>> edges_removed;
+
+   /**
+    * Constructs a new clusterer for the specified graph.
+    * @param numEdgesToRemove the number of edges to be progressively removed from the graph
+    */
+    public EdgeBetweennessClusterer(int numEdgesToRemove) {
+        mNumEdgesToRemove = numEdgesToRemove;
+        edges_removed = new LinkedHashMap<E, Pair<V>>();
+    }
+
+    /**
+    * Finds the set of clusters which have the strongest "community structure".
+    * The more edges removed the smaller and more cohesive the clusters.
+    * @param graph the graph
+    */
+    public Set<Set<V>> transform(Graph<V,E> graph) {
+                
+        if (mNumEdgesToRemove < 0 || mNumEdgesToRemove > graph.getEdgeCount()) {
+            throw new IllegalArgumentException("Invalid number of edges passed in.");
+        }
+        
+        edges_removed.clear();
+
+        for (int k=0;k<mNumEdgesToRemove;k++) {
+            BetweennessCentrality<V,E> bc = new BetweennessCentrality<V,E>(graph);
+            E to_remove = null;
+            double score = 0;
+            for (E e : graph.getEdges())
+                if (bc.getEdgeScore(e) > score)
+                {
+                    to_remove = e;
+                    score = bc.getEdgeScore(e);
+                }
+            edges_removed.put(to_remove, graph.getEndpoints(to_remove));
+            graph.removeEdge(to_remove);
+        }
+
+        WeakComponentClusterer<V,E> wcSearch = new WeakComponentClusterer<V,E>();
+        Set<Set<V>> clusterSet = wcSearch.transform(graph);
+
+        for (Map.Entry<E, Pair<V>> entry : edges_removed.entrySet())
+        {
+            Pair<V> endpoints = entry.getValue();
+            graph.addEdge(entry.getKey(), endpoints.getFirst(), endpoints.getSecond());
+        }
+        return clusterSet;
+    }
+
+    /**
+     * Retrieves the list of all edges that were removed 
+     * (assuming extract(...) was previously called).  
+     * The edges returned
+     * are stored in order in which they were removed.
+     * 
+     * @return the edges in the original graph
+     */
+    public List<E> getEdgesRemoved() 
+    {
+        return new ArrayList<E>(edges_removed.keySet());
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/VoltageClusterer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/VoltageClusterer.java
new file mode 100644 (file)
index 0000000..859c063
--- /dev/null
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2004, the JUNG Project and the Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ *
+ * Created on Aug 12, 2004
+ */
+package edu.uci.ics.jung.algorithms.cluster;
+
+import edu.uci.ics.jung.algorithms.scoring.VoltageScorer;
+import edu.uci.ics.jung.algorithms.util.DiscreteDistribution;
+import edu.uci.ics.jung.algorithms.util.KMeansClusterer;
+import edu.uci.ics.jung.algorithms.util.KMeansClusterer.NotEnoughClustersException;
+import edu.uci.ics.jung.graph.Graph;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+
+/**
+ * <p>Clusters vertices of a <code>Graph</code> based on their ranks as
+ * calculated by <code>VoltageScorer</code>.  This algorithm is based on,
+ * but not identical with, the method described in the paper below.
+ * The primary difference is that Wu and Huberman assume a priori that the clusters
+ * are of approximately the same size, and therefore use a more complex
+ * method than k-means (which is used here) for determining cluster
+ * membership based on co-occurrence data.</p>
+ *
+ * <p>The algorithm proceeds as follows:
+ * <ul>
+ * <li/>first, generate a set of candidate clusters as follows:
+ *      <ul>
+ *      <li/>pick (widely separated) vertex pair, run VoltageScorer
+ *      <li/>group the vertices in two clusters according to their voltages
+ *      <li/>store resulting candidate clusters
+ *      </ul>
+ * <li/>second, generate k-1 clusters as follows:
+ *      <ul>
+ *      <li/>pick a vertex v as a cluster 'seed'
+ *           <br>(Wu/Huberman: most frequent vertex in candidate clusters)
+ *      <li/>calculate co-occurrence over all candidate clusters of v with each other
+ *           vertex
+ *      <li/>separate co-occurrence counts into high/low;
+ *           high vertices constitute a cluster
+ *      <li/>remove v's vertices from candidate clusters; continue
+ *      </ul>
+ * <li/>finally, remaining unassigned vertices are assigned to the kth ("garbage")
+ * cluster.
+ * </ul></p>
+ *
+ * <p><b>NOTE</b>: Depending on how the co-occurrence data splits the data into
+ * clusters, the number of clusters returned by this algorithm may be less than the
+ * number of clusters requested.  The number of clusters will never be more than
+ * the number requested, however.</p>
+ *
+ * @author Joshua O'Madadhain
+ * @see "'Finding communities in linear time: a physics approach', Fang Wu and Bernardo Huberman, http://www.hpl.hp.com/research/idl/papers/linear/"
+ * @see VoltageScorer
+ * @see KMeansClusterer
+ */
+public class VoltageClusterer<V,E>
+{
+    protected int num_candidates;
+    protected KMeansClusterer<V> kmc;
+    protected Random rand;
+    protected Graph<V,E> g;
+
+    /**
+     * Creates an instance of a VoltageCluster with the specified parameters.
+     * These are mostly parameters that are passed directly to VoltageScorer
+     * and KMeansClusterer.
+     *
+     * @param num_candidates    the number of candidate clusters to create
+     */
+    public VoltageClusterer(Graph<V,E> g, int num_candidates)
+    {
+        if (num_candidates < 1)
+            throw new IllegalArgumentException("must generate >=1 candidates");
+
+        this.num_candidates = num_candidates;
+        this.kmc = new KMeansClusterer<V>();
+        rand = new Random();
+        this.g = g;
+    }
+
+    protected void setRandomSeed(int random_seed)
+    {
+        rand = new Random(random_seed);
+    }
+
+    /**
+     * Returns a community (cluster) centered around <code>v</code>.
+     * @param v the vertex whose community we wish to discover
+     */
+    public Collection<Set<V>> getCommunity(V v)
+    {
+        return cluster_internal(v, 2);
+    }
+
+    /**
+     * Clusters the vertices of <code>g</code> into
+     * <code>num_clusters</code> clusters, based on their connectivity.
+     * @param num_clusters  the number of clusters to identify
+     */
+    public Collection<Set<V>> cluster(int num_clusters)
+    {
+        return cluster_internal(null, num_clusters);
+    }
+
+    /**
+     * Does the work of <code>getCommunity</code> and <code>cluster</code>.
+     * @param origin the vertex around which clustering is to be done
+     * @param num_clusters the (maximum) number of clusters to find
+     */
+    protected Collection<Set<V>> cluster_internal(V origin, int num_clusters)
+    {
+        // generate candidate clusters
+        // repeat the following 'samples' times:
+        // * pick (widely separated) vertex pair, run VoltageScorer
+        // * use k-means to identify 2 communities in ranked graph
+        // * store resulting candidate communities
+        ArrayList<V> v_array = new ArrayList<V>(g.getVertices());
+
+        LinkedList<Set<V>> candidates = new LinkedList<Set<V>>();
+
+        for (int j = 0; j < num_candidates; j++)
+        {
+            V source;
+            if (origin == null)
+                source = v_array.get((int)(rand.nextDouble() * v_array.size()));
+            else
+                source = origin;
+            V target = null;
+            do
+            {
+                target = v_array.get((int)(rand.nextDouble() * v_array.size()));
+            }
+            while (source == target);
+            VoltageScorer<V,E> vs = new VoltageScorer<V,E>(g, source, target);
+            vs.evaluate();
+
+            Map<V, double[]> voltage_ranks = new HashMap<V, double[]>();
+            for (V v : g.getVertices())
+                voltage_ranks.put(v, new double[] {vs.getVertexScore(v)});
+
+//            addOneCandidateCluster(candidates, voltage_ranks);
+            addTwoCandidateClusters(candidates, voltage_ranks);
+        }
+
+        // repeat the following k-1 times:
+        // * pick a vertex v as a cluster seed
+        //   (Wu/Huberman: most frequent vertex in candidates)
+        // * calculate co-occurrence (in candidate clusters)
+        //   of this vertex with all others
+        // * use k-means to separate co-occurrence counts into high/low;
+        //   high vertices are a cluster
+        // * remove v's vertices from candidate clusters
+
+        Collection<Set<V>> clusters = new LinkedList<Set<V>>();
+        Set<V> remaining = new HashSet<V>(g.getVertices());
+
+        List<V> seed_candidates = getSeedCandidates(candidates);
+        int seed_index = 0;
+
+        for (int j = 0; j < (num_clusters - 1); j++)
+        {
+            if (remaining.isEmpty())
+                break;
+
+            V seed;
+            if (seed_index == 0 && origin != null)
+                seed = origin;
+            else
+            {
+                do { seed = seed_candidates.get(seed_index++); }
+                while (!remaining.contains(seed));
+            }
+
+            Map<V, double[]> occur_counts = getObjectCounts(candidates, seed);
+            if (occur_counts.size() < 2)
+                break;
+
+            // now that we have the counts, cluster them...
+            try
+            {
+                Collection<Map<V, double[]>> high_low = kmc.cluster(occur_counts, 2);
+                // ...get the cluster with the highest-valued centroid...
+                Iterator<Map<V, double[]>> h_iter = high_low.iterator();
+                Map<V, double[]> cluster1 = h_iter.next();
+                Map<V, double[]> cluster2 = h_iter.next();
+                double[] centroid1 = DiscreteDistribution.mean(cluster1.values());
+                double[] centroid2 = DiscreteDistribution.mean(cluster2.values());
+                Set<V> new_cluster;
+                if (centroid1[0] >= centroid2[0])
+                    new_cluster = cluster1.keySet();
+                else
+                    new_cluster = cluster2.keySet();
+
+                // ...remove the elements of new_cluster from each candidate...
+                for (Set<V> cluster : candidates)
+                    cluster.removeAll(new_cluster);
+                clusters.add(new_cluster);
+                remaining.removeAll(new_cluster);
+            }
+            catch (NotEnoughClustersException nece)
+            {
+                // all remaining vertices are in the same cluster
+                break;
+            }
+        }
+
+        // identify remaining vertices (if any) as a 'garbage' cluster
+        if (!remaining.isEmpty())
+            clusters.add(remaining);
+
+        return clusters;
+    }
+
+    /**
+     * Do k-means with three intervals and pick the
+     * smaller two clusters (presumed to be on the ends); this is closer to the Wu-Huberman method.
+     * @param candidates
+     * @param voltage_ranks
+     */
+    protected void addTwoCandidateClusters(LinkedList<Set<V>> candidates,
+            Map<V, double[]> voltage_ranks)
+    {
+        try
+        {
+            List<Map<V, double[]>> clusters = new ArrayList<Map<V, double[]>>(kmc.cluster(voltage_ranks, 3));
+            boolean b01 = clusters.get(0).size() > clusters.get(1).size();
+            boolean b02 = clusters.get(0).size() > clusters.get(2).size();
+            boolean b12 = clusters.get(1).size() > clusters.get(2).size();
+            if (b01 && b02)
+            {
+                candidates.add(clusters.get(1).keySet());
+                candidates.add(clusters.get(2).keySet());
+            }
+            else if (!b01 && b12)
+            {
+                candidates.add(clusters.get(0).keySet());
+                candidates.add(clusters.get(2).keySet());
+            }
+            else if (!b02 && !b12)
+            {
+                candidates.add(clusters.get(0).keySet());
+                candidates.add(clusters.get(1).keySet());
+            }
+        }
+        catch (NotEnoughClustersException e)
+        {
+            // no valid candidates, continue
+        }
+    }
+
+    /**
+     * alternative to addTwoCandidateClusters(): cluster vertices by voltages into 2 clusters.
+     * We only consider the smaller of the two clusters returned
+     * by k-means to be a 'true' cluster candidate; the other is a garbage cluster.
+     * @param candidates
+     * @param voltage_ranks
+     */
+    protected void addOneCandidateCluster(LinkedList<Set<V>> candidates,
+            Map<V, double[]> voltage_ranks)
+    {
+        try
+        {
+            List<Map<V, double[]>> clusters;
+            clusters = new ArrayList<Map<V, double[]>>(kmc.cluster(voltage_ranks, 2));
+            if (clusters.get(0).size() < clusters.get(1).size())
+                candidates.add(clusters.get(0).keySet());
+            else
+                candidates.add(clusters.get(1).keySet());
+        }
+        catch (NotEnoughClustersException e)
+        {
+            // no valid candidates, continue
+        }
+    }
+
+    /**
+     * Returns an array of cluster seeds, ranked in decreasing order
+     * of number of appearances in the specified collection of candidate
+     * clusters.
+     * @param candidates
+     */
+    protected List<V> getSeedCandidates(Collection<Set<V>> candidates)
+    {
+        final Map<V, double[]> occur_counts = getObjectCounts(candidates, null);
+
+        ArrayList<V> occurrences = new ArrayList<V>(occur_counts.keySet());
+        Collections.sort(occurrences, new MapValueArrayComparator(occur_counts));
+
+        System.out.println("occurrences: ");
+        for (int i = 0; i < occurrences.size(); i++)
+            System.out.println(occur_counts.get(occurrences.get(i))[0]);
+
+        return occurrences;
+    }
+
+    protected Map<V, double[]> getObjectCounts(Collection<Set<V>> candidates, V seed)
+    {
+        Map<V, double[]> occur_counts = new HashMap<V, double[]>();
+        for (V v : g.getVertices())
+            occur_counts.put(v, new double[]{0});
+
+        for (Set<V> candidate : candidates)
+        {
+            if (seed == null)
+                System.out.println(candidate.size());
+            if (seed == null || candidate.contains(seed))
+            {
+                for (V element : candidate)
+                {
+                    double[] count = occur_counts.get(element);
+                    count[0]++;
+                }
+            }
+        }
+
+        if (seed == null)
+        {
+            System.out.println("occur_counts size: " + occur_counts.size());
+            for (V v : occur_counts.keySet())
+                System.out.println(occur_counts.get(v)[0]);
+        }
+
+        return occur_counts;
+    }
+
+    protected class MapValueArrayComparator implements Comparator<V>
+    {
+        private Map<V, double[]> map;
+
+        protected MapValueArrayComparator(Map<V, double[]> map)
+        {
+            this.map = map;
+        }
+
+        public int compare(V o1, V o2)
+        {
+            double[] count0 = map.get(o1);
+            double[] count1 = map.get(o2);
+            if (count0[0] < count1[0])
+                return 1;
+            else if (count0[0] > count1[0])
+                return -1;
+            return 0;
+        }
+
+    }
+
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/WeakComponentClusterer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/WeakComponentClusterer.java
new file mode 100644 (file)
index 0000000..cb79a78
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.cluster;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.collections15.Buffer;
+import org.apache.commons.collections15.Transformer;
+import org.apache.commons.collections15.buffer.UnboundedFifoBuffer;
+
+import edu.uci.ics.jung.graph.Graph;
+
+
+
+/**
+ * Finds all weak components in a graph as sets of vertex sets.  A weak component is defined as
+ * a maximal subgraph in which all pairs of vertices in the subgraph are reachable from one
+ * another in the underlying undirected subgraph.
+ * <p>This implementation identifies components as sets of vertex sets.  
+ * To create the induced graphs from any or all of these vertex sets, 
+ * see <code>algorithms.filters.FilterUtils</code>.
+ * <p>
+ * Running time: O(|V| + |E|) where |V| is the number of vertices and |E| is the number of edges.
+ * @author Scott White
+ */
+public class WeakComponentClusterer<V,E> implements Transformer<Graph<V,E>, Set<Set<V>>> 
+{
+       /**
+     * Extracts the weak components from a graph.
+     * @param graph the graph whose weak components are to be extracted
+     * @return the list of weak components
+     */
+    public Set<Set<V>> transform(Graph<V,E> graph) {
+
+        Set<Set<V>> clusterSet = new HashSet<Set<V>>();
+
+        HashSet<V> unvisitedVertices = new HashSet<V>(graph.getVertices());
+
+        while (!unvisitedVertices.isEmpty()) {
+               Set<V> cluster = new HashSet<V>();
+            V root = unvisitedVertices.iterator().next();
+            unvisitedVertices.remove(root);
+            cluster.add(root);
+
+            Buffer<V> queue = new UnboundedFifoBuffer<V>();
+            queue.add(root);
+
+            while (!queue.isEmpty()) {
+                V currentVertex = queue.remove();
+                Collection<V> neighbors = graph.getNeighbors(currentVertex);
+
+                for(V neighbor : neighbors) {
+                    if (unvisitedVertices.contains(neighbor)) {
+                        queue.add(neighbor);
+                        unvisitedVertices.remove(neighbor);
+                        cluster.add(neighbor);
+                    }
+                }
+            }
+            clusterSet.add(cluster);
+        }
+        return clusterSet;
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/cluster/package.html
new file mode 100644 (file)
index 0000000..f8bdb22
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+-->
+</head>
+<body>
+
+Mechanisms for identifying clusters in graphs.  Where these clusters define disjoint sets of vertices, 
+they may be used to define a <code>VertexPartition</code> for more convenient manipulation of the vertex/set
+relationships.
+
+Current clustering algorithms include:
+<ul>
+<li/><code>BicomponentClusterer</code>: finds all subsets of vertices for which at least
+2 vertices must be removed in order to disconnect the induced subgraphs.
+<li/><code>EdgeBetweennessClusterer</code>: identifies vertex clusters by removing the edges of the highest
+'betweenness' scores (see the importance/scoring package).
+<li/><code>VoltageClusterer</code>: Clusters vertices based on their ranks as 
+calculated by <code>VoltageRanker</code>. 
+<li/><code>WeakComponentVertexClusterer</code>: Clusters vertices based on their membership in weakly 
+connected components of a graph.
+</ul>
+
+
+</body>
+</html>
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/EdgePredicateFilter.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/EdgePredicateFilter.java
new file mode 100644 (file)
index 0000000..5e3be06
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Created on May 19, 2008
+ *
+ * Copyright (c) 2008, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.filters;
+
+import org.apache.commons.collections15.Predicate;
+
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * Transforms the input graph into one which contains only those edges 
+ * that pass the specified <code>Predicate</code>.  The filtered graph
+ * is a copy of the original graph (same type, uses the same vertex and
+ * edge objects).  All vertices from the original graph
+ * are copied into the new graph (even if they are not incident to any
+ * edges in the new graph).
+ * 
+ * @author Joshua O'Madadhain
+ */
+public class EdgePredicateFilter<V, E> implements Filter<V, E>
+{
+    protected Predicate<E> edge_pred;
+
+    /**
+     * Creates an instance based on the specified edge <code>Predicate</code>.
+     * @param edge_pred   the predicate that specifies which edges to add to the filtered graph
+     */
+    public EdgePredicateFilter(Predicate<E> edge_pred)
+    {
+        this.edge_pred = edge_pred;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public Graph<V,E> transform(Graph<V,E> g)
+    {
+        Graph<V, E> filtered;
+        try
+        {
+            filtered = g.getClass().newInstance();
+        }
+        catch (InstantiationException e)
+        {
+            throw new RuntimeException("Unable to create copy of existing graph: ", e);
+        }
+        catch (IllegalAccessException e)
+        {
+            throw new RuntimeException("Unable to create copy of existing graph: ", e);
+        }
+
+        for (V v : g.getVertices())
+            filtered.addVertex(v);
+        
+        for (E e : g.getEdges())
+        {
+            if (edge_pred.evaluate(e))
+                filtered.addEdge(e, g.getIncidentVertices(e));
+        }
+        
+        return filtered;
+    }
+
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/Filter.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/Filter.java
new file mode 100644 (file)
index 0000000..a62895c
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.filters;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.graph.Graph;
+
+
+
+/**
+ * An interface for classes that return a subset of the input <code>Graph</code>
+ * as a <code>Graph</code>.  The <code>Graph</code> returned may be either a
+ * new graph or a view into an existing graph; the documentation for the filter
+ * must specify which.
+ * 
+ * @author danyelf
+ */
+public interface Filter<V,E> extends Transformer<Graph<V,E>, Graph<V,E>>{ }
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/FilterUtils.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/FilterUtils.java
new file mode 100644 (file)
index 0000000..4845c0f
--- /dev/null
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2008, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ * Created on Jun 7, 2008
+ * 
+ */
+package edu.uci.ics.jung.algorithms.filters;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * Utility methods relating to filtering.
+ */
+public class FilterUtils 
+{
+       /**
+        * Creates the induced subgraph from <code>graph</code> whose vertex set
+        * is equal to <code>vertices</code>.  The graph returned has 
+        * <code>vertices</code> as its vertex set, and includes all edges from
+        * <code>graph</code> which are incident only to elements of 
+        * <code>vertices</code>.
+        * 
+        * @param <V> the vertex type
+        * @param <E> the edge type
+        * @param vertices the subset of <code>graph</code>'s vertices around 
+        * which the subgraph is to be constructed
+        * @param graph the graph whose subgraph is to be constructed
+        * @return the subgraph induced by <code>vertices</code>
+        * @throws IllegalArgumentException if any vertex in 
+        * <code>vertices</code> is not in <code>graph</code>
+        */
+       @SuppressWarnings("unchecked")
+       public static <V,E,G extends Hypergraph<V,E>> G createInducedSubgraph(Collection<V> 
+               vertices, G graph)
+       {
+               G subgraph = null;
+               try 
+               {
+                       subgraph = (G)graph.getClass().newInstance();
+                       
+                       for (V v : vertices)
+                       {
+                               if (!graph.containsVertex(v))
+                                       throw new IllegalArgumentException("Vertex " + v + 
+                                               " is not an element of " + graph);
+                               subgraph.addVertex(v);
+                       }
+
+                       for (E e : graph.getEdges())
+                       {
+                               Collection<V> incident = graph.getIncidentVertices(e);
+                               if (vertices.containsAll(incident))
+                                       subgraph.addEdge(e, incident, graph.getEdgeType(e));
+                       }
+               } 
+        catch (InstantiationException e)
+        {
+            throw new RuntimeException("Unable to create copy of existing graph: ", e);
+        }
+        catch (IllegalAccessException e)
+        {
+            throw new RuntimeException("Unable to create copy of existing graph: ", e);
+        }
+               return subgraph;
+       }
+       
+       /**
+        * Creates the induced subgraphs of <code>graph</code> associated with each 
+        * element of <code>vertex_collections</code>.
+        * Note that these vertex collections need not be disjoint.
+        * @param <V> the vertex type
+        * @param <E> the edge type
+        * @param vertex_collections the collections of vertex collections to be
+        * used to induce the subgraphs
+        * @param graph the graph whose subgraphs are to be created
+        * @return the induced subgraphs of <code>graph</code> associated with each 
+        * element of <code>vertex_collections</code>
+        */
+       public static <V,E,G extends Hypergraph<V,E>> Collection<G> 
+               createAllInducedSubgraphs(Collection<? extends Collection<V>> 
+                       vertex_collections, G graph)
+       {
+               Collection<G> subgraphs = new ArrayList<G>();
+               
+               for (Collection<V> vertex_set : vertex_collections)
+                       subgraphs.add(createInducedSubgraph(vertex_set, graph));
+               
+               return subgraphs;
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/KNeighborhoodFilter.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/KNeighborhoodFilter.java
new file mode 100644 (file)
index 0000000..62bcfc2
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+/*
+ * Created on Dec 26, 2001
+ *
+ */
+package edu.uci.ics.jung.algorithms.filters;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import edu.uci.ics.jung.algorithms.filters.Filter;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.Pair;
+
+/**
+ * A filter used to extract the k-neighborhood around one or more root node(s).
+ * The k-neighborhood is defined as the subgraph induced by the set of 
+ * vertices that are k or fewer hops (unweighted shortest-path distance)
+ * away from the root node.
+ * 
+ * @author Danyel Fisher
+ */
+public class KNeighborhoodFilter<V,E> implements Filter<V,E> {
+
+       /**
+        * The type of edge to follow for defining the neighborhood.
+        */
+       public static enum EdgeType { IN_OUT, IN, OUT }
+       private Set<V> rootNodes;
+       private int radiusK;
+       private EdgeType edgeType;
+       
+       /**
+        * Constructs a new instance of the filter.
+        * @param rootNodes the set of root nodes
+        * @param radiusK the neighborhood radius around the root set
+        * @param edgeType 0 for in/out edges, 1 for in-edges, 2  for out-edges
+        */
+       public KNeighborhoodFilter(Set<V> rootNodes, int radiusK, EdgeType edgeType) {
+               this.rootNodes = rootNodes;
+               this.radiusK = radiusK;
+               this.edgeType = edgeType;
+       }
+       
+       /**
+        * Constructs a new instance of the filter.
+        * @param rootNode the root node
+        * @param radiusK the neighborhood radius around the root set
+        * @param edgeType 0 for in/out edges, 1 for in-edges, 2  for out-edges
+        */
+       public KNeighborhoodFilter(V rootNode, int radiusK, EdgeType edgeType) {
+               this.rootNodes = new HashSet<V>();
+               this.rootNodes.add(rootNode);
+               this.radiusK = radiusK;
+               this.edgeType = edgeType;
+       }
+       
+       /**
+        * Constructs an unassembled graph containing the k-neighborhood around the root node(s).
+        */
+       @SuppressWarnings("unchecked")
+       public Graph<V,E> transform(Graph<V,E> graph) {
+               // generate a Set of Vertices we want
+               // add all to the UG
+               int currentDepth = 0;
+               List<V> currentVertices = new ArrayList<V>();
+               Set<V> visitedVertices = new HashSet<V>();
+               Set<E> visitedEdges = new HashSet<E>();
+               Set<V> acceptedVertices = new HashSet<V>();
+               //Copy, mark, and add all the root nodes to the new subgraph
+               for (V currentRoot : rootNodes) {
+
+                       visitedVertices.add(currentRoot);
+                       acceptedVertices.add(currentRoot);
+                       currentVertices.add(currentRoot);
+               }
+               ArrayList<V> newVertices = null;
+               //Use BFS to locate the neighborhood around the root nodes within distance k
+               while (currentDepth < radiusK) {
+                       newVertices = new ArrayList<V>();
+                       for (V currentVertex : currentVertices) {
+
+                               Collection<E> edges = null;
+                               switch (edgeType) {
+                                       case IN_OUT :
+                                               edges = graph.getIncidentEdges(currentVertex);
+                                               break;
+                                       case IN :
+                                               edges = graph.getInEdges(currentVertex);
+                                               break;
+                                       case OUT :
+                                               edges = graph.getOutEdges(currentVertex);
+                                               break;
+                               }
+                               for (E currentEdge : edges) {
+
+                                       V currentNeighbor =
+                                               graph.getOpposite(currentVertex, currentEdge);
+                                       if (!visitedEdges.contains(currentEdge)) {
+                                               visitedEdges.add(currentEdge);
+                                               if (!visitedVertices.contains(currentNeighbor)) {
+                                                       visitedVertices.add(currentNeighbor);
+                                                       acceptedVertices.add(currentNeighbor);
+                                                       newVertices.add(currentNeighbor);
+                                               }
+                                       }
+                               }
+                       }
+                       currentVertices = newVertices;
+                       currentDepth++;
+               }
+               Graph<V,E> ug = null;
+               try {
+                       ug = graph.getClass().newInstance();
+                       for(E edge : graph.getEdges()) {
+                               Pair<V> endpoints = graph.getEndpoints(edge);
+                               if(acceptedVertices.containsAll(endpoints)) {
+                                       ug.addEdge(edge, endpoints.getFirst(), endpoints.getSecond());
+                               }
+                       }
+               } 
+        catch (InstantiationException e)
+        {
+            throw new RuntimeException("Unable to create copy of existing graph: ", e);
+        }
+        catch (IllegalAccessException e)
+        {
+            throw new RuntimeException("Unable to create copy of existing graph: ", e);
+        }
+               return ug;
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/VertexPredicateFilter.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/VertexPredicateFilter.java
new file mode 100644 (file)
index 0000000..4543b42
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Created on May 19, 2008
+ *
+ * Copyright (c) 2008, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.filters;
+
+import java.util.Collection;
+
+import org.apache.commons.collections15.Predicate;
+
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * Transforms the input graph into one which contains only those vertices 
+ * that pass the specified <code>Predicate</code>.  The filtered graph
+ * is a copy of the original graph (same type, uses the same vertex and
+ * edge objects).  Only those edges whose entire incident vertex collection
+ * passes the predicate are copied into the new graph.
+ * 
+ * @author Joshua O'Madadhain
+ */
+public class VertexPredicateFilter<V,E> implements Filter<V,E>
+{
+    protected Predicate<V> vertex_pred;
+
+    /**
+     * Creates an instance based on the specified vertex <code>Predicate</code>.
+     * @param vertex_pred   the predicate that specifies which vertices to add to the filtered graph
+     */
+    public VertexPredicateFilter(Predicate<V> vertex_pred)
+    {
+        this.vertex_pred = vertex_pred;
+    }
+    
+    @SuppressWarnings("unchecked")
+       public Graph<V,E> transform(Graph<V,E> g)
+    {
+        Graph<V, E> filtered;
+        try
+        {
+            filtered = g.getClass().newInstance();
+        }
+        catch (InstantiationException e)
+        {
+            throw new RuntimeException("Unable to create copy of existing graph: ", e);
+        }
+        catch (IllegalAccessException e)
+        {
+            throw new RuntimeException("Unable to create copy of existing graph: ", e);
+        }
+
+        for (V v : g.getVertices())
+            if (vertex_pred.evaluate(v))
+                filtered.addVertex(v);
+        
+        Collection<V> filtered_vertices = filtered.getVertices();
+        
+        for (E e : g.getEdges())
+        {
+            Collection<V> incident = g.getIncidentVertices(e);
+            if (filtered_vertices.containsAll(incident))
+                filtered.addEdge(e, incident);
+        }
+        
+        return filtered;
+    }
+
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/filters/package.html
new file mode 100644 (file)
index 0000000..0f9a018
--- /dev/null
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2008 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 
+-->
+</head>
+<body>
+
+Filtering mechanisms that produce subgraphs of an original graph. 
+Currently includes:
+<ul>
+<li/><code>Filter</code>: an interface for graph filters
+<li/><code>{Edge,Vertex}PredicateFilter</code>: graph filters that return the 
+induced subgraph according to the
+specified edge or vertex <code>Predicate</code>, respectively.
+<li/><code>KNeighborhoodFilter</code>: a filter that returns the subgraph 
+induced by vertices within (unweighted) distance k of a specified vertex.
+</ul>
+
+
+</body>
+</html>
+
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/flows/EdmondsKarpMaxFlow.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/flows/EdmondsKarpMaxFlow.java
new file mode 100644 (file)
index 0000000..af9ee34
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.flows;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections15.Buffer;
+import org.apache.commons.collections15.Factory;
+import org.apache.commons.collections15.Transformer;
+import org.apache.commons.collections15.buffer.UnboundedFifoBuffer;
+
+import edu.uci.ics.jung.algorithms.util.IterativeProcess;
+import edu.uci.ics.jung.graph.DirectedGraph;
+import edu.uci.ics.jung.graph.util.EdgeType;
+
+
+/**
+ * Implements the Edmonds-Karp maximum flow algorithm for solving the maximum flow problem. 
+ * After the algorithm is executed,
+ * the input {@code Map} is populated with a {@code Number} for each edge that indicates 
+ * the flow along that edge.
+ * <p>
+ * An example of using this algorithm is as follows:
+ * <pre>
+ * EdmondsKarpMaxFlow ek = new EdmondsKarpMaxFlow(graph, source, sink, edge_capacities, edge_flows, 
+ * edge_factory);
+ * ek.evaluate(); // This instructs the class to compute the max flow
+ * </pre>
+ *
+ * @see "Introduction to Algorithms by Cormen, Leiserson, Rivest, and Stein."
+ * @see "Network Flows by Ahuja, Magnanti, and Orlin."
+ * @see "Theoretical improvements in algorithmic efficiency for network flow problems by Edmonds and Karp, 1972."
+ * @author Scott White, adapted to jung2 by Tom Nelson
+ */
+public class EdmondsKarpMaxFlow<V,E> extends IterativeProcess {
+
+    private DirectedGraph<V,E> mFlowGraph;
+    private DirectedGraph<V,E> mOriginalGraph;
+    private V source;
+    private V target;
+    private int mMaxFlow;
+    private Set<V> mSourcePartitionNodes;
+    private Set<V> mSinkPartitionNodes;
+    private Set<E> mMinCutEdges;
+    
+    private Map<E,Number> residualCapacityMap = new HashMap<E,Number>();
+    private Map<V,V> parentMap = new HashMap<V,V>();
+    private Map<V,Number> parentCapacityMap = new HashMap<V,Number>();
+    private Transformer<E,Number> edgeCapacityTransformer;
+    private Map<E,Number> edgeFlowMap;
+    private Factory<E> edgeFactory;
+
+    /**
+     * Constructs a new instance of the algorithm solver for a given graph, source, and sink.
+     * Source and sink vertices must be elements of the specified graph, and must be 
+     * distinct.
+     * @param directedGraph the flow graph
+     * @param source the source vertex
+     * @param sink the sink vertex
+     * @param edgeCapacityTransformer the transformer that gets the capacity for each edge.
+     * @param edgeFlowMap the map where the solver will place the value of the flow for each edge
+     * @param edgeFactory used to create new edge instances for backEdges
+     */
+    @SuppressWarnings("unchecked")
+    public EdmondsKarpMaxFlow(DirectedGraph<V,E> directedGraph, V source, V sink, 
+               Transformer<E,Number> edgeCapacityTransformer, Map<E,Number> edgeFlowMap,
+               Factory<E> edgeFactory) {
+       
+       if(directedGraph.getVertices().contains(source) == false ||
+                       directedGraph.getVertices().contains(sink) == false) {
+            throw new IllegalArgumentException("source and sink vertices must be elements of the specified graph");
+       }
+        if (source.equals(sink)) {
+            throw new IllegalArgumentException("source and sink vertices must be distinct");
+        }
+        mOriginalGraph = directedGraph;
+
+        this.source = source;
+        this.target = sink;
+        this.edgeFlowMap = edgeFlowMap;
+        this.edgeCapacityTransformer = edgeCapacityTransformer;
+        this.edgeFactory = edgeFactory;
+        try {
+                       mFlowGraph = directedGraph.getClass().newInstance();
+                       for(E e : mOriginalGraph.getEdges()) {
+                               mFlowGraph.addEdge(e, mOriginalGraph.getSource(e), 
+                                               mOriginalGraph.getDest(e), EdgeType.DIRECTED);
+                       }
+                       for(V v : mOriginalGraph.getVertices()) {
+                               mFlowGraph.addVertex(v);
+                       }
+
+               } catch (InstantiationException e) {
+                       e.printStackTrace();
+               } catch (IllegalAccessException e) {
+                       e.printStackTrace();
+               }
+        mMaxFlow = 0;
+        mSinkPartitionNodes = new HashSet<V>();
+        mSourcePartitionNodes = new HashSet<V>();
+        mMinCutEdges = new HashSet<E>();
+    }
+
+    private void clearParentValues() {
+       parentMap.clear();
+       parentCapacityMap.clear();
+        parentCapacityMap.put(source, Integer.MAX_VALUE);
+        parentMap.put(source, source);
+    }
+
+    protected boolean hasAugmentingPath() {
+
+        mSinkPartitionNodes.clear();
+        mSourcePartitionNodes.clear();
+        mSinkPartitionNodes.addAll(mFlowGraph.getVertices());
+
+        Set<E> visitedEdgesMap = new HashSet<E>();
+        Buffer<V> queue = new UnboundedFifoBuffer<V>();
+        queue.add(source);
+
+        while (!queue.isEmpty()) {
+            V currentVertex = queue.remove();
+            mSinkPartitionNodes.remove(currentVertex);
+            mSourcePartitionNodes.add(currentVertex);
+            Number currentCapacity = parentCapacityMap.get(currentVertex);
+
+            Collection<E> neighboringEdges = mFlowGraph.getOutEdges(currentVertex);
+            
+            for (E neighboringEdge : neighboringEdges) {
+
+                V neighboringVertex = mFlowGraph.getDest(neighboringEdge);
+
+                Number residualCapacity = residualCapacityMap.get(neighboringEdge);
+                if (residualCapacity.intValue() <= 0 || visitedEdgesMap.contains(neighboringEdge))
+                    continue;
+
+                V neighborsParent = parentMap.get(neighboringVertex);
+                Number neighborCapacity = parentCapacityMap.get(neighboringVertex);
+                int newCapacity = Math.min(residualCapacity.intValue(),currentCapacity.intValue());
+
+                if ((neighborsParent == null) || newCapacity > neighborCapacity.intValue()) {
+                    parentMap.put(neighboringVertex, currentVertex);
+                    parentCapacityMap.put(neighboringVertex, new Integer(newCapacity));
+                    visitedEdgesMap.add(neighboringEdge);
+                    if (neighboringVertex != target) {
+                       queue.add(neighboringVertex);
+                    }
+                }
+            }
+        }
+
+        boolean hasAugmentingPath = false;
+        Number targetsParentCapacity = parentCapacityMap.get(target);
+        if (targetsParentCapacity != null && targetsParentCapacity.intValue() > 0) {
+            updateResidualCapacities();
+            hasAugmentingPath = true;
+        }
+        clearParentValues();
+        return hasAugmentingPath;
+    }
+
+     @Override
+    public void step() {
+        while (hasAugmentingPath()) {
+        }
+        computeMinCut();
+//        return 0;
+    }
+
+    private void computeMinCut() {
+
+        for (E e : mOriginalGraph.getEdges()) {
+
+               V source = mOriginalGraph.getSource(e);
+               V destination = mOriginalGraph.getDest(e);
+            if (mSinkPartitionNodes.contains(source) && mSinkPartitionNodes.contains(destination)) {
+                continue;
+            }
+            if (mSourcePartitionNodes.contains(source) && mSourcePartitionNodes.contains(destination)) {
+                continue;
+            }
+            if (mSinkPartitionNodes.contains(source) && mSourcePartitionNodes.contains(destination)) {
+                continue;
+            }
+            mMinCutEdges.add(e);
+        }
+    }
+
+    /**
+     * Returns the value of the maximum flow from the source to the sink.
+     */
+    public int getMaxFlow() {
+        return mMaxFlow;
+    }
+
+    /**
+     * Returns the nodes which share the same partition (as defined by the min-cut edges)
+     * as the sink node.
+     */
+    public Set<V> getNodesInSinkPartition() {
+        return mSinkPartitionNodes;
+    }
+
+    /**
+     * Returns the nodes which share the same partition (as defined by the min-cut edges)
+     * as the source node.
+     */
+    public Set<V> getNodesInSourcePartition() {
+        return mSourcePartitionNodes;
+    }
+
+    /**
+     * Returns the edges in the minimum cut.
+     */
+    public Set<E> getMinCutEdges() {
+        return mMinCutEdges;
+    }
+
+    /**
+     * Returns the graph for which the maximum flow is calculated.
+     */
+    public DirectedGraph<V,E> getFlowGraph() {
+        return mFlowGraph;
+    }
+
+    @Override
+    protected void initializeIterations() {
+        parentCapacityMap.put(source, Integer.MAX_VALUE);
+        parentMap.put(source, source);
+
+        List<E> edgeList = new ArrayList<E>(mFlowGraph.getEdges());
+
+        for (int eIdx=0;eIdx< edgeList.size();eIdx++) {
+            E edge = edgeList.get(eIdx);
+            Number capacity = edgeCapacityTransformer.transform(edge);
+
+            if (capacity == null) {
+                throw new IllegalArgumentException("Edge capacities must be provided in Transformer passed to constructor");
+            }
+            residualCapacityMap.put(edge, capacity);
+
+            V source = mFlowGraph.getSource(edge);
+            V destination = mFlowGraph.getDest(edge);
+
+            if(mFlowGraph.isPredecessor(source, destination) == false) {
+               E backEdge = edgeFactory.create();
+               mFlowGraph.addEdge(backEdge, destination, source, EdgeType.DIRECTED);
+                residualCapacityMap.put(backEdge, 0);
+            }
+        }
+    }
+    
+    @Override
+    protected void finalizeIterations() {
+
+        for (E currentEdge : mFlowGraph.getEdges()) {
+            Number capacity = edgeCapacityTransformer.transform(currentEdge);
+            
+            Number residualCapacity = residualCapacityMap.get(currentEdge);
+            if (capacity != null) {
+                Integer flowValue = new Integer(capacity.intValue()-residualCapacity.intValue());
+                this.edgeFlowMap.put(currentEdge, flowValue);
+            }
+        }
+
+        Set<E> backEdges = new HashSet<E>();
+        for (E currentEdge: mFlowGraph.getEdges()) {
+               
+            if (edgeCapacityTransformer.transform(currentEdge) == null) {
+                backEdges.add(currentEdge);
+            } else {
+                residualCapacityMap.remove(currentEdge);
+            }
+        }
+        for(E e : backEdges) {
+               mFlowGraph.removeEdge(e);
+        }
+    }
+
+    private void updateResidualCapacities() {
+
+        Number augmentingPathCapacity = parentCapacityMap.get(target);
+        mMaxFlow += augmentingPathCapacity.intValue();
+        V currentVertex = target;
+        V parentVertex = null;
+        while ((parentVertex = parentMap.get(currentVertex)) != currentVertex) {
+            E currentEdge = mFlowGraph.findEdge(parentVertex, currentVertex);
+
+            Number residualCapacity = residualCapacityMap.get(currentEdge);
+
+            residualCapacity = residualCapacity.intValue() - augmentingPathCapacity.intValue();
+            residualCapacityMap.put(currentEdge, residualCapacity);
+
+            E backEdge = mFlowGraph.findEdge(currentVertex, parentVertex);
+            residualCapacity = residualCapacityMap.get(backEdge);
+            residualCapacity = residualCapacity.intValue() + augmentingPathCapacity.intValue();
+            residualCapacityMap.put(backEdge, residualCapacity);
+            currentVertex = parentVertex;
+        }
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/flows/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/flows/package.html
new file mode 100644 (file)
index 0000000..1ec243d
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+-->
+</head>
+<body>
+
+Methods for calculating properties relating to network flows (such as max flow/min cut).
+
+</body>
+</html>
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/EvolvingGraphGenerator.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/EvolvingGraphGenerator.java
new file mode 100644 (file)
index 0000000..d351f9b
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.generators;
+
+
+
+/**
+ * An interface for algorithms that generate graphs that evolve iteratively.
+ * @author Scott White
+ */
+public interface EvolvingGraphGenerator<V, E> extends GraphGenerator<V,E> {
+
+    /**
+     * Instructs the algorithm to evolve the graph N steps.
+     * @param numSteps number of steps to iterate from the current state
+     */
+    void evolveGraph(int numSteps);
+
+    /**
+     * Retrieves the total number of steps elapsed.
+     * @return number of elapsed steps
+     */
+    int numIterations();
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/GraphGenerator.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/GraphGenerator.java
new file mode 100644 (file)
index 0000000..a329060
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.generators;
+
+import org.apache.commons.collections15.Factory;
+
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * An interface for algorithms that generate graphs.
+ * @author Scott White
+ */
+public interface GraphGenerator<V, E> extends Factory<Graph<V,E>>{ }
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/Lattice2DGenerator.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/Lattice2DGenerator.java
new file mode 100644 (file)
index 0000000..e84425c
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2009, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+
+package edu.uci.ics.jung.algorithms.generators;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.collections15.Factory;
+
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.EdgeType;
+
+/**
+ * Simple generator of an m x n lattice where each vertex
+ * is incident with each of its neighbors (to the left, right, up, and down).
+ * May be toroidal, in which case the vertices on the edges are connected to
+ * their counterparts on the opposite edges as well.
+ * 
+ * <p>If the graph factory supplied has a default edge type of {@code EdgeType.DIRECTED},
+ * then edges will be created in both directions between adjacent vertices.
+ * 
+ * @author Joshua O'Madadhain
+ */
+public class Lattice2DGenerator<V,E> implements GraphGenerator<V,E>
+{
+    protected int row_count;
+    protected int col_count;
+    protected boolean is_toroidal;
+    protected boolean is_directed;
+    protected Factory<? extends Graph<V, E>> graph_factory;
+    protected Factory<V> vertex_factory;
+    protected Factory<E> edge_factory;
+    private List<V> v_array;
+
+    /**
+     * Constructs a generator of square lattices of size {@code latticeSize} 
+     * with the specified parameters.
+     * 
+     * @param graph_factory used to create the {@code Graph} for the lattice
+     * @param vertex_factory used to create the lattice vertices
+     * @param edge_factory used to create the lattice edges
+     * @param latticeSize the number of rows and columns of the lattice
+     * @param isToroidal if true, the created lattice wraps from top to bottom and left to right
+     */
+    public Lattice2DGenerator(Factory<? extends Graph<V,E>> graph_factory, Factory<V> vertex_factory, 
+            Factory<E> edge_factory, int latticeSize, boolean isToroidal)
+    {
+        this(graph_factory, vertex_factory, edge_factory, latticeSize, latticeSize, isToroidal);
+    }
+
+    /**
+     * Creates a generator of {@code row_count} x {@code col_count} lattices 
+     * with the specified parameters.
+     * 
+     * @param graph_factory used to create the {@code Graph} for the lattice
+     * @param vertex_factory used to create the lattice vertices
+     * @param edge_factory used to create the lattice edges
+     * @param row_count the number of rows in the lattice
+     * @param col_count the number of columns in the lattice
+     * @param isToroidal if true, the created lattice wraps from top to bottom and left to right
+     */
+    public Lattice2DGenerator(Factory<? extends Graph<V,E>> graph_factory, Factory<V> vertex_factory, 
+            Factory<E> edge_factory, int row_count, int col_count, boolean isToroidal)
+    {
+        if (row_count < 2 || col_count < 2)
+        {
+            throw new IllegalArgumentException("Row and column counts must each be at least 2.");
+        }
+
+        this.row_count = row_count;
+        this.col_count = col_count;
+        this.is_toroidal = isToroidal;
+        this.graph_factory = graph_factory;
+        this.vertex_factory = vertex_factory;
+        this.edge_factory = edge_factory;
+        this.is_directed = (graph_factory.create().getDefaultEdgeType() == EdgeType.DIRECTED);
+    }
+    
+    /**
+     * @see edu.uci.ics.jung.algorithms.generators.GraphGenerator#create()
+     */
+    @SuppressWarnings("unchecked")
+    public Graph<V,E> create()
+    {
+        int vertex_count = row_count * col_count;
+        Graph<V,E> graph = graph_factory.create();
+        v_array = new ArrayList<V>(vertex_count);
+        for (int i = 0; i < vertex_count; i++)
+        {
+            V v = vertex_factory.create();
+            graph.addVertex(v);
+            v_array.add(i, v);
+        }
+
+        int start = is_toroidal ? 0 : 1;
+        int end_row = is_toroidal ? row_count : row_count - 1;
+        int end_col = is_toroidal ? col_count : col_count - 1;
+        
+        // fill in edges
+        // down
+        for (int i = 0; i < end_row; i++)
+            for (int j = 0; j < col_count; j++)
+                graph.addEdge(edge_factory.create(), getVertex(i,j), getVertex(i+1, j));
+        // right
+        for (int i = 0; i < row_count; i++)
+            for (int j = 0; j < end_col; j++)
+                graph.addEdge(edge_factory.create(), getVertex(i,j), getVertex(i, j+1));
+
+        // if the graph is directed, fill in the edges going the other direction...
+        if (graph.getDefaultEdgeType() == EdgeType.DIRECTED)
+        {
+            // up
+            for (int i = start; i < row_count; i++)
+                for (int j = 0; j < col_count; j++)
+                    graph.addEdge(edge_factory.create(), getVertex(i,j), getVertex(i-1, j));
+            // left
+            for (int i = 0; i < row_count; i++)
+                for (int j = start; j < col_count; j++)
+                    graph.addEdge(edge_factory.create(), getVertex(i,j), getVertex(i, j-1));
+        }
+        
+        return graph;
+    }
+
+    /**
+     * Returns the number of edges found in a lattice of this generator's specifications.
+     * (This is useful for subclasses that may modify the generated graphs to add more edges.)
+     */
+    public int getGridEdgeCount()
+    {
+        int boundary_adjustment = (is_toroidal ? 0 : 1);
+        int vertical_edge_count = col_count * (row_count - boundary_adjustment);
+        int horizontal_edge_count = row_count * (col_count - boundary_adjustment);
+        
+        return (vertical_edge_count + horizontal_edge_count) * (is_directed ? 2 : 1);
+    }
+    
+    protected int getIndex(int i, int j)
+    {
+        return ((mod(i, row_count)) * col_count) + (mod(j, col_count));
+    }
+
+    protected int mod(int i, int modulus) 
+    {
+        int i_mod = i % modulus;
+        return i_mod >= 0 ? i_mod : i_mod + modulus;
+    }
+    
+    /**
+     * Returns the vertex at position ({@code i mod row_count, j mod col_count}).
+     */
+    protected V getVertex(int i, int j)
+    {
+        return v_array.get(getIndex(i, j));
+    }
+    
+    /**
+     * Returns the {@code i}th vertex (counting row-wise).
+     */
+    protected V getVertex(int i)
+    {
+        return v_array.get(i);
+    }
+    
+    /**
+     * Returns the row in which vertex {@code i} is found.
+     */
+    protected int getRow(int i)
+    {
+        return i / row_count;
+    }
+    
+    /**
+     * Returns the column in which vertex {@code i} is found.
+     */
+    protected int getCol(int i)
+    {
+        return i % col_count;
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/package.html
new file mode 100644 (file)
index 0000000..441922d
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+-->
+</head>
+<body>
+
+Methods for generating new (often random) graphs with various properties.
+
+</body>
+</html>
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/BarabasiAlbertGenerator.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/BarabasiAlbertGenerator.java
new file mode 100644 (file)
index 0000000..77b419b
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.generators.random;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+
+import org.apache.commons.collections15.Factory;
+
+import edu.uci.ics.jung.algorithms.generators.EvolvingGraphGenerator;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.MultiGraph;
+import edu.uci.ics.jung.graph.util.EdgeType;
+import edu.uci.ics.jung.graph.util.Pair;
+
+
+/**
+ * <p>Simple evolving scale-free random graph generator. At each time
+ * step, a new vertex is created and is connected to existing vertices
+ * according to the principle of "preferential attachment", whereby 
+ * vertices with higher degree have a higher probability of being 
+ * selected for attachment.</p>
+ * 
+ * <p>At a given timestep, the probability <code>p</code> of creating an edge
+ * between an existing vertex <code>v</code> and the newly added vertex is
+ * <pre>
+ * p = (degree(v) + 1) / (|E| + |V|);
+ * </pre>
+ * 
+ * <p>where <code>|E|</code> and <code>|V|</code> are, respectively, the number 
+ * of edges and vertices currently in the network (counting neither the new
+ * vertex nor the other edges that are being attached to it).</p>
+ * 
+ * <p>Note that the formula specified in the original paper
+ * (cited below) was
+ * <pre>
+ * p = degree(v) / |E|
+ * </pre>
+ * </p>
+ * 
+ * <p>However, this would have meant that the probability of attachment for any existing
+ * isolated vertex would be 0.  This version uses Lagrangian smoothing to give
+ * each existing vertex a positive attachment probability.</p>
+ * 
+ * <p>The graph created may be either directed or undirected (controlled by a constructor
+ * parameter); the default is undirected.  
+ * If the graph is specified to be directed, then the edges added will be directed
+ * from the newly added vertex u to the existing vertex v, with probability proportional to the 
+ * indegree of v (number of edges directed towards v).  If the graph is specified to be undirected,
+ * then the (undirected) edges added will connect u to v, with probability proportional to the 
+ * degree of v.</p> 
+ * 
+ * <p>The <code>parallel</code> constructor parameter specifies whether parallel edges
+ * may be created.</p>
+ * 
+ * @see "A.-L. Barabasi and R. Albert, Emergence of scaling in random networks, Science 286, 1999."
+ * @author Scott White
+ * @author Joshua O'Madadhain
+ * @author Tom Nelson - adapted to jung2
+ */
+public class BarabasiAlbertGenerator<V,E> implements EvolvingGraphGenerator<V,E> {
+    private Graph<V, E> mGraph = null;
+    private int mNumEdgesToAttachPerStep;
+    private int mElapsedTimeSteps;
+    private Random mRandom;
+    protected List<V> vertex_index;
+    protected int init_vertices;
+    protected Map<V,Integer> index_vertex;
+    protected Factory<Graph<V,E>> graphFactory;
+    protected Factory<V> vertexFactory;
+    protected Factory<E> edgeFactory;
+    
+    /**
+     * Constructs a new instance of the generator.
+     * @param init_vertices     number of unconnected 'seed' vertices that the graph should start with
+     * @param numEdgesToAttach the number of edges that should be attached from the
+     * new vertex to pre-existing vertices at each time step
+     * @param directed  specifies whether the graph and edges to be created should be directed or not
+     * @param parallel  specifies whether the algorithm permits parallel edges
+     * @param seed  random number seed
+     */
+    public BarabasiAlbertGenerator(Factory<Graph<V,E>> graphFactory,
+               Factory<V> vertexFactory, Factory<E> edgeFactory, 
+               int init_vertices, int numEdgesToAttach, 
+            int seed, Set<V> seedVertices)
+    {
+        assert init_vertices > 0 : "Number of initial unconnected 'seed' vertices " + 
+                    "must be positive";
+        assert numEdgesToAttach > 0 : "Number of edges to attach " +
+                    "at each time step must be positive";
+        
+        mNumEdgesToAttachPerStep = numEdgesToAttach;
+        mRandom = new Random(seed);
+        this.graphFactory = graphFactory;
+        this.vertexFactory = vertexFactory;
+        this.edgeFactory = edgeFactory;
+        this.init_vertices = init_vertices;
+        initialize(seedVertices);
+    }
+    
+
+    /**
+     * Constructs a new instance of the generator, whose output will be an undirected graph,
+     * and which will use the current time as a seed for the random number generation.
+     * @param init_vertices     number of vertices that the graph should start with
+     * @param numEdgesToAttach the number of edges that should be attached from the
+     * new vertex to pre-existing vertices at each time step
+     */
+    public BarabasiAlbertGenerator(Factory<Graph<V,E>> graphFactory, 
+               Factory<V> vertexFactory, Factory<E> edgeFactory,
+               int init_vertices, int numEdgesToAttach, Set<V> seedVertices) {
+        this(graphFactory, vertexFactory, edgeFactory, init_vertices, numEdgesToAttach, (int) System.currentTimeMillis(), seedVertices);
+    }
+    
+    private void initialize(Set<V> seedVertices) {
+       
+       mGraph = graphFactory.create();
+
+        vertex_index = new ArrayList<V>(2*init_vertices);
+        index_vertex = new HashMap<V, Integer>(2*init_vertices);
+        for (int i = 0; i < init_vertices; i++) {
+            V v = vertexFactory.create();
+            mGraph.addVertex(v);
+            vertex_index.add(v);
+            index_vertex.put(v, i);
+            seedVertices.add(v);
+        }
+            
+        mElapsedTimeSteps = 0;
+    }
+
+    private void createRandomEdge(Collection<V> preexistingNodes,
+               V newVertex, Set<Pair<V>> added_pairs) {
+        V attach_point;
+        boolean created_edge = false;
+        Pair<V> endpoints;
+        do {
+            attach_point = vertex_index.get(mRandom.nextInt(vertex_index.size()));
+            
+            endpoints = new Pair<V>(newVertex, attach_point);
+            
+            // if parallel edges are not allowed, skip attach_point if <newVertex, attach_point>
+            // already exists; note that because of the way edges are added, we only need to check
+            // the list of candidate edges for duplicates.
+            if (!(mGraph instanceof MultiGraph))
+            {
+               if (added_pairs.contains(endpoints))
+                       continue;
+               if (mGraph.getDefaultEdgeType() == EdgeType.UNDIRECTED && 
+                       added_pairs.contains(new Pair<V>(attach_point, newVertex)))
+                       continue;
+            }
+
+            double degree = mGraph.inDegree(attach_point);
+            
+            // subtract 1 from numVertices because we don't want to count newVertex
+            // (which has already been added to the graph, but not to vertex_index)
+            double attach_prob = (degree + 1) / (mGraph.getEdgeCount() + mGraph.getVertexCount() - 1);
+            if (attach_prob >= mRandom.nextDouble())
+                created_edge = true;
+        }
+        while (!created_edge);
+
+        added_pairs.add(endpoints);
+        
+        if (mGraph.getDefaultEdgeType() == EdgeType.UNDIRECTED) {
+               added_pairs.add(new Pair<V>(attach_point, newVertex));
+        }
+    }
+
+    public void evolveGraph(int numTimeSteps) {
+
+        for (int i = 0; i < numTimeSteps; i++) {
+            evolveGraph();
+            mElapsedTimeSteps++;
+        }
+    }
+
+    private void evolveGraph() {
+        Collection<V> preexistingNodes = mGraph.getVertices();
+        V newVertex = vertexFactory.create();
+
+        mGraph.addVertex(newVertex);
+
+        // generate and store the new edges; don't add them to the graph
+        // yet because we don't want to bias the degree calculations
+        // (all new edges in a timestep should be added in parallel)
+        Set<Pair<V>> added_pairs = new HashSet<Pair<V>>(mNumEdgesToAttachPerStep*3);
+        
+        for (int i = 0; i < mNumEdgesToAttachPerStep; i++) 
+               createRandomEdge(preexistingNodes, newVertex, added_pairs);
+        
+        for (Pair<V> pair : added_pairs)
+        {
+               V v1 = pair.getFirst();
+               V v2 = pair.getSecond();
+               if (mGraph.getDefaultEdgeType() != EdgeType.UNDIRECTED || 
+                               !mGraph.isNeighbor(v1, v2))
+                       mGraph.addEdge(edgeFactory.create(), pair);
+        }
+        // now that we're done attaching edges to this new vertex, 
+        // add it to the index
+        vertex_index.add(newVertex);
+        index_vertex.put(newVertex, new Integer(vertex_index.size() - 1));
+    }
+
+    public int numIterations() {
+        return mElapsedTimeSteps;
+    }
+
+    public Graph<V, E> create() {
+        return mGraph;
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/EppsteinPowerLawGenerator.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/EppsteinPowerLawGenerator.java
new file mode 100644 (file)
index 0000000..e3bf04b
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.generators.random;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.commons.collections15.Factory;
+
+import edu.uci.ics.jung.algorithms.generators.GraphGenerator;
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * Graph generator that generates undirected graphs with power-law degree distributions.
+ * @author Scott White
+ * @see "A Steady State Model for Graph Power Law by David Eppstein and Joseph Wang"
+ */
+public class EppsteinPowerLawGenerator<V,E> implements GraphGenerator<V,E> {
+    private int mNumVertices;
+    private int mNumEdges;
+    private int mNumIterations;
+    private double mMaxDegree;
+    private Random mRandom;
+    private Factory<Graph<V,E>> graphFactory;
+    private Factory<V> vertexFactory;
+    private Factory<E> edgeFactory;
+
+    /**
+     * Creates an instance with the specified factories and specifications.
+     * @param graphFactory the factory to use to generate the graph
+     * @param vertexFactory the factory to use to create vertices
+     * @param edgeFactory the factory to use to create edges
+     * @param numVertices the number of vertices for the generated graph
+     * @param numEdges the number of edges the generated graph will have, should be Theta(numVertices)
+     * @param r the number of iterations to use; the larger the value the better the graph's degree
+     * distribution will approximate a power-law
+     */
+    public EppsteinPowerLawGenerator(Factory<Graph<V,E>> graphFactory,
+               Factory<V> vertexFactory, Factory<E> edgeFactory, 
+               int numVertices, int numEdges, int r) {
+       this.graphFactory = graphFactory;
+       this.vertexFactory = vertexFactory;
+       this.edgeFactory = edgeFactory;
+        mNumVertices = numVertices;
+        mNumEdges = numEdges;
+        mNumIterations = r;
+        mRandom = new Random();
+    }
+
+    protected Graph<V,E> initializeGraph() {
+        Graph<V,E> graph = null;
+        graph = graphFactory.create();
+        for(int i=0; i<mNumVertices; i++) {
+               graph.addVertex(vertexFactory.create());
+        }
+        List<V> vertices = new ArrayList<V>(graph.getVertices());
+        while (graph.getEdgeCount() < mNumEdges) {
+            V u = vertices.get((int) (mRandom.nextDouble() * mNumVertices));
+            V v = vertices.get((int) (mRandom.nextDouble() * mNumVertices));
+            if (!graph.isSuccessor(v,u)) {
+               graph.addEdge(edgeFactory.create(), u, v);
+            }
+        }
+
+        double maxDegree = 0;
+        for (V v : graph.getVertices()) {
+            maxDegree = Math.max(graph.degree(v),maxDegree);
+        }
+        mMaxDegree = maxDegree; //(maxDegree+1)*(maxDegree)/2;
+
+        return graph;
+    }
+
+    /**
+     * Generates a graph whose degree distribution approximates a power-law.
+     * @return the generated graph
+     */
+    public Graph<V,E> create() {
+        Graph<V,E> graph = initializeGraph();
+
+        List<V> vertices = new ArrayList<V>(graph.getVertices());
+        for (int rIdx = 0; rIdx < mNumIterations; rIdx++) {
+
+            V v = null;
+            int degree = 0;
+            do {
+                v = vertices.get((int) (mRandom.nextDouble() * mNumVertices));
+                degree = graph.degree(v);
+
+            } while (degree == 0);
+
+            List<E> edges = new ArrayList<E>(graph.getIncidentEdges(v));
+            E randomExistingEdge = edges.get((int) (mRandom.nextDouble()*degree));
+
+            // FIXME: look at email thread on a more efficient RNG for arbitrary distributions
+            
+            V x = vertices.get((int) (mRandom.nextDouble() * mNumVertices));
+            V y = null;
+            do {
+                y = vertices.get((int) (mRandom.nextDouble() * mNumVertices));
+
+            } while (mRandom.nextDouble() > ((graph.degree(y)+1)/mMaxDegree));
+
+            if (!graph.isSuccessor(y,x) && x != y) {
+                graph.removeEdge(randomExistingEdge);
+                graph.addEdge(edgeFactory.create(), x, y);
+            }
+        }
+
+        return graph;
+    }
+
+    /**
+     * Sets the seed for the random number generator.
+     * @param seed input to the random number generator.
+     */
+    public void setSeed(long seed) {
+        mRandom.setSeed(seed);
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/ErdosRenyiGenerator.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/ErdosRenyiGenerator.java
new file mode 100644 (file)
index 0000000..3a33730
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.generators.random;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.commons.collections15.Factory;
+
+import edu.uci.ics.jung.algorithms.generators.GraphGenerator;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.UndirectedGraph;
+
+/**
+ * Generates a random graph using the Erdos-Renyi binomial model
+ * (each pair of vertices is connected with probability p).
+ * 
+ *  @author William Giordano, Scott White, Joshua O'Madadhain
+ */
+public class ErdosRenyiGenerator<V,E> implements GraphGenerator<V,E> {
+    private int mNumVertices;
+    private double mEdgeConnectionProbability;
+    private Random mRandom;
+    Factory<UndirectedGraph<V,E>> graphFactory;
+    Factory<V> vertexFactory;
+    Factory<E> edgeFactory;
+
+    /**
+     *
+     * @param numVertices number of vertices graph should have
+     * @param p Connection's probability between 2 vertices
+     */
+       public ErdosRenyiGenerator(Factory<UndirectedGraph<V,E>> graphFactory,
+                       Factory<V> vertexFactory, Factory<E> edgeFactory,
+                       int numVertices,double p)
+    {
+        if (numVertices <= 0) {
+            throw new IllegalArgumentException("A positive # of vertices must be specified.");
+        }
+        mNumVertices = numVertices;
+        if (p < 0 || p > 1) {
+            throw new IllegalArgumentException("p must be between 0 and 1.");
+        }
+        this.graphFactory = graphFactory;
+        this.vertexFactory = vertexFactory;
+        this.edgeFactory = edgeFactory;
+        mEdgeConnectionProbability = p;
+        mRandom = new Random();
+       }
+
+    /**
+     * Returns a graph in which each pair of vertices is connected by 
+     * an undirected edge with the probability specified by the constructor.
+     */
+       public Graph<V,E> create() {
+        UndirectedGraph<V,E> g = graphFactory.create();
+        for(int i=0; i<mNumVertices; i++) {
+               g.addVertex(vertexFactory.create());
+        }
+        List<V> list = new ArrayList<V>(g.getVertices());
+
+               for (int i = 0; i < mNumVertices-1; i++) {
+            V v_i = list.get(i);
+                       for (int j = i+1; j < mNumVertices; j++) {
+                V v_j = list.get(j);
+                               if (mRandom.nextDouble() < mEdgeConnectionProbability) {
+                                       g.addEdge(edgeFactory.create(), v_i, v_j);
+                               }
+                       }
+               }
+        return g;
+    }
+
+    /**
+     * Sets the seed of the internal random number generator to {@code seed}.
+     * Enables consistent behavior.
+     */
+    public void setSeed(long seed) {
+        mRandom.setSeed(seed);
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/KleinbergSmallWorldGenerator.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/KleinbergSmallWorldGenerator.java
new file mode 100644 (file)
index 0000000..de01b69
--- /dev/null
@@ -0,0 +1,184 @@
+
+package edu.uci.ics.jung.algorithms.generators.random;
+
+/*
+* Copyright (c) 2009, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+import org.apache.commons.collections15.Factory;
+
+import edu.uci.ics.jung.algorithms.generators.Lattice2DGenerator;
+import edu.uci.ics.jung.algorithms.util.WeightedChoice;
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * Graph generator that produces a random graph with small world properties. 
+ * The underlying model is an mxn (optionally toroidal) lattice. Each node u 
+ * has four local connections, one to each of its neighbors, and
+ * in addition 1+ long range connections to some node v where v is chosen randomly according to
+ * probability proportional to d^-alpha where d is the lattice distance between u and v and alpha
+ * is the clustering exponent.
+ * 
+ * @see "Navigation in a small world J. Kleinberg, Nature 406(2000), 845."
+ * @author Joshua O'Madadhain
+ */
+public class KleinbergSmallWorldGenerator<V, E> extends Lattice2DGenerator<V, E> {
+    private double clustering_exponent;
+    private Random random;
+    private int num_connections = 1;
+    
+    /**
+     * Creates 
+     * @param graph_factory
+     * @param vertex_factory
+     * @param edge_factory
+     * @param latticeSize
+     * @param clusteringExponent
+     */
+    public KleinbergSmallWorldGenerator(Factory<? extends Graph<V,E>> graph_factory, Factory<V> vertex_factory, 
+            Factory<E> edge_factory, int latticeSize, double clusteringExponent) 
+    {
+        this(graph_factory, vertex_factory, edge_factory, latticeSize, latticeSize, clusteringExponent);
+    }
+
+    /**
+     * @param graph_factory
+     * @param vertex_factory
+     * @param edge_factory
+     * @param row_count
+     * @param col_count
+     * @param clusteringExponent
+     */
+    public KleinbergSmallWorldGenerator(Factory<? extends Graph<V,E>> graph_factory, Factory<V> vertex_factory, 
+            Factory<E> edge_factory, int row_count, int col_count, double clusteringExponent) 
+    {
+        super(graph_factory, vertex_factory, edge_factory, row_count, col_count, true);
+        clustering_exponent = clusteringExponent;
+        initialize();
+    }
+
+    /**
+     * @param graph_factory
+     * @param vertex_factory
+     * @param edge_factory
+     * @param row_count
+     * @param col_count
+     * @param clusteringExponent
+     * @param isToroidal
+     */
+    public KleinbergSmallWorldGenerator(Factory<? extends Graph<V,E>> graph_factory, Factory<V> vertex_factory, 
+            Factory<E> edge_factory, int row_count, int col_count, double clusteringExponent, 
+            boolean isToroidal) 
+    {
+        super(graph_factory, vertex_factory, edge_factory, row_count, col_count, isToroidal);
+        clustering_exponent = clusteringExponent;
+        initialize();
+    }
+
+    private void initialize()
+    {
+        this.random = new Random();
+    }
+    
+    /**
+     * Sets the {@code Random} instance used by this instance.  Useful for 
+     * unit testing.
+     */
+    public void setRandom(Random random)
+    {
+        this.random = random;
+    }
+    
+    /**
+     * Sets the seed of the internal random number generator.  May be used to provide repeatable
+     * experiments.
+     */
+    public void setRandomSeed(long seed) 
+    {
+        random.setSeed(seed);
+    }
+
+    /**
+     * Sets the number of new 'small-world' connections (outgoing edges) to be added to each vertex.
+     */
+    public void setConnectionCount(int num_connections)
+    {
+        if (num_connections <= 0)
+        {
+            throw new IllegalArgumentException("Number of new connections per vertex must be >= 1");
+        }
+        this.num_connections = num_connections;
+    }
+
+    /**
+     * Returns the number of new 'small-world' connections to be made to each vertex.
+     */
+    public int getConnectionCount()
+    {
+        return this.num_connections;
+    }
+    
+    /**
+     * Generates a random small world network according to the parameters given
+     * @return a random small world graph
+     */
+    @Override
+    public Graph<V,E> create() 
+    {
+        Graph<V, E> graph = super.create();
+        
+        // TODO: For toroidal graphs, we can make this more clever by pre-creating the WeightedChoice object
+        // and using the output as an offset to the current vertex location.
+        WeightedChoice<V> weighted_choice;
+        
+        // Add long range connections
+        for (int i = 0; i < graph.getVertexCount(); i++)
+        {
+            V source = getVertex(i);
+            int row = getRow(i);
+            int col = getCol(i);
+            int row_offset = row < row_count/2 ? -row_count : row_count;
+            int col_offset = col < col_count/2 ? -col_count : col_count;
+
+            Map<V, Float> vertex_weights = new HashMap<V, Float>();
+            for (int j = 0; j < row_count; j++)
+            {
+                for (int k = 0; k < col_count; k++)
+                {
+                    if (j == row && k == col)
+                        continue;
+                    int v_dist = Math.abs(j - row);
+                    int h_dist = Math.abs(k - col);
+                    if (is_toroidal)
+                    {
+                        v_dist = Math.min(v_dist, Math.abs(j - row+row_offset));
+                        h_dist = Math.min(h_dist, Math.abs(k - col+col_offset));
+                    }
+                    int distance = v_dist + h_dist;
+                    if (distance < 2)
+                        continue;
+                    else
+                        vertex_weights.put(getVertex(j,k), (float)Math.pow(distance, -clustering_exponent));
+                }
+            }
+
+            for (int j = 0; j < this.num_connections; j++) {
+                weighted_choice = new WeightedChoice<V>(vertex_weights, random);
+                V target = weighted_choice.nextItem();
+                graph.addEdge(edge_factory.create(), source, target);
+            }
+        }
+
+        return graph;
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/MixedRandomGraphGenerator.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/MixedRandomGraphGenerator.java
new file mode 100644 (file)
index 0000000..a39a640
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ * 
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ */
+/*
+ * Created on Jul 2, 2003
+ *  
+ */
+package edu.uci.ics.jung.algorithms.generators.random;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections15.Factory;
+
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.EdgeType;
+
+/**
+ * 
+ * Generates a mixed-mode random graph based on the output of <code>BarabasiAlbertGenerator</code>.
+ * Primarily intended for providing a heterogeneous sample graph for visualization testing, etc.
+ *  
+ */
+public class MixedRandomGraphGenerator {
+
+       /**
+        * Equivalent to <code>generateMixedRandomGraph(edge_weight, num_vertices, true)</code>.
+        */
+       public static <V,E> Graph<V, E> generateMixedRandomGraph(
+                       Factory<Graph<V,E>> graphFactory,
+                       Factory<V> vertexFactory,
+               Factory<E> edgeFactory,
+               Map<E,Number> edge_weight, 
+                       int num_vertices, Set<V> seedVertices)
+       {
+               return generateMixedRandomGraph(graphFactory, vertexFactory, edgeFactory, 
+                               edge_weight, num_vertices, true, seedVertices);
+       }
+
+    /**
+     * Returns a random mixed-mode graph.  Starts with a randomly generated 
+     * Barabasi-Albert (preferential attachment) generator 
+     * (4 initial vertices, 3 edges added at each step, and num_vertices - 4 evolution steps).
+     * Then takes the resultant graph, replaces random undirected edges with directed
+     * edges, and assigns random weights to each edge.
+     */
+    public static <V,E> Graph<V,E> generateMixedRandomGraph(
+               Factory<Graph<V,E>> graphFactory,
+               Factory<V> vertexFactory,
+               Factory<E> edgeFactory,
+               Map<E,Number> edge_weights, 
+            int num_vertices, boolean parallel, Set<V> seedVertices)
+    {
+        int seed = (int)(Math.random() * 10000);
+        BarabasiAlbertGenerator<V,E> bag = 
+            new BarabasiAlbertGenerator<V,E>(graphFactory, vertexFactory, edgeFactory,
+                       4, 3, //false, parallel, 
+                       seed, seedVertices);
+        bag.evolveGraph(num_vertices - 4);
+        Graph<V, E> ug = bag.create();
+
+        // create a SparseMultigraph version of g
+        Graph<V, E> g = graphFactory.create();
+               //new SparseMultigraph<V, E>();
+        for(V v : ug.getVertices()) {
+               g.addVertex(v);
+        }
+        
+        // randomly replace some of the edges by directed edges to 
+        // get a mixed-mode graph, add random weights
+        
+        for(E e : ug.getEdges()) {
+            V v1 = ug.getEndpoints(e).getFirst();
+            V v2 = ug.getEndpoints(e).getSecond();
+
+            E me = edgeFactory.create();
+            g.addEdge(me, v1, v2, Math.random() < .5 ? EdgeType.DIRECTED : EdgeType.UNDIRECTED);
+            edge_weights.put(me, Math.random());
+        }
+        
+        return g;
+    }
+    
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/generators/random/package.html
new file mode 100644 (file)
index 0000000..9f85614
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+-->
+</head>
+<body>
+
+Methods for generating random graphs with various properties.  These include:
+<ul>
+<li/><code>BarabasiAlbertGenerator</code>: scale-free graphs using the preferential attachment heuristic.
+<li/><code>EppsteinPowerLawGenerator</code>: graphs whose degree distribution approximates a power law
+<li/><code>ErdosRenyiGenerator</code>: graphs for which edges are created with a specified probability
+<li/><code>MixedRandomGraphGenerator</code>: takes the output of <code>BarabasiAlbertGenerator</code> and
+perturbs it to generate a mixed-mode analog with both directed and undirected edges. 
+<li/>
+
+
+</body>
+</html>
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/AbstractRanker.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/AbstractRanker.java
new file mode 100644 (file)
index 0000000..6ea8bc8
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.importance;
+
+import java.text.DecimalFormat;
+import java.text.Format;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections15.Factory;
+import org.apache.commons.collections15.map.LazyMap;
+
+import edu.uci.ics.jung.algorithms.util.IterativeProcess;
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * Abstract class for algorithms that rank nodes or edges by some "importance" metric. Provides a common set of
+ * services such as:
+ * <ul>
+ *  <li> storing rank scores</li>
+ *  <li> getters and setters for rank scores</li>
+ *  <li> computing default edge weights</li>
+ *  <li> normalizing default or user-provided edge transition weights </li>
+ *  <li> normalizing rank scores</li>
+ *  <li> automatic cleanup of decorations</li>
+ *  <li> creation of Ranking list</li>
+ * <li>print rankings in sorted order by rank</li>
+ * </ul>
+ * <p>
+ * By default, all rank scores are removed from the vertices (or edges) being ranked.
+ * @author Scott White
+ */
+public abstract class AbstractRanker<V,E> extends IterativeProcess {
+    private Graph<V,E> mGraph;
+    private List<Ranking<?>> mRankings;
+    private boolean mRemoveRankScoresOnFinalize;
+    private boolean mRankNodes;
+    private boolean mRankEdges;
+    private boolean mNormalizeRankings;
+    protected Map<Object,Map<V, Number>> vertexRankScores = 
+       LazyMap.decorate(
+                       new HashMap<Object,Map<V,Number>>(),
+                       new Factory<Map<V,Number>>() {
+                                       public Map<V,Number> create() {
+                                               return new HashMap<V,Number>();
+                                       }});
+    protected Map<Object,Map<E, Number>> edgeRankScores = 
+       LazyMap.decorate(
+                       new HashMap<Object,Map<E,Number>>(),
+                       new Factory<Map<E,Number>>() {
+                                       public Map<E,Number> create() {
+                                               return new HashMap<E,Number>();
+                                       }});
+    private Map<E,Number> edgeWeights = new HashMap<E,Number>();
+
+    protected void initialize(Graph<V,E> graph, boolean isNodeRanker, 
+        boolean isEdgeRanker) {
+        if (!isNodeRanker && !isEdgeRanker)
+            throw new IllegalArgumentException("Must rank edges, vertices, or both");
+        mGraph = graph;
+        mRemoveRankScoresOnFinalize = true;
+        mNormalizeRankings = true;
+        mRankNodes = isNodeRanker;
+        mRankEdges = isEdgeRanker;
+    }
+    
+    /**
+        * @return all rankScores
+        */
+       public Map<Object,Map<V, Number>> getVertexRankScores() {
+               return vertexRankScores;
+       }
+
+       public Map<Object,Map<E, Number>> getEdgeRankScores() {
+               return edgeRankScores;
+       }
+
+    /**
+        * @return the rankScores
+        */
+       public Map<V, Number> getVertexRankScores(Object key) {
+               return vertexRankScores.get(key);
+       }
+
+       public Map<E, Number> getEdgeRankScores(Object key) {
+               return edgeRankScores.get(key);
+       }
+
+       protected Collection<V> getVertices() {
+        return mGraph.getVertices();
+    }
+
+       protected int getVertexCount() {
+        return mGraph.getVertexCount();
+    }
+
+    protected Graph<V,E> getGraph() {
+        return mGraph;
+    }
+
+    @Override
+    public void reset() {
+    }
+
+    /**
+     * Returns <code>true</code> if this ranker ranks nodes, and 
+     * <code>false</code> otherwise.
+     */
+    public boolean isRankingNodes() {
+        return mRankNodes;
+    }
+
+    /**
+     * Returns <code>true</code> if this ranker ranks edges, and 
+     * <code>false</code> otherwise.
+     */
+    public boolean isRankingEdges() {
+        return mRankEdges;
+    }
+    
+    /**
+     * Instructs the ranker whether or not it should remove the rank scores from the nodes (or edges) once the ranks
+     * have been computed.
+     * @param removeRankScoresOnFinalize <code>true</code> if the rank scores are to be removed, <code>false</code> otherwise
+     */
+    public void setRemoveRankScoresOnFinalize(boolean removeRankScoresOnFinalize) {
+        this.mRemoveRankScoresOnFinalize = removeRankScoresOnFinalize;
+    }
+
+    protected void onFinalize(Object e) {}
+    
+    /**
+     * The user datum key used to store the rank score.
+     * @return the key
+     */
+    abstract public Object getRankScoreKey();
+
+
+    @Override
+    protected void finalizeIterations() {
+        List<Ranking<?>> sortedRankings = new ArrayList<Ranking<?>>();
+
+        int id = 1;
+        if (mRankNodes) {
+            for (V currentVertex : getVertices()) {
+                Ranking<V> ranking = new Ranking<V>(id,getVertexRankScore(currentVertex),currentVertex);
+                sortedRankings.add(ranking);
+                if (mRemoveRankScoresOnFinalize) {
+                       this.vertexRankScores.get(getRankScoreKey()).remove(currentVertex);
+                }
+                id++;
+                onFinalize(currentVertex);
+            }
+        }
+        if (mRankEdges) {
+            for (E currentEdge : mGraph.getEdges()) {
+
+                Ranking<E> ranking = new Ranking<E>(id,getEdgeRankScore(currentEdge),currentEdge);
+                sortedRankings.add(ranking);
+                if (mRemoveRankScoresOnFinalize) {
+                       this.edgeRankScores.get(getRankScoreKey()).remove(currentEdge);
+                }
+                id++;
+                onFinalize(currentEdge);
+            }
+        }
+
+        mRankings = sortedRankings;
+        Collections.sort(mRankings);
+    }
+
+    /**
+     * Retrieves the list of ranking instances in descending sorted order by rank score
+     * If the algorithm is ranking edges, the instances will be of type <code>EdgeRanking</code>, otherwise
+     * if the algorithm is ranking nodes the instances will be of type <code>NodeRanking</code>
+     * @return  the list of rankings
+     */
+    public List<Ranking<?>> getRankings() {
+        return mRankings;
+    }
+
+    /**
+     * Return a list of the top k rank scores.
+     * @param topKRankings the value of k to use
+     * @return list of rank scores
+     */
+    public List<Double> getRankScores(int topKRankings) {
+        List<Double> scores = new ArrayList<Double>();
+        int count=1;
+        for (Ranking<?> currentRanking : getRankings()) {
+            if (count > topKRankings) {
+                return scores;
+            }
+            scores.add(currentRanking.rankScore);
+            count++;
+        }
+
+        return scores;
+    }
+
+    /**
+     * Given an edge or node, returns the corresponding rank score. This is a default
+     * implementation of getRankScore which assumes the decorations are of type MutableDouble.
+     * This method only returns legal values if <code>setRemoveRankScoresOnFinalize(false)</code> was called
+     * prior to <code>evaluate()</code>.
+     * @return  the rank score value
+     */
+    public double getVertexRankScore(V v) {
+        Number rankScore = vertexRankScores.get(getRankScoreKey()).get(v);
+        if (rankScore != null) {
+            return rankScore.doubleValue();
+        } else {
+            throw new RuntimeException("setRemoveRankScoresOnFinalize(false) must be called before evaluate().");
+        }
+    }
+    
+    public double getVertexRankScore(V v, Object key) {
+       return vertexRankScores.get(key).get(v).doubleValue();
+    }
+
+    public double getEdgeRankScore(E e) {
+        Number rankScore = edgeRankScores.get(getRankScoreKey()).get(e);
+        if (rankScore != null) {
+            return rankScore.doubleValue();
+        } else {
+            throw new RuntimeException("setRemoveRankScoresOnFinalize(false) must be called before evaluate().");
+        }
+    }
+    
+    public double getEdgeRankScore(E e, Object key) {
+       return edgeRankScores.get(key).get(e).doubleValue();
+    }
+
+    protected void setVertexRankScore(V v, double rankValue, Object key) {
+       vertexRankScores.get(key).put(v, rankValue);
+    }
+
+    protected void setEdgeRankScore(E e, double rankValue, Object key) {
+               edgeRankScores.get(key).put(e, rankValue);
+    }
+
+    protected void setVertexRankScore(V v, double rankValue) {
+       setVertexRankScore(v,rankValue, getRankScoreKey());
+    }
+
+    protected void setEdgeRankScore(E e, double rankValue) {
+       setEdgeRankScore(e, rankValue, getRankScoreKey());
+    }
+
+    protected void removeVertexRankScore(V v, Object key) {
+       vertexRankScores.get(key).remove(v);
+    }
+
+    protected void removeEdgeRankScore(E e, Object key) {
+       edgeRankScores.get(key).remove(e);
+    }
+
+    protected void removeVertexRankScore(V v) {
+       vertexRankScores.get(getRankScoreKey()).remove(v);
+    }
+
+    protected void removeEdgeRankScore(E e) {
+       edgeRankScores.get(getRankScoreKey()).remove(e);
+    }
+
+    protected double getEdgeWeight(E e) {
+       return edgeWeights.get(e).doubleValue();
+    }
+
+    protected void setEdgeWeight(E e, double weight) {
+       edgeWeights.put(e, weight);
+    }
+    
+    public void setEdgeWeights(Map<E,Number> edgeWeights) {
+       this.edgeWeights = edgeWeights;
+    }
+
+    /**
+        * @return the edgeWeights
+        */
+       public Map<E, Number> getEdgeWeights() {
+               return edgeWeights;
+       }
+
+       protected void assignDefaultEdgeTransitionWeights() {
+
+        for (V currentVertex : getVertices()) {
+
+            Collection<E> outgoingEdges = mGraph.getOutEdges(currentVertex);
+
+            double numOutEdges = outgoingEdges.size();
+            for (E currentEdge : outgoingEdges) {
+                setEdgeWeight(currentEdge,1.0/numOutEdges);
+            }
+        }
+    }
+
+    protected void normalizeEdgeTransitionWeights() {
+
+        for (V currentVertex : getVertices()) {
+
+               Collection<E> outgoingEdges = mGraph.getOutEdges(currentVertex);
+
+            double totalEdgeWeight = 0;
+            for (E currentEdge : outgoingEdges) {
+                totalEdgeWeight += getEdgeWeight(currentEdge);
+            }
+
+            for (E currentEdge : outgoingEdges) {
+                setEdgeWeight(currentEdge,getEdgeWeight(currentEdge)/totalEdgeWeight);
+            }
+        }
+    }
+
+    protected void normalizeRankings() {
+        if (!mNormalizeRankings) {
+            return;
+        }
+        double totalWeight = 0;
+
+        for (V currentVertex : getVertices()) {
+            totalWeight += getVertexRankScore(currentVertex);
+        }
+
+        for (V currentVertex : getVertices()) {
+            setVertexRankScore(currentVertex,getVertexRankScore(currentVertex)/totalWeight);
+        }
+    }
+
+    /**
+     * Print the rankings to standard out in descending order of rank score
+     * @param verbose if <code>true</code>, include information about the actual rank order as well as
+     * the original position of the vertex before it was ranked
+     * @param printScore if <code>true</code>, include the actual value of the rank score
+     */
+    public void printRankings(boolean verbose,boolean printScore) {
+            double total = 0;
+            Format formatter = new DecimalFormat("#0.#######");
+            int rank = 1;
+
+            for (Ranking<?> currentRanking : getRankings()) {
+                double rankScore = currentRanking.rankScore;
+                if (verbose) {
+                    System.out.print("Rank " + rank + ": ");
+                    if (printScore) {
+                        System.out.print(formatter.format(rankScore));
+                    }
+                    System.out.print("\tVertex Id: " + currentRanking.originalPos);
+                        System.out.print(" (" + currentRanking.getRanked() + ")");
+                    System.out.println();
+                } else {
+                    System.out.print(rank + "\t");
+                     if (printScore) {
+                        System.out.print(formatter.format(rankScore));
+                    }
+                    System.out.println("\t" + currentRanking.originalPos);
+
+                }
+                total += rankScore;
+                rank++;
+            }
+
+            if (verbose) {
+                System.out.println("Total: " + formatter.format(total));
+            }
+    }
+
+    /**
+     * Allows the user to specify whether or not s/he wants the rankings to be normalized.
+     * In some cases, this will have no effect since the algorithm doesn't allow normalization
+     * as an option
+     * @param normalizeRankings
+     */
+    public void setNormalizeRankings(boolean normalizeRankings) {
+        mNormalizeRankings = normalizeRankings;
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/BetweennessCentrality.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/BetweennessCentrality.java
new file mode 100644 (file)
index 0000000..25906f2
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.importance;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import org.apache.commons.collections15.Buffer;
+import org.apache.commons.collections15.buffer.UnboundedFifoBuffer;
+
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.UndirectedGraph;
+
+/**
+ * Computes betweenness centrality for each vertex and edge in the graph. The result is that each vertex
+ * and edge has a UserData element of type MutableDouble whose key is 'centrality.BetweennessCentrality'.
+ * Note: Many social network researchers like to normalize the betweenness values by dividing the values by
+ * (n-1)(n-2)/2. The values given here are unnormalized.<p>
+ *
+ * A simple example of usage is:
+ * <pre>
+ * BetweennessCentrality ranker = new BetweennessCentrality(someGraph);
+ * ranker.evaluate();
+ * ranker.printRankings();
+ * </pre>
+ *
+ * Running time is: O(n^2 + nm).
+ * @see "Ulrik Brandes: A Faster Algorithm for Betweenness Centrality. Journal of Mathematical Sociology 25(2):163-177, 2001."
+ * @author Scott White
+ * @author Tom Nelson converted to jung2
+ */
+
+public class BetweennessCentrality<V,E> extends AbstractRanker<V,E> {
+
+    public static final String CENTRALITY = "centrality.BetweennessCentrality";
+
+    /**
+     * Constructor which initializes the algorithm
+     * @param g the graph whose nodes are to be analyzed
+     */
+    public BetweennessCentrality(Graph<V,E> g) {
+        initialize(g, true, true);
+    }
+
+    public BetweennessCentrality(Graph<V,E> g, boolean rankNodes) {
+        initialize(g, rankNodes, true);
+    }
+
+    public BetweennessCentrality(Graph<V,E> g, boolean rankNodes, boolean rankEdges)
+    {
+        initialize(g, rankNodes, rankEdges);
+    }
+    
+       protected void computeBetweenness(Graph<V,E> graph) {
+
+       Map<V,BetweennessData> decorator = new HashMap<V,BetweennessData>();
+       Map<V,Number> bcVertexDecorator = 
+               vertexRankScores.get(getRankScoreKey());
+       bcVertexDecorator.clear();
+       Map<E,Number> bcEdgeDecorator = 
+               edgeRankScores.get(getRankScoreKey());
+       bcEdgeDecorator.clear();
+        
+        Collection<V> vertices = graph.getVertices();
+        
+        for (V s : vertices) {
+
+            initializeData(graph,decorator);
+
+            decorator.get(s).numSPs = 1;
+            decorator.get(s).distance = 0;
+
+            Stack<V> stack = new Stack<V>();
+            Buffer<V> queue = new UnboundedFifoBuffer<V>();
+            queue.add(s);
+
+            while (!queue.isEmpty()) {
+                V v = queue.remove();
+                stack.push(v);
+
+                for(V w : getGraph().getSuccessors(v)) {
+
+                    if (decorator.get(w).distance < 0) {
+                        queue.add(w);
+                        decorator.get(w).distance = decorator.get(v).distance + 1;
+                    }
+
+                    if (decorator.get(w).distance == decorator.get(v).distance + 1) {
+                        decorator.get(w).numSPs += decorator.get(v).numSPs;
+                        decorator.get(w).predecessors.add(v);
+                    }
+                }
+            }
+            
+            while (!stack.isEmpty()) {
+                V w = stack.pop();
+
+                for (V v : decorator.get(w).predecessors) {
+
+                    double partialDependency = (decorator.get(v).numSPs / decorator.get(w).numSPs);
+                    partialDependency *= (1.0 + decorator.get(w).dependency);
+                    decorator.get(v).dependency +=  partialDependency;
+                    E currentEdge = getGraph().findEdge(v, w);
+                    double edgeValue = bcEdgeDecorator.get(currentEdge).doubleValue();
+                    edgeValue += partialDependency;
+                    bcEdgeDecorator.put(currentEdge, edgeValue);
+                }
+                if (w != s) {
+                       double bcValue = bcVertexDecorator.get(w).doubleValue();
+                       bcValue += decorator.get(w).dependency;
+                       bcVertexDecorator.put(w, bcValue);
+                }
+            }
+        }
+
+        if(graph instanceof UndirectedGraph) {
+            for (V v : vertices) { 
+               double bcValue = bcVertexDecorator.get(v).doubleValue();
+               bcValue /= 2.0;
+               bcVertexDecorator.put(v, bcValue);
+            }
+            for (E e : graph.getEdges()) {
+               double bcValue = bcEdgeDecorator.get(e).doubleValue();
+               bcValue /= 2.0;
+               bcEdgeDecorator.put(e, bcValue);
+            }
+        }
+
+        for (V vertex : vertices) {
+            decorator.remove(vertex);
+        }
+    }
+
+    private void initializeData(Graph<V,E> g, Map<V,BetweennessData> decorator) {
+        for (V vertex : g.getVertices()) {
+
+               Map<V,Number> bcVertexDecorator = vertexRankScores.get(getRankScoreKey());
+               if(bcVertexDecorator.containsKey(vertex) == false) {
+                       bcVertexDecorator.put(vertex, 0.0);
+               }
+            decorator.put(vertex, new BetweennessData());
+        }
+        for (E e : g.getEdges()) {
+
+               Map<E,Number> bcEdgeDecorator = edgeRankScores.get(getRankScoreKey());
+               if(bcEdgeDecorator.containsKey(e) == false) {
+                       bcEdgeDecorator.put(e, 0.0);
+               }
+        }
+    }
+    
+    /**
+     * the user datum key used to store the rank scores
+     * @return the key
+     */
+    @Override
+    public String getRankScoreKey() {
+        return CENTRALITY;
+    }
+
+    @Override
+    public void step() {
+        computeBetweenness(getGraph());
+    }
+
+    class BetweennessData {
+        double distance;
+        double numSPs;
+        List<V> predecessors;
+        double dependency;
+
+        BetweennessData() {
+            distance = -1;
+            numSPs = 0;
+            predecessors = new ArrayList<V>();
+            dependency = 0;
+        }
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/KStepMarkov.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/KStepMarkov.java
new file mode 100644 (file)
index 0000000..9ee4030
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.importance;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import edu.uci.ics.jung.graph.DirectedGraph;
+
+
+/**
+ * Algorithm variant of <code>PageRankWithPriors</code> that computes the importance of a node based upon taking fixed-length random
+ * walks out from the root set and then computing the stationary probability of being at each node. Specifically, it computes
+ * the relative probability that the markov chain will spend at any particular node, given that it start in the root
+ * set and ends after k steps.
+ * <p>
+ * A simple example of usage is:
+ * <pre>
+ * KStepMarkov ranker = new KStepMarkov(someGraph,rootSet,6,null);
+ * ranker.evaluate();
+ * ranker.printRankings();
+ * </pre>
+ * <p>
+ *
+ * @author Scott White
+ * @author Tom Nelson - adapter to jung2
+ * @see "Algorithms for Estimating Relative Importance in Graphs by Scott White and Padhraic Smyth, 2003"
+ */
+public class KStepMarkov<V,E> extends RelativeAuthorityRanker<V,E> {
+    public final static String RANK_SCORE = "jung.algorithms.importance.KStepMarkovExperimental.RankScore";
+    private final static String CURRENT_RANK = "jung.algorithms.importance.KStepMarkovExperimental.CurrentRank";
+    private int mNumSteps;
+    HashMap<V,Number> mPreviousRankingsMap;
+
+    /**
+     * Construct the algorihm instance and initializes the algorithm.
+     * @param graph the graph to be analyzed
+     * @param priors the set of root nodes
+     * @param k positive integer parameter which controls the relative tradeoff between a distribution "biased" towards
+     * R and the steady-state distribution which is independent of where the Markov-process started. Generally values
+     * between 4-8 are reasonable
+     * @param edgeWeights the weight for each edge 
+     */
+    public KStepMarkov(DirectedGraph<V,E> graph, Set<V> priors, int k, Map<E,Number> edgeWeights) {
+        super.initialize(graph,true,false);
+        mNumSteps = k;
+        setPriors(priors);
+        initializeRankings();
+        if (edgeWeights == null) {
+            assignDefaultEdgeTransitionWeights();
+        } else {
+            setEdgeWeights(edgeWeights);
+        }
+        normalizeEdgeTransitionWeights();
+    }
+
+    /**
+     * The user datum key used to store the rank scores.
+     * @return the key
+     */
+    @Override
+    public String getRankScoreKey() {
+        return RANK_SCORE;
+    }
+
+    protected void incrementRankScore(V v, double rankValue) {
+       double value = getVertexRankScore(v, RANK_SCORE);
+       value += rankValue;
+       setVertexRankScore(v, value, RANK_SCORE);
+    }
+
+    protected double getCurrentRankScore(V v) {
+       return getVertexRankScore(v, CURRENT_RANK);
+    }
+
+    protected void setCurrentRankScore(V v, double rankValue) {
+       setVertexRankScore(v, rankValue, CURRENT_RANK);
+    }
+
+    protected void initializeRankings() {
+         mPreviousRankingsMap = new HashMap<V,Number>();
+         for (V v : getVertices()) {
+            Set<V> priors = getPriors();
+            double numPriors = priors.size();
+
+            if (getPriors().contains(v)) {
+                setVertexRankScore(v, 1.0/ numPriors);
+                setCurrentRankScore(v, 1.0/ numPriors);
+                mPreviousRankingsMap.put(v,1.0/numPriors);
+            } else {
+                setVertexRankScore(v, 0);
+                setCurrentRankScore(v, 0);
+                mPreviousRankingsMap.put(v, 0);
+            }
+        }
+     }
+    @Override
+    public void step() {
+
+        for (int i=0;i<mNumSteps;i++) {
+            updateRankings();
+            for (V v : getVertices()) {
+                double currentRankScore = getCurrentRankScore(v);
+                incrementRankScore(v,currentRankScore);
+                mPreviousRankingsMap.put(v, currentRankScore);
+            }
+        }
+        normalizeRankings();
+    }
+
+    protected void updateRankings() {
+
+        for (V v : getVertices()) {
+
+            Collection<E> incomingEdges = getGraph().getInEdges(v);
+
+            double currentPageRankSum = 0;
+            for (E e : incomingEdges) {
+                double currentWeight = getEdgeWeight(e);
+                currentPageRankSum += 
+                       mPreviousRankingsMap.get(getGraph().getOpposite(v,e)).doubleValue()*currentWeight;
+            }
+            setCurrentRankScore(v,currentPageRankSum);
+        }
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/Ranking.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/Ranking.java
new file mode 100644 (file)
index 0000000..b96e559
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.importance;
+
+
+/**
+ * Abstract data container for ranking objects. Stores common data relevant to both node and edge rankings, namely,
+ * the original position of the instance in the list and the actual ranking score.
+ * @author Scott White
+ */
+public class Ranking<V> implements Comparable {
+    /**
+     * The original (0-indexed) position of the instance being ranked
+     */
+    public int originalPos;
+    /**
+     * The actual rank score (normally between 0 and 1)
+     */
+    public double rankScore;
+    
+    /**
+     * what is being ranked
+     */
+    private V ranked;
+
+    /**
+     * Constructor which allows values to be set on construction
+     * @param originalPos The original (0-indexed) position of the instance being ranked
+     * @param rankScore The actual rank score (normally between 0 and 1)
+     */
+    public Ranking(int originalPos, double rankScore, V ranked) {
+        this.originalPos = originalPos;
+        this.rankScore = rankScore;
+        this.ranked = ranked;
+    }
+
+    /**
+     * Compares two ranking based on the rank score.
+     * @param o The other ranking
+     * @return -1 if the other ranking is higher, 0 if they are equal, and 1 if this ranking is higher
+     */
+    public int compareTo(Object o) {
+
+        Ranking otherRanking = (Ranking) o;
+        return Double.compare(otherRanking.rankScore,rankScore);
+    }
+
+    /**
+     * Returns the rank score as a string.
+     * @return the stringified rank score
+     */
+    @Override
+    public String toString() {
+        return String.valueOf(rankScore);
+    }
+
+       /**
+        * @return the ranked
+        */
+       public V getRanked() {
+               return ranked;
+       }
+
+       /**
+        * @param ranked the ranked to set
+        */
+       public void setRanked(V ranked) {
+               this.ranked = ranked;
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/RelativeAuthorityRanker.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/RelativeAuthorityRanker.java
new file mode 100644 (file)
index 0000000..b40ba8d
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.importance;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * This class provides basic infrastructure for relative authority algorithms that compute the importance of nodes
+ * relative to one or more root nodes. The services provided are:
+ * <ul>
+ * <li>The set of root nodes (priors) is stored and maintained</li>
+ * <li>Getters and setters for the prior rank score are provided</li>
+ * </ul>
+ * 
+ * @author Scott White
+ */
+public abstract class RelativeAuthorityRanker<V,E> extends AbstractRanker<V,E> {
+    private Set<V> mPriors;
+    /**
+     * The default key used for the user datum key corresponding to prior rank scores.
+     */
+
+    protected Map<V,Number> priorRankScoreMap = new HashMap<V,Number>();
+    /**
+     * Cleans up all of the prior rank scores on finalize.
+     */
+    @Override
+    protected void finalizeIterations() {
+        super.finalizeIterations();
+        priorRankScoreMap.clear();
+    }
+
+    /**
+     * Retrieves the value of the prior rank score.
+     * @param v the root node (prior)
+     * @return the prior rank score
+     */
+    protected double getPriorRankScore(V v) {
+       return priorRankScoreMap.get(v).doubleValue();
+
+    }
+
+    /**
+     * Allows the user to specify a value to set for the prior rank score
+     * @param v the root node (prior)
+     * @param value the score to set to
+     */
+    public void setPriorRankScore(V v, double value) {
+       this.priorRankScoreMap.put(v, value);
+    }
+
+    /**
+     * Retrieves the set of priors.
+     * @return the set of root nodes (priors)
+     */
+    protected Set<V> getPriors() { return mPriors; }
+
+    /**
+     * Specifies which vertices are root nodes (priors).
+     * @param priors the root nodes
+     */
+    protected void setPriors(Set<V> priors) { mPriors = priors; }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/WeightedNIPaths.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/importance/WeightedNIPaths.java
new file mode 100644 (file)
index 0000000..bd715ce
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.importance;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections15.Factory;
+
+import edu.uci.ics.jung.graph.DirectedGraph;
+
+
+
+/**
+ * This algorithm measures the importance of nodes based upon both the number and length of disjoint paths that lead
+ * to a given node from each of the nodes in the root set. Specifically the formula for measuring the importance of a
+ * node is given by: I(t|R) = sum_i=1_|P(r,t)|_{alpha^|p_i|} where alpha is the path decay coefficient, p_i is path i
+ * and P(r,t) is a set of maximum-sized node-disjoint paths from r to t.
+ * <p>
+ * This algorithm uses heuristic breadth-first search to try and find the maximum-sized set of node-disjoint paths
+ * between two nodes. As such, it is not guaranteed to give exact answers.
+ * <p>
+ * A simple example of usage is:
+ * <pre>
+ * WeightedNIPaths ranker = new WeightedNIPaths(someGraph,2.0,6,rootSet);
+ * ranker.evaluate();
+ * ranker.printRankings();
+ * </pre>
+ * 
+ * @author Scott White
+ * @see "Algorithms for Estimating Relative Importance in Graphs by Scott White and Padhraic Smyth, 2003"
+ */
+public class WeightedNIPaths<V,E> extends AbstractRanker<V,E> {
+    public final static String WEIGHTED_NIPATHS_KEY = "jung.algorithms.importance.WEIGHTED_NIPATHS_KEY";
+    private double mAlpha;
+    private int mMaxDepth;
+    private Set<V> mPriors;
+    private Map<E,Number> pathIndices = new HashMap<E,Number>();
+    private Map<Object,V> roots = new HashMap<Object,V>();
+    private Map<V,Set<Number>> pathsSeenMap = new HashMap<V,Set<Number>>();
+    private Factory<V> vertexFactory;
+    private Factory<E> edgeFactory;
+
+    /**
+     * Constructs and initializes the algorithm.
+     * @param graph the graph whose nodes are being measured for their importance
+     * @param alpha the path decay coefficient (>= 1); 2 is recommended
+     * @param maxDepth the maximal depth to search out from the root set
+     * @param priors the root set (starting vertices)
+     */
+    public WeightedNIPaths(DirectedGraph<V,E> graph, Factory<V> vertexFactory,
+               Factory<E> edgeFactory, double alpha, int maxDepth, Set<V> priors) {
+        super.initialize(graph, true,false);
+        this.vertexFactory = vertexFactory;
+        this.edgeFactory = edgeFactory;
+        mAlpha = alpha;
+        mMaxDepth = maxDepth;
+        mPriors = priors;
+        for (V v : graph.getVertices()) {
+               super.setVertexRankScore(v, 0.0);
+        }
+    }
+
+    protected void incrementRankScore(V v, double rankValue) {
+        setVertexRankScore(v, getVertexRankScore(v) + rankValue);
+    }
+
+    protected void computeWeightedPathsFromSource(V root, int depth) {
+
+        int pathIdx = 1;
+
+        for (E e : getGraph().getOutEdges(root)) {
+            this.pathIndices.put(e, pathIdx);
+            this.roots.put(e, root);
+            newVertexEncountered(pathIdx, getGraph().getEndpoints(e).getSecond(), root);
+            pathIdx++;
+        }
+
+        List<E> edges = new ArrayList<E>();
+
+        V virtualNode = vertexFactory.create();
+        getGraph().addVertex(virtualNode);
+        E virtualSinkEdge = edgeFactory.create();
+
+        getGraph().addEdge(virtualSinkEdge, virtualNode, root);
+        edges.add(virtualSinkEdge);
+
+        int currentDepth = 0;
+        while (currentDepth <= depth) {
+
+            double currentWeight = Math.pow(mAlpha, -1.0 * currentDepth);
+            for (E currentEdge : edges) { 
+                incrementRankScore(getGraph().getEndpoints(currentEdge).getSecond(),//
+                               currentWeight);
+            }
+
+            if ((currentDepth == depth) || (edges.size() == 0)) break;
+
+            List<E> newEdges = new ArrayList<E>();
+
+            for (E currentSourceEdge : edges) { //Iterator sourceEdgeIt = edges.iterator(); sourceEdgeIt.hasNext();) {
+                Number sourcePathIndex = this.pathIndices.get(currentSourceEdge);
+
+                // from the currentSourceEdge, get its opposite end
+                // then iterate over the out edges of that opposite end
+                V newDestVertex = getGraph().getEndpoints(currentSourceEdge).getSecond();
+                Collection<E> outs = getGraph().getOutEdges(newDestVertex);
+                for (E currentDestEdge : outs) {
+                       V destEdgeRoot = this.roots.get(currentDestEdge);
+                       V destEdgeDest = getGraph().getEndpoints(currentDestEdge).getSecond();
+
+                    if (currentSourceEdge == virtualSinkEdge) {
+                        newEdges.add(currentDestEdge);
+                        continue;
+                    }
+                    if (destEdgeRoot == root) {
+                        continue;
+                    }
+                    if (destEdgeDest == getGraph().getEndpoints(currentSourceEdge).getFirst()) {//currentSourceEdge.getSource()) {
+                        continue;
+                    }
+                    Set<Number> pathsSeen = this.pathsSeenMap.get(destEdgeDest);
+
+                    if (pathsSeen == null) {
+                        newVertexEncountered(sourcePathIndex.intValue(), destEdgeDest, root);
+                    } else if (roots.get(destEdgeDest) != root) {
+                        roots.put(destEdgeDest,root);
+                        pathsSeen.clear();
+                        pathsSeen.add(sourcePathIndex);
+                    } else if (!pathsSeen.contains(sourcePathIndex)) {
+                        pathsSeen.add(sourcePathIndex);
+                    } else {
+                        continue;
+                    }
+
+                    this.pathIndices.put(currentDestEdge, sourcePathIndex);
+                    this.roots.put(currentDestEdge, root);
+                    newEdges.add(currentDestEdge);
+                }
+            }
+
+            edges = newEdges;
+            currentDepth++;
+        }
+
+        getGraph().removeVertex(virtualNode);
+    }
+
+    private void newVertexEncountered(int sourcePathIndex, V dest, V root) {
+        Set<Number> pathsSeen = new HashSet<Number>();
+        pathsSeen.add(sourcePathIndex);
+        this.pathsSeenMap.put(dest, pathsSeen);
+        roots.put(dest, root);
+    }
+
+    @Override
+    public void step() {
+        for (V v : mPriors) {
+            computeWeightedPathsFromSource(v, mMaxDepth);
+        }
+
+        normalizeRankings();
+//        return 0;
+    }
+    
+    /**
+     * Given a node, returns the corresponding rank score. This implementation of <code>getRankScore</code> assumes
+     * the decoration representing the rank score is of type <code>MutableDouble</code>.
+     * @return  the rank score for this node
+     */
+    @Override
+    public String getRankScoreKey() {
+        return WEIGHTED_NIPATHS_KEY;
+    }
+
+    @Override
+    protected void onFinalize(Object udc) {
+       pathIndices.remove(udc);
+       roots.remove(udc);
+       pathsSeenMap.remove(udc);
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/AbstractLayout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/AbstractLayout.java
new file mode 100644 (file)
index 0000000..b59dcfa
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ * 
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ * 
+ * Created on Jul 7, 2003
+ * 
+ */
+package edu.uci.ics.jung.algorithms.layout;
+
+import java.awt.Dimension;
+import java.awt.geom.Point2D;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections15.Transformer;
+import org.apache.commons.collections15.functors.ChainedTransformer;
+import org.apache.commons.collections15.functors.CloneTransformer;
+import org.apache.commons.collections15.map.LazyMap;
+
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * Abstract class for implementations of {@code Layout}.  It handles some of the
+ * basic functions: storing coordinates, maintaining the dimensions, initializing
+ * the locations, maintaining locked vertices.
+ * 
+ * @author Danyel Fisher, Scott White
+ * @author Tom Nelson - converted to jung2
+ * @param <V> the vertex type
+ * @param <E> the edge type
+ */
+abstract public class AbstractLayout<V, E> implements Layout<V,E> {
+
+    /**
+     * a set of vertices that should not move in relation to the
+     * other vertices
+     */
+       private Set<V> dontmove = new HashSet<V>();
+
+       protected Dimension size;
+       protected Graph<V, E> graph;
+       protected boolean initialized;
+    
+    protected Map<V, Point2D> locations = 
+       LazyMap.decorate(new HashMap<V, Point2D>(),
+                       new Transformer<V,Point2D>() {
+                                       public Point2D transform(V arg0) {
+                                               return new Point2D.Double();
+                                       }});
+
+
+       /**
+        * Creates an instance which does not initialize the vertex locations.
+        * 
+        * @param graph the graph for which the layout algorithm is to be created.
+        */
+       protected AbstractLayout(Graph<V, E> graph) {
+           if (graph == null) 
+           {
+               throw new IllegalArgumentException("Graph must be non-null");
+           }
+               this.graph = graph;
+       }
+       
+    @SuppressWarnings("unchecked")
+    protected AbstractLayout(Graph<V,E> graph, Transformer<V,Point2D> initializer) {
+               this.graph = graph;
+               Transformer<V, ? extends Object> chain = 
+                       ChainedTransformer.getInstance(initializer, CloneTransformer.getInstance());
+               this.locations = LazyMap.decorate(new HashMap<V,Point2D>(), (Transformer<V,Point2D>)chain);
+               initialized = true;
+       }
+       
+       protected AbstractLayout(Graph<V,E> graph, Dimension size) {
+               this.graph = graph;
+               this.size = size;
+       }
+       
+       @SuppressWarnings("unchecked")
+    protected AbstractLayout(Graph<V,E> graph, Transformer<V,Point2D> initializer, Dimension size) {
+               this.graph = graph;
+               Transformer<V, ? extends Object> chain = 
+                       ChainedTransformer.getInstance(initializer, CloneTransformer.getInstance());
+               this.locations = LazyMap.decorate(new HashMap<V,Point2D>(), (Transformer<V,Point2D>)chain);
+               this.size = size;
+       }
+    
+    public void setGraph(Graph<V,E> graph) {
+        this.graph = graph;
+        if(size != null && graph != null) {
+               initialize();
+        }
+    }
+    
+       /**
+        * When a visualization is resized, it presumably wants to fix the
+        * locations of the vertices and possibly to reinitialize its data. The
+        * current method calls <tt>initializeLocations</tt> followed by <tt>initialize_local</tt>.
+        */
+       public void setSize(Dimension size) {
+               
+               if(size != null && graph != null) {
+                       
+                       Dimension oldSize = this.size;
+                       this.size = size;
+                       initialize();
+                       
+                       if(oldSize != null) {
+                               adjustLocations(oldSize, size);
+                       }
+               }
+       }
+       
+       private void adjustLocations(Dimension oldSize, Dimension size) {
+
+               int xOffset = (size.width - oldSize.width) / 2;
+               int yOffset = (size.height - oldSize.height) / 2;
+
+               // now, move each vertex to be at the new screen center
+               while(true) {
+                   try {
+                for(V v : getGraph().getVertices()) {
+                           offsetVertex(v, xOffset, yOffset);
+                       }
+                       break;
+                   } catch(ConcurrentModificationException cme) {
+                   }
+               }
+       }
+    
+    public boolean isLocked(V v) {
+        return dontmove.contains(v);
+    }
+    
+    @SuppressWarnings("unchecked")
+    public void setInitializer(Transformer<V,Point2D> initializer) {
+       if(this.equals(initializer)) {
+               throw new IllegalArgumentException("Layout cannot be initialized with itself");
+       }
+               Transformer<V, ? extends Object> chain = 
+                       ChainedTransformer.getInstance(initializer, CloneTransformer.getInstance());
+       this.locations = LazyMap.decorate(new HashMap<V,Point2D>(), (Transformer<V, Point2D>)chain);
+       initialized = true;
+    }
+    
+       /**
+        * Returns the current size of the visualization space, accoring to the
+        * last call to resize().
+        * 
+        * @return the current size of the screen
+        */
+       public Dimension getSize() {
+               return size;
+       }
+
+       /**
+        * Returns the Coordinates object that stores the vertex' x and y location.
+        * 
+        * @param v
+        *            A Vertex that is a part of the Graph being visualized.
+        * @return A Coordinates object with x and y locations.
+        */
+       private Point2D getCoordinates(V v) {
+        return locations.get(v);
+       }
+       
+       public Point2D transform(V v) {
+               return getCoordinates(v);
+       }
+       
+       /**
+        * Returns the x coordinate of the vertex from the Coordinates object.
+        * in most cases you will be better off calling transform(v).
+        */
+       public double getX(V v) {
+        assert getCoordinates(v) != null : "Cannot getX for an unmapped vertex "+v;
+        return getCoordinates(v).getX();
+       }
+
+       /**
+        * Returns the y coordinate of the vertex from the Coordinates object.
+        * In most cases you will be better off calling transform(v).
+        */
+       public double getY(V v) {
+        assert getCoordinates(v) != null : "Cannot getY for an unmapped vertex "+v;
+        return getCoordinates(v).getY();
+       }
+       
+       /**
+        * @param v
+        * @param xOffset
+        * @param yOffset
+        */
+       protected void offsetVertex(V v, double xOffset, double yOffset) {
+               Point2D c = getCoordinates(v);
+        c.setLocation(c.getX()+xOffset, c.getY()+yOffset);
+               setLocation(v, c);
+       }
+
+       /**
+        * Accessor for the graph that represets all vertices.
+        * 
+        * @return the graph that contains all vertices.
+        */
+       public Graph<V, E> getGraph() {
+           return graph;
+       }
+       
+       /**
+        * Forcibly moves a vertex to the (x,y) location by setting its x and y
+        * locations to the inputted location. Does not add the vertex to the
+        * "dontmove" list, and (in the default implementation) does not make any
+        * adjustments to the rest of the graph.
+        */
+       public void setLocation(V picked, double x, double y) {
+               Point2D coord = getCoordinates(picked);
+               coord.setLocation(x, y);
+       }
+
+       public void setLocation(V picked, Point2D p) {
+               Point2D coord = getCoordinates(picked);
+               coord.setLocation(p);
+       }
+
+       /**
+        * Locks {@code v} in place if {@code state} is {@code true}, otherwise unlocks it.
+        */
+       public void lock(V v, boolean state) {
+               if(state == true) 
+                   dontmove.add(v);
+               else 
+                   dontmove.remove(v);
+       }
+       
+       /**
+        * Locks all vertices in place if {@code lock} is {@code true}, otherwise unlocks all vertices.
+        */
+       public void lock(boolean lock) {
+               for(V v : graph.getVertices()) {
+                       lock(v, lock);
+               }
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/AggregateLayout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/AggregateLayout.java
new file mode 100644 (file)
index 0000000..3805837
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ * 
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ * 
+ * 
+ * 
+ */
+package edu.uci.ics.jung.algorithms.layout;
+
+import java.awt.Dimension;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.util.IterativeContext;
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * A {@code Layout} implementation that combines 
+ * multiple other layouts so that they may be manipulated
+ * as one layout. The relaxer thread will step each layout
+ * in sequence.
+ * 
+ * @author Tom Nelson - tomnelson@dev.java.net
+ *
+ * @param <V> the vertex type
+ * @param <E> the edge type
+ */
+public class AggregateLayout<V, E> implements Layout<V,E>, IterativeContext {
+
+       protected Layout<V,E> delegate;
+       protected Map<Layout<V,E>,Point2D> layouts = new HashMap<Layout<V,E>,Point2D>();
+
+       /**
+        * Creates an instance backed by the specified {@code delegate}.
+        * @param delegate
+        */
+       public AggregateLayout(Layout<V, E> delegate) {
+               this.delegate = delegate;
+       }
+
+       /**
+        * @return the delegate
+        */
+       public Layout<V, E> getDelegate() {
+               return delegate;
+       }
+
+       /**
+        * @param delegate the delegate to set
+        */
+       public void setDelegate(Layout<V, E> delegate) {
+               this.delegate = delegate;
+       }
+
+       /**
+        * adds the passed layout as a sublayout, also specifying
+        * the center of where this sublayout should appear
+        * @param layout
+        * @param center
+        */
+       public void put(Layout<V,E> layout, Point2D center) {
+               layouts.put(layout,center);
+       }
+       
+       /**
+        * Returns the center of the passed layout.
+        * @param layout
+        * @return the center of the passed layout
+        */
+       public Point2D get(Layout<V,E> layout) {
+               return layouts.get(layout);
+       }
+       
+       /**
+        * Removes {@code layout} from this instance.
+        */
+       public void remove(Layout<V,E> layout) {
+               layouts.remove(layout);
+       }
+       
+       /**
+        * Removes all layouts from this instance.
+        */
+       public void removeAll() {
+               layouts.clear();
+       }
+       
+       /**
+        * Returns the graph for which this layout is defined.
+        * @return the graph for which this layout is defined
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#getGraph()
+        */
+       public Graph<V, E> getGraph() {
+               return delegate.getGraph();
+       }
+
+       /**
+        * Returns the size of the underlying layout.
+        * @return the size of the underlying layout
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#getSize()
+        */
+       public Dimension getSize() {
+               return delegate.getSize();
+       }
+
+       /**
+        * 
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#initialize()
+        */
+       public void initialize() {
+               delegate.initialize();
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       layout.initialize();
+               }
+       }
+
+       /**
+        * Override to test if the passed vertex is locked in
+        * any of the layouts.
+        * @param v
+        * @return true if v is locked in any of the layouts, and false otherwise
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#isLocked(java.lang.Object)
+        */
+       public boolean isLocked(V v) {
+               boolean locked = false;
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       locked |= layout.isLocked(v);
+               }
+               locked |= delegate.isLocked(v);
+               return locked;
+       }
+
+       /**
+        * override to lock or unlock this vertex in any layout with
+        * a subgraph containing it
+        * @param v
+        * @param state
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#lock(java.lang.Object, boolean)
+        */
+       public void lock(V v, boolean state) {
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       if(layout.getGraph().getVertices().contains(v)) {
+                               layout.lock(v, state);
+                       }
+               }
+               delegate.lock(v, state);
+       }
+
+       /**
+        * 
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#reset()
+        */
+       public void reset() {
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       layout.reset();
+               }
+               delegate.reset();
+       }
+
+       /**
+        * @param graph
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#setGraph(edu.uci.ics.jung.graph.Graph)
+        */
+       public void setGraph(Graph<V, E> graph) {
+               delegate.setGraph(graph);
+       }
+
+       /**
+        * @param initializer
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#setInitializer(org.apache.commons.collections15.Transformer)
+        */
+       public void setInitializer(Transformer<V, Point2D> initializer) {
+               delegate.setInitializer(initializer);
+       }
+
+       /**
+        * @param v
+        * @param location
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#setLocation(java.lang.Object, java.awt.geom.Point2D)
+        */
+       public void setLocation(V v, Point2D location) {
+               boolean wasInSublayout = false;
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       if(layout.getGraph().getVertices().contains(v)) {
+                               Point2D center = layouts.get(layout);
+                               // transform by the layout itself, but offset to the
+                               // center of the sublayout
+                               Dimension d = layout.getSize();
+
+                               AffineTransform at = 
+                                       AffineTransform.getTranslateInstance(-center.getX()+d.width/2,-center.getY()+d.height/2);
+                               Point2D localLocation = at.transform(location, null);
+                               layout.setLocation(v, localLocation);
+                               wasInSublayout = true;
+                       }
+               }
+               if(wasInSublayout == false && getGraph().getVertices().contains(v)) {
+                       delegate.setLocation(v, location);
+               }
+       }
+
+       /**
+        * @param d
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#setSize(java.awt.Dimension)
+        */
+       public void setSize(Dimension d) {
+               delegate.setSize(d);
+       }
+       
+       /**
+        * Returns a map from each {@code Layout} instance to its center point.
+        */
+       public Map<Layout<V,E>,Point2D> getLayouts() {
+               return layouts;
+       }
+
+       /**
+        * Returns the location of the vertex.  The location is specified first
+        * by the sublayouts, and then by the base layout if no sublayouts operate
+        * on this vertex.
+        * @return the location of the vertex
+        * @see org.apache.commons.collections15.Transformer#transform(java.lang.Object)
+        */
+       public Point2D transform(V v) {
+               boolean wasInSublayout = false;
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       if(layout.getGraph().getVertices().contains(v)) {
+                               wasInSublayout = true;
+                               Point2D center = layouts.get(layout);
+                               // transform by the layout itself, but offset to the
+                               // center of the sublayout
+                               Dimension d = layout.getSize();
+                               AffineTransform at = 
+                                       AffineTransform.getTranslateInstance(center.getX()-d.width/2,
+                                                       center.getY()-d.height/2);
+                               return at.transform(layout.transform(v),null);
+                       }
+               }
+               if(wasInSublayout == false) {
+                       return delegate.transform(v);
+               }
+               return null;
+       
+       }
+
+       /**
+        * Check all sublayouts.keySet() and the delegate layout, returning
+        * done == true iff all are done.
+        */
+       public boolean done() {
+               boolean done = true;
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       if(layout instanceof IterativeContext) {
+                               done &= ((IterativeContext)layout).done();
+                       }
+               }
+               if(delegate instanceof IterativeContext) {
+                       done &= ((IterativeContext)delegate).done();
+               }
+               return done;
+       }
+
+       /**
+        * call step on any sublayout that is also an IterativeContext
+        * and is not done
+        */
+       public void step() {
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       if(layout instanceof IterativeContext) {
+                               IterativeContext context = (IterativeContext)layout;
+                               if(context.done() == false) {
+                                       context.step();
+                               }
+                       }
+               }
+               if(delegate instanceof IterativeContext) {
+                       IterativeContext context = (IterativeContext)delegate;
+                       if(context.done() == false) {
+                               context.step();
+                       }
+               }
+       }
+       
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/BalloonLayout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/BalloonLayout.java
new file mode 100644 (file)
index 0000000..1d9f384
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2005, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ *
+ * Created on Jul 9, 2005
+ */
+
+package edu.uci.ics.jung.algorithms.layout;
+import java.awt.Dimension;
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections15.Transformer;
+import org.apache.commons.collections15.map.LazyMap;
+
+import edu.uci.ics.jung.graph.Forest;
+import edu.uci.ics.jung.graph.util.TreeUtils;
+
+/**
+ * A {@code Layout} implementation that assigns positions to {@code Tree} or 
+ * {@code Forest} vertices using associations with nested circles ("balloons").  
+ * A balloon is nested inside another balloon if the first balloon's subtree
+ * is a subtree of the second balloon's subtree.
+ * 
+ * @author Tom Nelson 
+ *  
+ */
+public class BalloonLayout<V,E> extends TreeLayout<V,E> {
+
+    protected Map<V,PolarPoint> polarLocations =
+       LazyMap.decorate(new HashMap<V, PolarPoint>(),
+                       new Transformer<V,PolarPoint>() {
+                                       public PolarPoint transform(V arg0) {
+                                               return new PolarPoint();
+                                       }});
+    
+    protected Map<V,Double> radii = new HashMap<V,Double>();
+    
+    /**
+     * Creates an instance based on the input forest.
+     */
+    public BalloonLayout(Forest<V,E> g) 
+    {
+        super(g);
+    }
+    
+    protected void setRootPolars() 
+    {
+        List<V> roots = TreeUtils.getRoots(graph);
+        if(roots.size() == 1) {
+               // its a Tree
+               V root = roots.get(0);
+               setRootPolar(root);
+            setPolars(new ArrayList<V>(graph.getChildren(root)),
+                    getCenter(), getSize().width/2);
+       } else if (roots.size() > 1) {
+               // its a Forest
+               setPolars(roots, getCenter(), getSize().width/2);
+       }
+    }
+    
+    protected void setRootPolar(V root) {
+       PolarPoint pp = new PolarPoint(0,0);
+       Point2D p = getCenter();
+       polarLocations.put(root, pp);
+       locations.put(root, p);
+    }
+    
+
+    protected void setPolars(List<V> kids, Point2D parentLocation, double parentRadius) {
+
+       int childCount = kids.size();
+       if(childCount == 0) return;
+       // handle the 1-child case with 0 limit on angle.
+       double angle = Math.max(0, Math.PI / 2 * (1 - 2.0/childCount));
+       double childRadius = parentRadius*Math.cos(angle) / (1 + Math.cos(angle));
+       double radius = parentRadius - childRadius;
+
+       double rand = Math.random();
+
+       for(int i=0; i< childCount; i++) {
+               V child = kids.get(i);
+               double theta = i* 2*Math.PI/childCount + rand;
+               radii.put(child, childRadius);
+               
+               PolarPoint pp = new PolarPoint(theta, radius);
+               polarLocations.put(child, pp);
+               
+               Point2D p = PolarPoint.polarToCartesian(pp);
+               p.setLocation(p.getX()+parentLocation.getX(), p.getY()+parentLocation.getY());
+               locations.put(child, p);
+               setPolars(new ArrayList<V>(graph.getChildren(child)), p, childRadius);
+       }
+    }
+
+    @Override
+    public void setSize(Dimension size) {
+       this.size = size;
+       setRootPolars();
+    }
+
+       /**
+        * Returns the coordinates of {@code v}'s parent, or the
+        * center of this layout's area if it's a root.
+        */
+       public Point2D getCenter(V v) {
+               V parent = graph.getParent(v);
+               if(parent == null) {
+                       return getCenter();
+               }
+               return locations.get(parent);
+       }
+
+       @Override
+    public void setLocation(V v, Point2D location) {
+               Point2D c = getCenter(v);
+               Point2D pv = new Point2D.Double(location.getX()-c.getX(),location.getY()-c.getY());
+               PolarPoint newLocation = PolarPoint.cartesianToPolar(pv);
+               polarLocations.get(v).setLocation(newLocation);
+               
+               Point2D center = getCenter(v);
+               pv.setLocation(pv.getX()+center.getX(), pv.getY()+center.getY());
+               locations.put(v, pv);
+       }
+
+       @Override
+    public Point2D transform(V v) {
+               return locations.get(v);
+       }
+
+       /**
+        * @return the radii
+        */
+       public Map<V, Double> getRadii() {
+               return radii;
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/CircleLayout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/CircleLayout.java
new file mode 100644 (file)
index 0000000..8cafb77
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+/*
+ * Created on Dec 4, 2003
+ */
+package edu.uci.ics.jung.algorithms.layout;
+
+import java.awt.Dimension;
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections15.Factory;
+import org.apache.commons.collections15.map.LazyMap;
+
+import edu.uci.ics.jung.graph.Graph;
+
+
+
+/**
+ * A {@code Layout} implementation that positions vertices equally spaced on a regular circle.
+ *
+ * @author Masanori Harada
+ */
+public class CircleLayout<V, E> extends AbstractLayout<V,E> {
+
+       private double radius;
+       private List<V> vertex_ordered_list;
+       
+       Map<V, CircleVertexData> circleVertexDataMap =
+                       LazyMap.decorate(new HashMap<V,CircleVertexData>(), 
+                       new Factory<CircleVertexData>() {
+                               public CircleVertexData create() {
+                                       return new CircleVertexData();
+                               }});    
+
+       /**
+        * Creates an instance for the specified graph.
+        */
+       public CircleLayout(Graph<V,E> g) {
+               super(g);
+       }
+
+       /**
+        * Returns the radius of the circle.
+        */
+       public double getRadius() {
+               return radius;
+       }
+
+       /**
+        * Sets the radius of the circle.  Must be called before
+        * {@code initialize()} is called.
+        */
+       public void setRadius(double radius) {
+               this.radius = radius;
+       }
+
+       /**
+        * Sets the order of the vertices in the layout according to the ordering
+        * specified by {@code comparator}.
+        */
+       public void setVertexOrder(Comparator<V> comparator)
+       {
+           if (vertex_ordered_list == null)
+               vertex_ordered_list = new ArrayList<V>(getGraph().getVertices());
+           Collections.sort(vertex_ordered_list, comparator);
+       }
+
+    /**
+     * Sets the order of the vertices in the layout according to the ordering
+     * of {@code vertex_list}.
+     */
+       public void setVertexOrder(List<V> vertex_list)
+       {
+           if (!vertex_list.containsAll(getGraph().getVertices())) 
+               throw new IllegalArgumentException("Supplied list must include " +
+                               "all vertices of the graph");
+           this.vertex_ordered_list = vertex_list;
+       }
+       
+       public void reset() {
+               initialize();
+       }
+
+       public void initialize() 
+       {
+               Dimension d = getSize();
+               
+               if (d != null) 
+               {
+                   if (vertex_ordered_list == null) 
+                       setVertexOrder(new ArrayList<V>(getGraph().getVertices()));
+
+                       double height = d.getHeight();
+                       double width = d.getWidth();
+
+                       if (radius <= 0) {
+                               radius = 0.45 * (height < width ? height : width);
+                       }
+
+                       int i = 0;
+                       for (V v : vertex_ordered_list)
+                       {
+                               Point2D coord = transform(v);
+
+                               double angle = (2 * Math.PI * i) / vertex_ordered_list.size();
+
+                               coord.setLocation(Math.cos(angle) * radius + width / 2,
+                                               Math.sin(angle) * radius + height / 2);
+
+                               CircleVertexData data = getCircleData(v);
+                               data.setAngle(angle);
+                               i++;
+                       }
+               }
+       }
+
+       protected CircleVertexData getCircleData(V v) {
+               return circleVertexDataMap.get(v);
+       }
+
+       protected static class CircleVertexData {
+               private double angle;
+
+               protected double getAngle() {
+                       return angle;
+               }
+
+               protected void setAngle(double angle) {
+                       this.angle = angle;
+               }
+
+               @Override
+               public String toString() {
+                       return "CircleVertexData: angle=" + angle;
+               }
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/DAGLayout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/DAGLayout.java
new file mode 100644 (file)
index 0000000..97d3ee6
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ *
+ * Created on Dec 4, 2003
+ */
+package edu.uci.ics.jung.algorithms.layout;
+
+import java.awt.Dimension;
+import java.awt.geom.Point2D;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.Pair;
+
+/**
+ * An implementation of {@code Layout} suitable for tree-like directed
+ * acyclic graphs. Parts of it will probably not terminate if the graph is
+ * cyclic! The layout will result in directed edges pointing generally upwards.
+ * Any vertices with no successors are considered to be level 0, and tend
+ * towards the top of the layout. Any vertex has a level one greater than the
+ * maximum level of all its successors.
+ *
+ *
+ * @author John Yesberg
+ */
+public class DAGLayout<V, E> extends SpringLayout<V,E> {
+
+    /**
+     * Each vertex has a minimumLevel. Any vertex with no successors has
+     * minimumLevel of zero. The minimumLevel of any vertex must be strictly
+     * greater than the minimumLevel of its parents. (Vertex A is a parent of
+     * Vertex B iff there is an edge from B to A.) Typically, a vertex will
+     * have a minimumLevel which is one greater than the minimumLevel of its
+     * parent's. However, if the vertex has two parents, its minimumLevel will
+     * be one greater than the maximum of the parents'. We need to calculate
+     * the minimumLevel for each vertex. When we layout the graph, vertices
+     * cannot be drawn any higher than the minimumLevel. The graphHeight of a
+     * graph is the greatest minimumLevel that is used. We will modify the
+     * SpringLayout calculations so that nodes cannot move above their assigned
+     * minimumLevel.
+     */
+       private Map<V,Number> minLevels = new HashMap<V,Number>();
+       // Simpler than the "pair" technique.
+       static int graphHeight;
+       static int numRoots;
+       final double SPACEFACTOR = 1.3;
+       // How much space do we allow for additional floating at the bottom.
+       final double LEVELATTRACTIONRATE = 0.8;
+
+       /**
+        * A bunch of parameters to help work out when to stop quivering.
+        *
+        * If the MeanSquareVel(ocity) ever gets below the MSV_THRESHOLD, then we
+        * will start a final cool-down phase of COOL_DOWN_INCREMENT increments. If
+        * the MeanSquareVel ever exceeds the threshold, we will exit the cool down
+        * phase, and continue looking for another opportunity.
+        */
+       final double MSV_THRESHOLD = 10.0;
+       double meanSquareVel;
+       boolean stoppingIncrements = false;
+       int incrementsLeft;
+       final int COOL_DOWN_INCREMENTS = 200;
+
+       /**
+        * Creates an instance for the specified graph.
+        */
+       public DAGLayout(Graph<V,E> g) {
+               super(g);
+       }
+
+       /**
+        * setRoot calculates the level of each vertex in the graph. Level 0 is
+        * allocated to any vertex with no successors. Level n+1 is allocated to
+        * any vertex whose successors' maximum level is n.
+        */
+       public void setRoot(Graph<V,E> g) {
+               numRoots = 0;
+               for(V v : g.getVertices()) {
+                       Collection<V> successors = getGraph().getSuccessors(v);
+                       if (successors.size() == 0) {
+                               setRoot(v);
+                               numRoots++;
+                       }
+               }
+       }
+
+       /**
+        * Set vertex v to be level 0.
+        */
+       public void setRoot(V v) {
+               minLevels.put(v, new Integer(0));
+               // set all the levels.
+               propagateMinimumLevel(v);
+       }
+
+       /**
+        * A recursive method for allocating the level for each vertex. Ensures
+        * that all predecessors of v have a level which is at least one greater
+        * than the level of v.
+        *
+        * @param v
+        */
+       public void propagateMinimumLevel(V v) {
+               int level = minLevels.get(v).intValue();
+               for(V child : getGraph().getPredecessors(v)) {
+                       int oldLevel, newLevel;
+                       Number o = minLevels.get(child);
+                       if (o != null)
+                               oldLevel = o.intValue();
+                       else
+                               oldLevel = 0;
+                       newLevel = Math.max(oldLevel, level + 1);
+                       minLevels.put(child, new Integer(newLevel));
+
+                       if (newLevel > graphHeight)
+                               graphHeight = newLevel;
+                       propagateMinimumLevel(child);
+               }
+       }
+
+       /**
+        * Sets random locations for a vertex within the dimensions of the space.
+        * This overrides the method in AbstractLayout
+        *
+        * @param coord
+        * @param d
+        */
+       private void initializeLocation(
+               V v,
+               Point2D coord,
+               Dimension d) {
+
+               int level = minLevels.get(v).intValue();
+               int minY = (int) (level * d.getHeight() / (graphHeight * SPACEFACTOR));
+               double x = Math.random() * d.getWidth();
+               double y = Math.random() * (d.getHeight() - minY) + minY;
+               coord.setLocation(x,y);
+       }
+
+       @Override
+       public void setSize(Dimension size) {
+               super.setSize(size);
+               for(V v : getGraph().getVertices()) {
+                       initializeLocation(v,transform(v),getSize());
+               }
+       }
+
+       /**
+        * Had to override this one as well, to ensure that setRoot() is called.
+        */
+       @Override
+       public void initialize() {
+               super.initialize();
+               setRoot(getGraph());
+       }
+
+       /**
+        * Override the moveNodes() method from SpringLayout. The only change we
+        * need to make is to make sure that nodes don't float higher than the minY
+        * coordinate, as calculated by their minimumLevel.
+        */
+       @Override
+       protected void moveNodes() {
+               // Dimension d = currentSize;
+               double oldMSV = meanSquareVel;
+               meanSquareVel = 0;
+
+               synchronized (getSize()) {
+
+                       for(V v : getGraph().getVertices()) {
+                               if (isLocked(v))
+                                       continue;
+                               SpringLayout.SpringVertexData vd = springVertexData.get(v);
+                               Point2D xyd = transform(v);
+
+                               int width = getSize().width;
+                               int height = getSize().height;
+
+                               // (JY addition: three lines are new)
+                               int level =
+                                       minLevels.get(v).intValue();
+                               int minY = (int) (level * height / (graphHeight * SPACEFACTOR));
+                               int maxY =
+                                       level == 0
+                                               ? (int) (height / (graphHeight * SPACEFACTOR * 2))
+                                               : height;
+
+                               // JY added 2* - double the sideways repulsion.
+                               vd.dx += 2 * vd.repulsiondx + vd.edgedx;
+                               vd.dy += vd.repulsiondy + vd.edgedy;
+
+                               // JY Addition: Attract the vertex towards it's minimumLevel
+                               // height.
+                               double delta = xyd.getY() - minY;
+                               vd.dy -= delta * LEVELATTRACTIONRATE;
+                               if (level == 0)
+                                       vd.dy -= delta * LEVELATTRACTIONRATE;
+                               // twice as much at the top.
+
+                               // JY addition:
+                               meanSquareVel += (vd.dx * vd.dx + vd.dy * vd.dy);
+
+                               // keeps nodes from moving any faster than 5 per time unit
+                               xyd.setLocation(xyd.getX()+Math.max(-5, Math.min(5, vd.dx)) , xyd.getY()+Math.max(-5, Math.min(5, vd.dy)) );
+
+                               if (xyd.getX() < 0) {
+                                       xyd.setLocation(0, xyd.getY());
+                               } else if (xyd.getX() > width) {
+                                       xyd.setLocation(width, xyd.getY());
+                               }
+
+                               // (JY addition: These two lines replaced 0 with minY)
+                               if (xyd.getY() < minY) {
+                                       xyd.setLocation(xyd.getX(), minY);
+                                       // (JY addition: replace height with maxY)
+                               } else if (xyd.getY() > maxY) {
+                                       xyd.setLocation(xyd.getX(), maxY);
+                               }
+
+                               // (JY addition: if there's only one root, anchor it in the
+                               // middle-top of the screen)
+                               if (numRoots == 1 && level == 0) {
+                                       xyd.setLocation(width/2, xyd.getY());
+                               }
+                       }
+               }
+               //System.out.println("MeanSquareAccel="+meanSquareVel);
+               if (!stoppingIncrements
+                       && Math.abs(meanSquareVel - oldMSV) < MSV_THRESHOLD) {
+                       stoppingIncrements = true;
+                       incrementsLeft = COOL_DOWN_INCREMENTS;
+               } else if (
+                       stoppingIncrements
+                               && Math.abs(meanSquareVel - oldMSV) <= MSV_THRESHOLD) {
+                       incrementsLeft--;
+                       if (incrementsLeft <= 0)
+                               incrementsLeft = 0;
+               }
+       }
+
+       /**
+        * Override incrementsAreDone so that we can eventually stop.
+        */
+       @Override
+       public boolean done() {
+               if (stoppingIncrements && incrementsLeft == 0)
+                       return true;
+               else
+                       return false;
+       }
+
+       /**
+        * Override forceMove so that if someone moves a node, we can re-layout
+        * everything.
+        */
+       @Override
+       public void setLocation(V picked, double x, double y) {
+               Point2D coord = transform(picked);
+               coord.setLocation(x,y);
+               stoppingIncrements = false;
+       }
+
+       /**
+        * Override forceMove so that if someone moves a node, we can re-layout
+        * everything.
+        */
+       @Override
+       public void setLocation(V picked, Point2D p) {
+               Point2D coord = transform(picked);
+               coord.setLocation(p);
+               stoppingIncrements = false;
+       }
+
+       /**
+        * Overridden relaxEdges. This one reduces the effect of edges between
+        * greatly different levels.
+        *
+        */
+       @Override
+       protected void relaxEdges() {
+               for(E e : getGraph().getEdges()) {
+                   Pair<V> endpoints = getGraph().getEndpoints(e);
+                       V v1 = endpoints.getFirst();
+                       V v2 = endpoints.getSecond();
+
+                       Point2D p1 = transform(v1);
+                       Point2D p2 = transform(v2);
+                       double vx = p1.getX() - p2.getX();
+                       double vy = p1.getY() - p2.getY();
+                       double len = Math.sqrt(vx * vx + vy * vy);
+
+                       // JY addition.
+                       int level1 =
+                               minLevels.get(v1).intValue();
+                       int level2 =
+                               minLevels.get(v2).intValue();
+
+                       // desiredLen *= Math.pow( 1.1, (v1.degree() + v2.degree()) );
+//          double desiredLen = getLength(e);
+                       double desiredLen = lengthFunction.transform(e);
+
+                       // round from zero, if needed [zero would be Bad.].
+                       len = (len == 0) ? .0001 : len;
+
+                       // force factor: optimal length minus actual length,
+                       // is made smaller as the current actual length gets larger.
+                       // why?
+
+                       // System.out.println("Desired : " + getLength( e ));
+                       double f = force_multiplier * (desiredLen - len) / len;
+
+                       f = f * Math.pow(stretch / 100.0,
+                                       (getGraph().degree(v1) + getGraph().degree(v2) -2));
+
+                       // JY addition. If this is an edge which stretches a long way,
+                       // don't be so concerned about it.
+                       if (level1 != level2)
+                               f = f / Math.pow(Math.abs(level2 - level1), 1.5);
+
+                       // f= Math.min( 0, f );
+
+                       // the actual movement distance 'dx' is the force multiplied by the
+                       // distance to go.
+                       double dx = f * vx;
+                       double dy = f * vy;
+                       SpringVertexData v1D, v2D;
+                       v1D = springVertexData.get(v1);
+                       v2D = springVertexData.get(v2);
+
+//                     SpringEdgeData<E> sed = getSpringEdgeData(e);
+//                     sed.f = f;
+
+                       v1D.edgedx += dx;
+                       v1D.edgedy += dy;
+                       v2D.edgedx += -dx;
+                       v2D.edgedy += -dy;
+               }
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/FRLayout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/FRLayout.java
new file mode 100644 (file)
index 0000000..c8a2a24
--- /dev/null
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.layout;
+
+import edu.uci.ics.jung.algorithms.layout.util.RandomLocationTransformer;
+import edu.uci.ics.jung.algorithms.util.IterativeContext;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.Pair;
+
+import org.apache.commons.collections15.Factory;
+import org.apache.commons.collections15.map.LazyMap;
+
+import java.awt.Dimension;
+import java.awt.geom.Point2D;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Implements the Fruchterman-Reingold force-directed algorithm for node layout.
+ * 
+ * <p>Behavior is determined by the following settable parameters:
+ * <ul>
+ * <li/>attraction multiplier: how much edges try to keep their vertices together
+ * <li/>repulsion multiplier: how much vertices try to push each other apart
+ * <li/>maximum iterations: how many iterations this algorithm will use before stopping
+ * </ul>
+ * Each of the first two defaults to 0.75; the maximum number of iterations defaults to 700.
+ *
+ * @see "Fruchterman and Reingold, 'Graph Drawing by Force-directed Placement'"
+ * @see "http://i11www.ilkd.uni-karlsruhe.de/teaching/SS_04/visualisierung/papers/fruchterman91graph.pdf"
+ * @author Scott White, Yan-Biao Boey, Danyel Fisher
+ */
+public class FRLayout<V, E> extends AbstractLayout<V, E> implements IterativeContext {
+
+    private double forceConstant;
+
+    private double temperature;
+
+    private int currentIteration;
+
+    private int mMaxIterations = 700;
+
+    private Map<V, FRVertexData> frVertexData =
+       LazyMap.decorate(new HashMap<V,FRVertexData>(), new Factory<FRVertexData>() {
+               public FRVertexData create() {
+                       return new FRVertexData();
+               }});
+
+    private double attraction_multiplier = 0.75;
+
+    private double attraction_constant;
+
+    private double repulsion_multiplier = 0.75;
+
+    private double repulsion_constant;
+
+    private double max_dimension;
+
+    /**
+     * Creates an instance for the specified graph.
+     */
+    public FRLayout(Graph<V, E> g) {
+        super(g);
+    }
+
+    /**
+     * Creates an instance of size {@code d} for the specified graph.
+     */
+    public FRLayout(Graph<V, E> g, Dimension d) {
+        super(g, new RandomLocationTransformer<V>(d), d);
+        initialize();
+        max_dimension = Math.max(d.height, d.width);
+    }
+
+       @Override
+       public void setSize(Dimension size) {
+               if(initialized == false) {
+                       setInitializer(new RandomLocationTransformer<V>(size));
+               }
+               super.setSize(size);
+        max_dimension = Math.max(size.height, size.width);
+       }
+
+       /**
+        * Sets the attraction multiplier.
+        */
+       public void setAttractionMultiplier(double attraction) {
+        this.attraction_multiplier = attraction;
+    }
+
+       /**
+        * Sets the repulsion multiplier.
+        */
+    public void setRepulsionMultiplier(double repulsion) {
+        this.repulsion_multiplier = repulsion;
+    }
+
+       public void reset() {
+               doInit();
+       }
+
+    public void initialize() {
+       doInit();
+    }
+
+    private void doInit() {
+       Graph<V,E> graph = getGraph();
+       Dimension d = getSize();
+       if(graph != null && d != null) {
+               currentIteration = 0;
+               temperature = d.getWidth() / 10;
+
+               forceConstant =
+                       Math
+                       .sqrt(d.getHeight()
+                                       * d.getWidth()
+                                       / graph.getVertexCount());
+
+               attraction_constant = attraction_multiplier * forceConstant;
+               repulsion_constant = repulsion_multiplier * forceConstant;
+       }
+    }
+
+    private double EPSILON = 0.000001D;
+
+    /**
+     * Moves the iteration forward one notch, calculation attraction and
+     * repulsion between vertices and edges and cooling the temperature.
+     */
+    public synchronized void step() {
+        currentIteration++;
+
+        /**
+         * Calculate repulsion
+         */
+        while(true) {
+
+            try {
+                for(V v1 : getGraph().getVertices()) {
+                    calcRepulsion(v1);
+                }
+                break;
+            } catch(ConcurrentModificationException cme) {}
+        }
+
+        /**
+         * Calculate attraction
+         */
+        while(true) {
+            try {
+                for(E e : getGraph().getEdges()) {
+
+                    calcAttraction(e);
+                }
+                break;
+            } catch(ConcurrentModificationException cme) {}
+        }
+
+
+        while(true) {
+            try {
+                for(V v : getGraph().getVertices()) {
+                    if (isLocked(v)) continue;
+                    calcPositions(v);
+                }
+                break;
+            } catch(ConcurrentModificationException cme) {}
+        }
+        cool();
+    }
+
+    protected synchronized void calcPositions(V v) {
+        FRVertexData fvd = getFRData(v);
+        if(fvd == null) return;
+        Point2D xyd = transform(v);
+        double deltaLength = Math.max(EPSILON, fvd.norm());
+
+        double newXDisp = fvd.getX() / deltaLength
+                * Math.min(deltaLength, temperature);
+
+        if (Double.isNaN(newXDisp)) {
+               throw new IllegalArgumentException(
+                "Unexpected mathematical result in FRLayout:calcPositions [xdisp]"); }
+
+        double newYDisp = fvd.getY() / deltaLength
+                * Math.min(deltaLength, temperature);
+        xyd.setLocation(xyd.getX()+newXDisp, xyd.getY()+newYDisp);
+
+        double borderWidth = getSize().getWidth() / 50.0;
+        double newXPos = xyd.getX();
+        if (newXPos < borderWidth) {
+            newXPos = borderWidth + Math.random() * borderWidth * 2.0;
+        } else if (newXPos > (getSize().getWidth() - borderWidth)) {
+            newXPos = getSize().getWidth() - borderWidth - Math.random()
+                    * borderWidth * 2.0;
+        }
+
+        double newYPos = xyd.getY();
+        if (newYPos < borderWidth) {
+            newYPos = borderWidth + Math.random() * borderWidth * 2.0;
+        } else if (newYPos > (getSize().getHeight() - borderWidth)) {
+            newYPos = getSize().getHeight() - borderWidth
+                    - Math.random() * borderWidth * 2.0;
+        }
+
+        xyd.setLocation(newXPos, newYPos);
+    }
+
+    protected void calcAttraction(E e) {
+       Pair<V> endpoints = getGraph().getEndpoints(e);
+        V v1 = endpoints.getFirst();
+        V v2 = endpoints.getSecond();
+        boolean v1_locked = isLocked(v1);
+        boolean v2_locked = isLocked(v2);
+
+        if(v1_locked && v2_locked) {
+               // both locked, do nothing
+               return;
+        }
+        Point2D p1 = transform(v1);
+        Point2D p2 = transform(v2);
+        if(p1 == null || p2 == null) return;
+        double xDelta = p1.getX() - p2.getX();
+        double yDelta = p1.getY() - p2.getY();
+
+        double deltaLength = Math.max(EPSILON, Math.sqrt((xDelta * xDelta)
+                + (yDelta * yDelta)));
+
+        double force = (deltaLength * deltaLength) / attraction_constant;
+
+        if (Double.isNaN(force)) { throw new IllegalArgumentException(
+                "Unexpected mathematical result in FRLayout:calcPositions [force]"); }
+
+        double dx = (xDelta / deltaLength) * force;
+        double dy = (yDelta / deltaLength) * force;
+        if(v1_locked == false) {
+               FRVertexData fvd1 = getFRData(v1);
+               fvd1.offset(-dx, -dy);
+        }
+        if(v2_locked == false) {
+               FRVertexData fvd2 = getFRData(v2);
+               fvd2.offset(dx, dy);
+        }
+    }
+
+    protected void calcRepulsion(V v1) {
+        FRVertexData fvd1 = getFRData(v1);
+        if(fvd1 == null)
+            return;
+        fvd1.setLocation(0, 0);
+
+        try {
+            for(V v2 : getGraph().getVertices()) {
+
+//                if (isLocked(v2)) continue;
+                if (v1 != v2) {
+                    Point2D p1 = transform(v1);
+                    Point2D p2 = transform(v2);
+                    if(p1 == null || p2 == null) continue;
+                    double xDelta = p1.getX() - p2.getX();
+                    double yDelta = p1.getY() - p2.getY();
+
+                    double deltaLength = Math.max(EPSILON, Math
+                            .sqrt((xDelta * xDelta) + (yDelta * yDelta)));
+
+                    double force = (repulsion_constant * repulsion_constant) / deltaLength;
+
+                    if (Double.isNaN(force)) { throw new RuntimeException(
+                    "Unexpected mathematical result in FRLayout:calcPositions [repulsion]"); }
+
+                    fvd1.offset((xDelta / deltaLength) * force,
+                            (yDelta / deltaLength) * force);
+                }
+            }
+        } catch(ConcurrentModificationException cme) {
+            calcRepulsion(v1);
+        }
+    }
+
+    private void cool() {
+        temperature *= (1.0 - currentIteration / (double) mMaxIterations);
+    }
+
+    /**
+     * Sets the maximum number of iterations.
+     */
+    public void setMaxIterations(int maxIterations) {
+        mMaxIterations = maxIterations;
+    }
+
+    protected FRVertexData getFRData(V v) {
+        return frVertexData.get(v);
+    }
+
+    /**
+     * This one is an incremental visualization.
+     */
+    public boolean isIncremental() {
+        return true;
+    }
+
+    /**
+     * Returns true once the current iteration has passed the maximum count,
+     * <tt>MAX_ITERATIONS</tt>.
+     */
+    public boolean done() {
+        if (currentIteration > mMaxIterations || temperature < 1.0/max_dimension)
+        {
+            return true;
+        }
+        return false;
+    }
+
+    protected static class FRVertexData extends Point2D.Double
+    {
+        protected void offset(double x, double y)
+        {
+            this.x += x;
+            this.y += y;
+        }
+
+        protected double norm()
+        {
+            return Math.sqrt(x*x + y*y);
+        }
+     }
+}
\ No newline at end of file
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/FRLayout2.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/FRLayout2.java
new file mode 100644 (file)
index 0000000..0f5b05e
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ * 
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.layout;
+
+import java.awt.Dimension;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.collections15.Factory;
+import org.apache.commons.collections15.map.LazyMap;
+
+import edu.uci.ics.jung.algorithms.layout.util.RandomLocationTransformer;
+import edu.uci.ics.jung.algorithms.util.IterativeContext;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.Pair;
+
+/**
+ * Implements the Fruchterman-Reingold force-directed algorithm for node layout.
+ * This is an experimental attempt at optimizing {@code FRLayout}; if it is successful
+ * it will be folded back into {@code FRLayout} (and this class will disappear).
+ * 
+ * <p>Behavior is determined by the following settable parameters:
+ * <ul>
+ * <li/>attraction multiplier: how much edges try to keep their vertices together
+ * <li/>repulsion multiplier: how much vertices try to push each other apart
+ * <li/>maximum iterations: how many iterations this algorithm will use before stopping
+ * </ul>
+ * Each of the first two defaults to 0.75; the maximum number of iterations defaults to 700.
+
+ * 
+ * @see "Fruchterman and Reingold, 'Graph Drawing by Force-directed Placement'"
+ * @see http://i11www.ilkd.uni-karlsruhe.de/teaching/SS_04/visualisierung/papers/fruchterman91graph.pdf
+ * 
+ * @author Tom Nelson
+ * @author Scott White, Yan-Biao Boey, Danyel Fisher
+ */
+public class FRLayout2<V, E> extends AbstractLayout<V, E> implements IterativeContext {
+
+    private double forceConstant;
+
+    private double temperature;
+
+    private int currentIteration;
+
+    private int maxIterations = 700;
+    
+    private Map<V, Point2D> frVertexData = 
+       LazyMap.decorate(new HashMap<V,Point2D>(), new Factory<Point2D>() {
+               public Point2D create() {
+                       return new Point2D.Double();
+               }});
+
+    private double attraction_multiplier = 0.75;
+    
+    private double attraction_constant;
+    
+    private double repulsion_multiplier = 0.75;
+    
+    private double repulsion_constant;
+    
+    private double max_dimension;
+    
+    private Rectangle2D innerBounds = new Rectangle2D.Double();
+    
+    private boolean checked = false;
+    
+    /**
+     * Creates an instance for the specified graph.
+     */
+    public FRLayout2(Graph<V, E> g) {
+        super(g);
+    }
+    
+    /**
+     * Creates an instance of size {@code d} for the specified graph.
+     */
+    public FRLayout2(Graph<V, E> g, Dimension d) {
+        super(g, new RandomLocationTransformer<V>(d), d);
+        max_dimension = Math.max(d.height, d.width);
+        initialize();
+    }
+    
+       @Override
+       public void setSize(Dimension size) {
+               if(initialized == false) 
+                       setInitializer(new RandomLocationTransformer<V>(size));
+               super.setSize(size);
+               double t = size.width/50.0;
+               innerBounds.setFrameFromDiagonal(t,t,size.width-t,size.height-t);
+        max_dimension = Math.max(size.height, size.width);
+       }
+
+    /**
+     * Sets the attraction multiplier.
+     */
+       public void setAttractionMultiplier(double attraction) {
+        this.attraction_multiplier = attraction;
+    }
+    
+    /**
+     * Sets the repulsion multiplier.
+     */
+    public void setRepulsionMultiplier(double repulsion) {
+        this.repulsion_multiplier = repulsion;
+    }
+    
+       public void reset() {
+               doInit();
+       }
+    
+    public void initialize() {
+       doInit();
+    }
+
+    private void doInit() {
+       Graph<V,E> graph = getGraph();
+       Dimension d = getSize();
+       if(graph != null && d != null) {
+               currentIteration = 0;
+               temperature = d.getWidth() / 10;
+
+               forceConstant = 
+                       Math
+                       .sqrt(d.getHeight()
+                                       * d.getWidth()
+                                       / graph.getVertexCount());
+
+               attraction_constant = attraction_multiplier * forceConstant;
+               repulsion_constant = repulsion_multiplier * forceConstant;
+       }
+    }
+
+    private double EPSILON = 0.000001D;
+
+    /**
+     * Moves the iteration forward one notch, calculation attraction and
+     * repulsion between vertices and edges and cooling the temperature.
+     */
+    public synchronized void step() {
+        currentIteration++;
+
+        /**
+         * Calculate repulsion
+         */
+        while(true) {
+            
+            try {
+                for(V v1 : getGraph().getVertices()) {
+                    calcRepulsion(v1);
+                }
+                break;
+            } catch(ConcurrentModificationException cme) {}
+        }
+
+        /**
+         * Calculate attraction
+         */
+        while(true) {
+            try {
+                for(E e : getGraph().getEdges()) {
+                    calcAttraction(e);
+                }
+                break;
+            } catch(ConcurrentModificationException cme) {}
+        }
+
+
+        while(true) {
+            try {    
+                for(V v : getGraph().getVertices()) {
+                    if (isLocked(v)) continue;
+                    calcPositions(v);
+                }
+                break;
+            } catch(ConcurrentModificationException cme) {}
+        }
+        cool();
+    }
+
+    protected synchronized void calcPositions(V v) {
+        Point2D fvd = this.frVertexData.get(v);
+        if(fvd == null) return;
+        Point2D xyd = transform(v);
+        double deltaLength = Math.max(EPSILON, 
+                       Math.sqrt(fvd.getX()*fvd.getX()+fvd.getY()*fvd.getY()));
+
+        double newXDisp = fvd.getX() / deltaLength
+                * Math.min(deltaLength, temperature);
+
+        assert Double.isNaN(newXDisp) == false : "Unexpected mathematical result in FRLayout:calcPositions [xdisp]";
+
+        double newYDisp = fvd.getY() / deltaLength
+                * Math.min(deltaLength, temperature);
+        double newX = xyd.getX()+Math.max(-5, Math.min(5,newXDisp));
+        double newY = xyd.getY()+Math.max(-5, Math.min(5,newYDisp));
+        
+        newX = Math.max(innerBounds.getMinX(), Math.min(newX, innerBounds.getMaxX()));
+        newY = Math.max(innerBounds.getMinY(), Math.min(newY, innerBounds.getMaxY()));
+        
+        xyd.setLocation(newX, newY);
+
+    }
+
+    protected void calcAttraction(E e) {
+       Pair<V> endpoints = getGraph().getEndpoints(e);
+        V v1 = endpoints.getFirst();
+        V v2 = endpoints.getSecond();
+        boolean v1_locked = isLocked(v1);
+        boolean v2_locked = isLocked(v2);
+        
+        if(v1_locked && v2_locked) {
+               // both locked, do nothing
+               return;
+        }
+        Point2D p1 = transform(v1);
+        Point2D p2 = transform(v2);
+        if(p1 == null || p2 == null) return;
+        double xDelta = p1.getX() - p2.getX();
+        double yDelta = p1.getY() - p2.getY();
+
+        double deltaLength = Math.max(EPSILON, p1.distance(p2));
+
+        double force = deltaLength  / attraction_constant;
+
+        assert Double.isNaN(force) == false : "Unexpected mathematical result in FRLayout:calcPositions [force]";
+
+        double dx = xDelta * force;
+        double dy = yDelta * force;
+        Point2D fvd1 = frVertexData.get(v1);
+        Point2D fvd2 = frVertexData.get(v2);
+        if(v2_locked) {
+               // double the offset for v1, as v2 will not be moving in
+               // the opposite direction
+               fvd1.setLocation(fvd1.getX()-2*dx, fvd1.getY()-2*dy);
+        } else {
+        fvd1.setLocation(fvd1.getX()-dx, fvd1.getY()-dy);
+        }
+        if(v1_locked) {
+               // double the offset for v2, as v1 will not be moving in
+               // the opposite direction
+               fvd2.setLocation(fvd2.getX()+2*dx, fvd2.getY()+2*dy);
+        } else {
+        fvd2.setLocation(fvd2.getX()+dx, fvd2.getY()+dy);
+    }
+    }
+
+    protected void calcRepulsion(V v1) {
+        Point2D fvd1 = frVertexData.get(v1);
+        if(fvd1 == null) return;
+        fvd1.setLocation(0, 0);
+        boolean v1_locked = isLocked(v1);
+
+        try {
+            for(V v2 : getGraph().getVertices()) {
+
+                boolean v2_locked = isLocked(v2);
+               if (v1_locked && v2_locked) continue;
+                if (v1 != v2) {
+                    Point2D p1 = transform(v1);
+                    Point2D p2 = transform(v2);
+                    if(p1 == null || p2 == null) continue;
+                    double xDelta = p1.getX() - p2.getX();
+                    double yDelta = p1.getY() - p2.getY();
+                    
+                    double deltaLength = Math.max(EPSILON, p1.distanceSq(p2));
+                    
+                    double force = (repulsion_constant * repulsion_constant);// / deltaLength;
+                    
+                    double forceOverDeltaLength = force / deltaLength;
+                    
+                    assert Double.isNaN(force) == false : "Unexpected mathematical result in FRLayout:calcPositions [repulsion]";
+                    
+                    if(v2_locked) {
+                       // double the offset for v1, as v2 will not be moving in
+                       // the opposite direction
+                       fvd1.setLocation(fvd1.getX()+2 * xDelta * forceOverDeltaLength,
+                               fvd1.getY()+ 2 * yDelta * forceOverDeltaLength);
+                    } else {
+                       fvd1.setLocation(fvd1.getX()+xDelta * forceOverDeltaLength,
+                                       fvd1.getY()+yDelta * forceOverDeltaLength);
+                }
+            }
+            }
+        } catch(ConcurrentModificationException cme) {
+            calcRepulsion(v1);
+        }
+    }
+
+    private void cool() {
+        temperature *= (1.0 - currentIteration / (double) maxIterations);
+    }
+
+    /**
+     * Sets the maximum number of iterations.
+     */
+    public void setMaxIterations(int maxIterations) {
+        this.maxIterations = maxIterations;
+    }
+
+    /**
+     * This one is an incremental visualization.
+     */
+    public boolean isIncremental() {
+        return true;
+    }
+
+    /**
+     * Returns true once the current iteration has passed the maximum count,
+     * <tt>MAX_ITERATIONS</tt>.
+     */
+    public boolean done() {
+        if (currentIteration > maxIterations || temperature < 1.0/max_dimension) { 
+            if (!checked)
+            {
+//                System.out.println("current iteration: " + currentIteration);
+//                System.out.println("temperature: " + temperature);
+                checked = true;
+            }
+            return true; 
+        } 
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/GraphElementAccessor.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/GraphElementAccessor.java
new file mode 100644 (file)
index 0000000..4cf1c51
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2005, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ * 
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ * 
+ *
+ * Created on Apr 12, 2005
+ */
+package edu.uci.ics.jung.algorithms.layout;
+
+import java.awt.Shape;
+import java.util.Collection;
+
+/**
+ * Interface for coordinate-based selection of graph components.
+ * @author Tom Nelson
+ * @author Joshua O'Madadhain
+ */
+public interface GraphElementAccessor<V, E>
+{
+    /**
+     * Returns a vertex which is associated with the 
+     * location <code>(x,y)</code>.  This is typically determined
+     * with respect to the vertex's location as specified
+     * by a <code>Layout</code>.
+     */
+    V getVertex(Layout<V,E> layout, double x, double y);
+    
+    /**
+     * Returns the vertices contained within {@code rectangle} relative
+     * to {@code layout}.
+     */
+    Collection<V> getVertices(Layout<V,E> layout, Shape rectangle);
+
+    /**
+     * Returns an edge which is associated with the 
+     * location <code>(x,y)</code>.  This is typically determined
+     * with respect to the edge's location as specified
+     * by a {@code Layout}.
+     */
+    E getEdge(Layout<V,E> layout, double x, double y);
+
+}
\ No newline at end of file
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/ISOMLayout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/ISOMLayout.java
new file mode 100644 (file)
index 0000000..bea8eda
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.layout;
+
+import edu.uci.ics.jung.algorithms.layout.util.RandomLocationTransformer;
+import edu.uci.ics.jung.algorithms.util.IterativeContext;
+import edu.uci.ics.jung.graph.Graph;
+
+import org.apache.commons.collections15.Factory;
+import org.apache.commons.collections15.map.LazyMap;
+
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implements a self-organizing map layout algorithm, based on Meyer's
+ * self-organizing graph methods.
+ *
+ * @author Yan Biao Boey
+ */
+public class ISOMLayout<V, E> extends AbstractLayout<V,E> implements IterativeContext {
+
+       Map<V, ISOMVertexData> isomVertexData =
+               LazyMap.decorate(new HashMap<V, ISOMVertexData>(),
+                               new Factory<ISOMVertexData>() {
+                                       public ISOMVertexData create() {
+                                               return new ISOMVertexData();
+                                       }});
+
+       private int maxEpoch;
+       private int epoch;
+
+       private int radiusConstantTime;
+       private int radius;
+       private int minRadius;
+
+       private double adaption;
+       private double initialAdaption;
+       private double minAdaption;
+
+    protected GraphElementAccessor<V,E> elementAccessor =
+       new RadiusGraphElementAccessor<V,E>();
+
+       private double coolingFactor;
+
+       private List<V> queue = new ArrayList<V>();
+       private String status = null;
+
+       /**
+        * Returns the current number of epochs and execution status, as a string.
+        */
+       public String getStatus() {
+               return status;
+       }
+
+       /**
+        * Creates an <code>ISOMLayout</code> instance for the specified graph <code>g</code>.
+        * @param g
+        */
+       public ISOMLayout(Graph<V,E> g) {
+               super(g);
+       }
+
+       public void initialize() {
+
+               setInitializer(new RandomLocationTransformer<V>(getSize()));
+               maxEpoch = 2000;
+               epoch = 1;
+
+               radiusConstantTime = 100;
+               radius = 5;
+               minRadius = 1;
+
+               initialAdaption = 90.0D / 100.0D;
+               adaption = initialAdaption;
+               minAdaption = 0;
+
+               //factor = 0; //Will be set later on
+               coolingFactor = 2;
+
+               //temperature = 0.03;
+               //initialJumpRadius = 100;
+               //jumpRadius = initialJumpRadius;
+
+               //delay = 100;
+       }
+
+
+       /**
+       * Advances the current positions of the graph elements.
+       */
+       public void step() {
+               status = "epoch: " + epoch + "; ";
+               if (epoch < maxEpoch) {
+                       adjust();
+                       updateParameters();
+                       status += " status: running";
+
+               } else {
+                       status += "adaption: " + adaption + "; ";
+                       status += "status: done";
+//                     done = true;
+               }
+       }
+
+       private synchronized void adjust() {
+               //Generate random position in graph space
+               Point2D tempXYD = new Point2D.Double();
+
+               // creates a new XY data location
+        tempXYD.setLocation(10 + Math.random() * getSize().getWidth(),
+                10 + Math.random() * getSize().getHeight());
+
+               //Get closest vertex to random position
+               V winner = elementAccessor.getVertex(this, tempXYD.getX(), tempXYD.getY());
+
+               while(true) {
+                   try {
+                       for(V v : getGraph().getVertices()) {
+                           ISOMVertexData ivd = getISOMVertexData(v);
+                           ivd.distance = 0;
+                           ivd.visited = false;
+                       }
+                       break;
+                   } catch(ConcurrentModificationException cme) {}
+        }
+               adjustVertex(winner, tempXYD);
+       }
+
+       private synchronized void updateParameters() {
+               epoch++;
+               double factor = Math.exp(-1 * coolingFactor * (1.0 * epoch / maxEpoch));
+               adaption = Math.max(minAdaption, factor * initialAdaption);
+               //jumpRadius = (int) factor * jumpRadius;
+               //temperature = factor * temperature;
+               if ((radius > minRadius) && (epoch % radiusConstantTime == 0)) {
+                       radius--;
+               }
+       }
+
+       private synchronized void adjustVertex(V v, Point2D tempXYD) {
+               queue.clear();
+               ISOMVertexData ivd = getISOMVertexData(v);
+               ivd.distance = 0;
+               ivd.visited = true;
+               queue.add(v);
+               V current;
+
+               while (!queue.isEmpty()) {
+                       current = queue.remove(0);
+                       ISOMVertexData currData = getISOMVertexData(current);
+                       Point2D currXYData = transform(current);
+
+                       double dx = tempXYD.getX() - currXYData.getX();
+                       double dy = tempXYD.getY() - currXYData.getY();
+                       double factor = adaption / Math.pow(2, currData.distance);
+
+                       currXYData.setLocation(currXYData.getX()+(factor*dx), currXYData.getY()+(factor*dy));
+
+                       if (currData.distance < radius) {
+                           Collection<V> s = getGraph().getNeighbors(current);
+                           while(true) {
+                               try {
+                                       for(V child : s) {
+                                       ISOMVertexData childData = getISOMVertexData(child);
+                                       if (childData != null && !childData.visited) {
+                                           childData.visited = true;
+                                           childData.distance = currData.distance + 1;
+                                           queue.add(child);
+                                       }
+                                   }
+                                   break;
+                               } catch(ConcurrentModificationException cme) {}
+                           }
+                       }
+               }
+       }
+
+       protected ISOMVertexData getISOMVertexData(V v) {
+               return isomVertexData.get(v);
+       }
+
+       /**
+        * This one is an incremental visualization.
+        * @return <code>true</code> is the layout algorithm is incremental, <code>false</code> otherwise
+        */
+       public boolean isIncremental() {
+               return true;
+       }
+
+       /**
+        * Returns <code>true</code> if the vertex positions are no longer being
+        * updated.  Currently <code>ISOMLayout</code> stops updating vertex
+        * positions after a certain number of iterations have taken place.
+        * @return <code>true</code> if the vertex position updates have stopped,
+        * <code>false</code> otherwise
+        */
+       public boolean done() {
+               return epoch >= maxEpoch;
+       }
+
+       protected static class ISOMVertexData {
+               int distance;
+               boolean visited;
+
+               protected ISOMVertexData() {
+                   distance = 0;
+                   visited = false;
+               }
+       }
+
+       /**
+        * Resets the layout iteration count to 0, which allows the layout algorithm to
+        * continue updating vertex positions.
+        */
+       public void reset() {
+               epoch = 0;
+       }
+}
\ No newline at end of file
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/KKLayout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/KKLayout.java
new file mode 100644 (file)
index 0000000..a1b9f40
--- /dev/null
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.layout;
+/*
+ * This source is under the same license with JUNG.
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+
+import java.awt.Dimension;
+import java.awt.geom.Point2D;
+import java.util.ConcurrentModificationException;
+
+import edu.uci.ics.jung.algorithms.layout.util.RandomLocationTransformer;
+import edu.uci.ics.jung.algorithms.shortestpath.Distance;
+import edu.uci.ics.jung.algorithms.shortestpath.DistanceStatistics;
+import edu.uci.ics.jung.algorithms.shortestpath.UnweightedShortestPath;
+import edu.uci.ics.jung.algorithms.util.IterativeContext;
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * Implements the Kamada-Kawai algorithm for node layout.
+ * Does not respect filter calls, and sometimes crashes when the view changes to it.
+ *
+ * @see "Tomihisa Kamada and Satoru Kawai: An algorithm for drawing general indirect graphs. Information Processing Letters 31(1):7-15, 1989" 
+ * @see "Tomihisa Kamada: On visualization of abstract objects and relations. Ph.D. dissertation, Dept. of Information Science, Univ. of Tokyo, Dec. 1988."
+ *
+ * @author Masanori Harada
+ */
+public class KKLayout<V,E> extends AbstractLayout<V,E> implements IterativeContext {
+
+       private double EPSILON = 0.1d;
+
+       private int currentIteration;
+    private int maxIterations = 2000;
+       private String status = "KKLayout";
+
+       private double L;                       // the ideal length of an edge
+       private double K = 1;           // arbitrary const number
+       private double[][] dm;     // distance matrix
+
+       private boolean adjustForGravity = true;
+       private boolean exchangeVertices = true;
+
+       private V[] vertices;
+       private Point2D[] xydata;
+
+    /**
+     * Retrieves graph distances between vertices of the visible graph
+     */
+    protected Distance<V> distance;
+
+    /**
+     * The diameter of the visible graph. In other words, the maximum over all pairs
+     * of vertices of the length of the shortest path between a and bf the visible graph.
+     */
+       protected double diameter;
+
+    /**
+     * A multiplicative factor which partly specifies the "preferred" length of an edge (L).
+     */
+    private double length_factor = 0.9;
+
+    /**
+     * A multiplicative factor which specifies the fraction of the graph's diameter to be 
+     * used as the inter-vertex distance between disconnected vertices.
+     */
+    private double disconnected_multiplier = 0.5;
+    
+       /**
+        * Creates an instance for the specified graph.
+        */
+       public KKLayout(Graph<V,E> g) 
+    {
+        this(g, new UnweightedShortestPath<V,E>(g));
+       }
+
+       /**
+        * Creates an instance for the specified graph and distance metric.
+        */
+    public KKLayout(Graph<V,E> g, Distance<V> distance){
+        super(g);
+        this.distance = distance;
+    }
+
+    /**
+     * Sets a multiplicative factor which 
+     * partly specifies the "preferred" length of an edge (L).
+     */
+    public void setLengthFactor(double length_factor){
+        this.length_factor = length_factor;
+    }
+    
+    /**
+     * Sets a multiplicative factor that specifies the fraction of the graph's diameter to be 
+     * used as the inter-vertex distance between disconnected vertices.
+     */
+    public void setDisconnectedDistanceMultiplier(double disconnected_multiplier){
+        this.disconnected_multiplier = disconnected_multiplier;
+    }
+    
+    /**
+     * Returns a string with information about the current status of the algorithm.
+     */
+       public String getStatus() {
+               return status + this.getSize();
+       }
+
+       /**
+        * Sets the maximum number of iterations.
+        */
+    public void setMaxIterations(int maxIterations) {
+        this.maxIterations = maxIterations;
+    }
+
+       /**
+        * This one is an incremental visualization.
+        */
+       public boolean isIncremental() {
+               return true;
+       }
+
+       /**
+        * Returns true once the current iteration has passed the maximum count.
+        */
+       public boolean done() {
+               if (currentIteration > maxIterations) {
+                       return true;
+               }
+               return false;
+       }
+
+       @SuppressWarnings("unchecked")
+    public void initialize() {
+       currentIteration = 0;
+
+       if(graph != null && size != null) {
+
+               double height = size.getHeight();
+               double width = size.getWidth();
+
+               int n = graph.getVertexCount();
+               dm = new double[n][n];
+               vertices = (V[])graph.getVertices().toArray();
+               xydata = new Point2D[n];
+
+               // assign IDs to all visible vertices
+               while(true) {
+                       try {
+                               int index = 0;
+                               for(V v : graph.getVertices()) {
+                                       Point2D xyd = transform(v);
+                                       vertices[index] = v;
+                                       xydata[index] = xyd;
+                                       index++;
+                               }
+                               break;
+                       } catch(ConcurrentModificationException cme) {}
+               }
+
+               diameter = DistanceStatistics.<V,E>diameter(graph, distance, true);
+
+               double L0 = Math.min(height, width);
+               L = (L0 / diameter) * length_factor;  // length_factor used to be hardcoded to 0.9
+               //L = 0.75 * Math.sqrt(height * width / n);
+
+               for (int i = 0; i < n - 1; i++) {
+                       for (int j = i + 1; j < n; j++) {
+                               Number d_ij = distance.getDistance(vertices[i], vertices[j]);
+                               Number d_ji = distance.getDistance(vertices[j], vertices[i]);
+                               double dist = diameter * disconnected_multiplier;
+                               if (d_ij != null)
+                                       dist = Math.min(d_ij.doubleValue(), dist);
+                               if (d_ji != null)
+                                       dist = Math.min(d_ji.doubleValue(), dist);
+                               dm[i][j] = dm[j][i] = dist;
+                       }
+               }
+       }
+       }
+
+       public void step() {
+               try {
+                       currentIteration++;
+                       double energy = calcEnergy();
+                       status = "Kamada-Kawai V=" + getGraph().getVertexCount()
+                       + "(" + getGraph().getVertexCount() + ")"
+                       + " IT: " + currentIteration
+                       + " E=" + energy
+                       ;
+
+                       int n = getGraph().getVertexCount();
+                       if (n == 0)
+                               return;
+
+                       double maxDeltaM = 0;
+                       int pm = -1;            // the node having max deltaM
+                       for (int i = 0; i < n; i++) {
+                               if (isLocked(vertices[i]))
+                                       continue;
+                               double deltam = calcDeltaM(i);
+
+                               if (maxDeltaM < deltam) {
+                                       maxDeltaM = deltam;
+                                       pm = i;
+                               }
+                       }
+                       if (pm == -1)
+                               return;
+
+                       for (int i = 0; i < 100; i++) {
+                               double[] dxy = calcDeltaXY(pm);
+                               xydata[pm].setLocation(xydata[pm].getX()+dxy[0], xydata[pm].getY()+dxy[1]);
+
+                               double deltam = calcDeltaM(pm);
+                               if (deltam < EPSILON)
+                                       break;
+                       }
+
+                       if (adjustForGravity)
+                               adjustForGravity();
+
+                       if (exchangeVertices && maxDeltaM < EPSILON) {
+                               energy = calcEnergy();
+                               for (int i = 0; i < n - 1; i++) {
+                                       if (isLocked(vertices[i]))
+                                               continue;
+                                       for (int j = i + 1; j < n; j++) {
+                                               if (isLocked(vertices[j]))
+                                                       continue;
+                                               double xenergy = calcEnergyIfExchanged(i, j);
+                                               if (energy > xenergy) {
+                                                       double sx = xydata[i].getX();
+                                                       double sy = xydata[i].getY();
+                                                       xydata[i].setLocation(xydata[j]);
+                                                       xydata[j].setLocation(sx, sy);
+                                                       return;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               finally {
+//                     fireStateChanged();
+               }
+       }
+
+       /**
+        * Shift all vertices so that the center of gravity is located at
+        * the center of the screen.
+        */
+       public void adjustForGravity() {
+               Dimension d = getSize();
+               double height = d.getHeight();
+               double width = d.getWidth();
+               double gx = 0;
+               double gy = 0;
+               for (int i = 0; i < xydata.length; i++) {
+                       gx += xydata[i].getX();
+                       gy += xydata[i].getY();
+               }
+               gx /= xydata.length;
+               gy /= xydata.length;
+               double diffx = width / 2 - gx;
+               double diffy = height / 2 - gy;
+               for (int i = 0; i < xydata.length; i++) {
+            xydata[i].setLocation(xydata[i].getX()+diffx, xydata[i].getY()+diffy);
+               }
+       }
+
+    /* (non-Javadoc)
+        * @see edu.uci.ics.jung.visualization.layout.AbstractLayout#setSize(java.awt.Dimension)
+        */
+       @Override
+       public void setSize(Dimension size) {
+               if(initialized == false)
+                       setInitializer(new RandomLocationTransformer<V>(size));
+               super.setSize(size);
+       }
+
+       /**
+        * Enable or disable gravity point adjusting.
+        */
+       public void setAdjustForGravity(boolean on) {
+               adjustForGravity = on;
+       }
+
+       /**
+        * Returns true if gravity point adjusting is enabled.
+        */
+       public boolean getAdjustForGravity() {
+               return adjustForGravity;
+       }
+
+       /**
+        * Enable or disable the local minimum escape technique by
+        * exchanging vertices.
+        */
+       public void setExchangeVertices(boolean on) {
+               exchangeVertices = on;
+       }
+
+       /**
+        * Returns true if the local minimum escape technique by
+        * exchanging vertices is enabled.
+        */
+       public boolean getExchangeVertices() {
+               return exchangeVertices;
+       }
+
+       /**
+        * Determines a step to new position of the vertex m.
+        */
+       private double[] calcDeltaXY(int m) {
+               double dE_dxm = 0;
+               double dE_dym = 0;
+               double d2E_d2xm = 0;
+               double d2E_dxmdym = 0;
+               double d2E_dymdxm = 0;
+               double d2E_d2ym = 0;
+
+               for (int i = 0; i < vertices.length; i++) {
+                       if (i != m) {
+                
+                double dist = dm[m][i];
+                               double l_mi = L * dist;
+                               double k_mi = K / (dist * dist);
+                               double dx = xydata[m].getX() - xydata[i].getX();
+                               double dy = xydata[m].getY() - xydata[i].getY();
+                               double d = Math.sqrt(dx * dx + dy * dy);
+                               double ddd = d * d * d;
+
+                               dE_dxm += k_mi * (1 - l_mi / d) * dx;
+                               dE_dym += k_mi * (1 - l_mi / d) * dy;
+                               d2E_d2xm += k_mi * (1 - l_mi * dy * dy / ddd);
+                               d2E_dxmdym += k_mi * l_mi * dx * dy / ddd;
+                               d2E_d2ym += k_mi * (1 - l_mi * dx * dx / ddd);
+                       }
+               }
+               // d2E_dymdxm equals to d2E_dxmdym.
+               d2E_dymdxm = d2E_dxmdym;
+
+               double denomi = d2E_d2xm * d2E_d2ym - d2E_dxmdym * d2E_dymdxm;
+               double deltaX = (d2E_dxmdym * dE_dym - d2E_d2ym * dE_dxm) / denomi;
+               double deltaY = (d2E_dymdxm * dE_dxm - d2E_d2xm * dE_dym) / denomi;
+               return new double[]{deltaX, deltaY};
+       }
+
+       /**
+        * Calculates the gradient of energy function at the vertex m.
+        */
+       private double calcDeltaM(int m) {
+               double dEdxm = 0;
+               double dEdym = 0;
+               for (int i = 0; i < vertices.length; i++) {
+                       if (i != m) {
+                double dist = dm[m][i];
+                               double l_mi = L * dist;
+                               double k_mi = K / (dist * dist);
+
+                               double dx = xydata[m].getX() - xydata[i].getX();
+                               double dy = xydata[m].getY() - xydata[i].getY();
+                               double d = Math.sqrt(dx * dx + dy * dy);
+
+                               double common = k_mi * (1 - l_mi / d);
+                               dEdxm += common * dx;
+                               dEdym += common * dy;
+                       }
+               }
+               return Math.sqrt(dEdxm * dEdxm + dEdym * dEdym);
+       }
+
+       /**
+        * Calculates the energy function E.
+        */
+       private double calcEnergy() {
+               double energy = 0;
+               for (int i = 0; i < vertices.length - 1; i++) {
+                       for (int j = i + 1; j < vertices.length; j++) {
+                double dist = dm[i][j];
+                               double l_ij = L * dist;
+                               double k_ij = K / (dist * dist);
+                               double dx = xydata[i].getX() - xydata[j].getX();
+                               double dy = xydata[i].getY() - xydata[j].getY();
+                               double d = Math.sqrt(dx * dx + dy * dy);
+
+
+                               energy += k_ij / 2 * (dx * dx + dy * dy + l_ij * l_ij -
+                                                                         2 * l_ij * d);
+                       }
+               }
+               return energy;
+       }
+
+       /**
+        * Calculates the energy function E as if positions of the
+        * specified vertices are exchanged.
+        */
+       private double calcEnergyIfExchanged(int p, int q) {
+               if (p >= q)
+                       throw new RuntimeException("p should be < q");
+               double energy = 0;              // < 0
+               for (int i = 0; i < vertices.length - 1; i++) {
+                       for (int j = i + 1; j < vertices.length; j++) {
+                               int ii = i;
+                               int jj = j;
+                               if (i == p) ii = q;
+                               if (j == q) jj = p;
+
+                double dist = dm[i][j];
+                               double l_ij = L * dist;
+                               double k_ij = K / (dist * dist);
+                               double dx = xydata[ii].getX() - xydata[jj].getX();
+                               double dy = xydata[ii].getY() - xydata[jj].getY();
+                               double d = Math.sqrt(dx * dx + dy * dy);
+                               
+                               energy += k_ij / 2 * (dx * dx + dy * dy + l_ij * l_ij -
+                                                                         2 * l_ij * d);
+                       }
+               }
+               return energy;
+       }
+
+       public void reset() {
+               currentIteration = 0;
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/Layout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/Layout.java
new file mode 100644 (file)
index 0000000..5162ac5
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.layout;
+
+import java.awt.Dimension;
+import java.awt.geom.Point2D;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * A generalized interface is a mechanism for returning (x,y) coordinates 
+ * from vertices. In general, most of these methods are used to both control and
+ * get information from the layout algorithm.
+ * <p>
+ * @author danyelf
+ * @author tom nelson
+ */
+public interface Layout<V, E> extends Transformer<V,Point2D> {
+    
+       /**
+        * Initializes fields in the node that may not have
+        * been set during the constructor. Must be called before
+        * the iterations begin.
+        */
+       void initialize();
+       
+       /**
+        * provides initial locations for all vertices.
+        * @param initializer
+        */
+       void setInitializer(Transformer<V,Point2D> initializer);
+    
+       /**
+        * setter for graph
+        * @param graph
+        */
+    void setGraph(Graph<V,E> graph);
+
+       /**
+        * Returns the full graph (the one that was passed in at 
+        * construction time) that this Layout refers to.
+        * 
+        */
+       Graph<V,E> getGraph();
+       
+       /**
+        * 
+        *
+        */
+       void reset();
+       
+       /**
+        * @param d
+        */
+       void setSize(Dimension d);
+       
+       /**
+        * Returns the current size of the visualization's space.
+        */
+       Dimension getSize();
+
+
+       /**
+        * Sets a flag which fixes this vertex in place.
+     * 
+        * @param v     vertex
+        */
+       void lock(V v, boolean state);
+
+    /**
+     * Returns <code>true</code> if the position of vertex <code>v</code>
+     * is locked.
+     */
+    boolean isLocked(V v);
+
+    /**
+     * set the location of a vertex
+     * @param v
+     * @param location
+     */
+       void setLocation(V v, Point2D location);
+
+
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/LayoutDecorator.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/LayoutDecorator.java
new file mode 100644 (file)
index 0000000..b1f2595
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2005, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ *
+ * Created on Aug 23, 2005
+ */
+
+package edu.uci.ics.jung.algorithms.layout;
+
+import java.awt.Dimension;
+import java.awt.geom.Point2D;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.util.IterativeContext;
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * a pure decorator for the Layout interface. Intended to be overridden
+ * to provide specific behavior decoration
+ * 
+ * @author Tom Nelson 
+ *
+ */
+public abstract class LayoutDecorator<V, E> implements Layout<V, E>, IterativeContext {
+    
+    protected Layout<V, E> delegate;
+    
+    /**
+     * Creates an instance backed by the specified delegate layout.
+     */
+    public LayoutDecorator(Layout<V, E> delegate) {
+        this.delegate = delegate;
+    }
+
+    /**
+     * Returns the backing (delegate) layout.
+     */
+    public Layout<V,E> getDelegate() {
+        return delegate;
+    }
+
+    /**
+     * Sets the backing (delegate) layout.
+     */
+    public void setDelegate(Layout<V,E> delegate) {
+        this.delegate = delegate;
+    }
+
+    /**
+     * @see edu.uci.ics.jung.algorithms.util.IterativeContext#done()
+     */
+    public void step() {
+       if(delegate instanceof IterativeContext) {
+               ((IterativeContext)delegate).step();
+       }
+    }
+
+    /**
+        * 
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#initialize()
+        */
+       public void initialize() {
+               delegate.initialize();
+       }
+
+       /**
+        * @param initializer
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#setInitializer(org.apache.commons.collections15.Transformer)
+        */
+       public void setInitializer(Transformer<V, Point2D> initializer) {
+               delegate.setInitializer(initializer);
+       }
+
+       /**
+        * @param v
+        * @param location
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#setLocation(java.lang.Object, java.awt.geom.Point2D)
+        */
+       public void setLocation(V v, Point2D location) {
+               delegate.setLocation(v, location);
+       }
+
+    /**
+     * @see edu.uci.ics.jung.algorithms.layout.Layout#getSize()
+     */
+    public Dimension getSize() {
+        return delegate.getSize();
+    }
+
+    /**
+     * @see edu.uci.ics.jung.algorithms.layout.Layout#getGraph()
+     */
+    public Graph<V, E> getGraph() {
+        return delegate.getGraph();
+    }
+
+    /**
+     * @see edu.uci.ics.jung.algorithms.layout.Layout#transform(Object)
+     */
+    public Point2D transform(V v) {
+        return delegate.transform(v);
+    }
+
+    /**
+     * @see edu.uci.ics.jung.algorithms.util.IterativeContext#done()
+     */
+    public boolean done() {
+       if(delegate instanceof IterativeContext) {
+               return ((IterativeContext)delegate).done();
+       }
+       return true;
+    }
+
+    /**
+     * @see edu.uci.ics.jung.algorithms.layout.Layout#lock(Object, boolean)
+     */
+    public void lock(V v, boolean state) {
+        delegate.lock(v, state);
+    }
+
+    /**
+     * @see edu.uci.ics.jung.algorithms.layout.Layout#isLocked(Object)
+     */
+    public boolean isLocked(V v) {
+        return delegate.isLocked(v);
+    }
+    
+    /**
+     * @see edu.uci.ics.jung.algorithms.layout.Layout#setSize(Dimension)
+     */
+    public void setSize(Dimension d) {
+        delegate.setSize(d);
+    }
+
+    /**
+     * @see edu.uci.ics.jung.algorithms.layout.Layout#reset()
+     */
+    public void reset() {
+       delegate.reset();
+    }
+    
+    public void setGraph(Graph<V, E> graph) {
+        delegate.setGraph(graph);
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/PolarPoint.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/PolarPoint.java
new file mode 100644 (file)
index 0000000..aa3dc7b
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.layout;
+
+import java.awt.geom.Point2D;
+
+/**
+ * Represents a point in polar coordinates: distance and angle from the origin.
+ * Includes conversions between polar and Cartesian
+ * coordinates (Point2D).
+ * 
+ * @author Tom Nelson - tomnelson@dev.java.net
+ */
+public class PolarPoint 
+{
+       double theta;
+       double radius;
+       
+       /**
+        * Creates a new instance with radius and angle each 0.
+        */
+       public PolarPoint() {
+               this(0,0);
+       }
+
+       /**
+        * Creates a new instance with radius {@code radius} and angle {@code theta}.
+        */
+       public PolarPoint(double theta, double radius) {
+               this.theta = theta;
+               this.radius = radius;
+       }
+       
+       /**
+        * Returns the angle for this point.
+        */
+       public double getTheta() { return theta; }
+
+       /**
+        * Returns the radius for this point.
+        */
+       public double getRadius() { return radius; }
+       
+       /**
+        * Sets the angle for this point to {@code theta}.
+        */
+       public void setTheta(double theta) { this.theta = theta; }
+       
+       /**
+        * Sets the radius for this point to {@code theta}.
+        */
+       public void setRadius(double radius) { this.radius = radius; }
+
+       /**
+        * Returns the result of converting <code>polar</code> to Cartesian coordinates.
+        */
+       public static Point2D polarToCartesian(PolarPoint polar) {
+               return polarToCartesian(polar.getTheta(), polar.getRadius());
+       }
+
+       /**
+        * Returns the result of converting <code>(theta, radius)</code> to Cartesian coordinates.
+        */
+       public static Point2D polarToCartesian(double theta, double radius) {
+               return new Point2D.Double(radius*Math.cos(theta), radius*Math.sin(theta));
+       }
+
+       /**
+        * Returns the result of converting <code>point</code> to polar coordinates.
+        */
+       public static PolarPoint cartesianToPolar(Point2D point) {
+               return cartesianToPolar(point.getX(), point.getY());
+       }
+
+       /**
+        * Returns the result of converting <code>(x, y)</code> to polar coordinates.
+        */
+       public static PolarPoint cartesianToPolar(double x, double y) {
+               double theta = Math.atan2(y,x);
+               double radius = Math.sqrt(x*x+y*y);
+               return new PolarPoint(theta, radius);
+       }
+       
+       @Override
+       public String toString() {
+           return "PolarPoint[" + radius + "," + theta +"]";
+       }
+       
+       /**
+        * Sets the angle and radius of this point to those of {@code p}.
+        */
+       public void setLocation(PolarPoint p) {
+               this.theta = p.getTheta();
+               this.radius = p.getRadius();
+       }
+}
\ No newline at end of file
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/RadialTreeLayout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/RadialTreeLayout.java
new file mode 100644 (file)
index 0000000..457bd96
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2005, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ *
+ * Created on Jul 9, 2005
+ */
+
+package edu.uci.ics.jung.algorithms.layout;
+import java.awt.Dimension;
+import java.awt.geom.Point2D;
+import java.util.HashMap;
+import java.util.Map;
+
+import edu.uci.ics.jung.graph.Forest;
+
+/**
+ * A radial layout for Tree or Forest graphs.
+ * 
+ * @author Tom Nelson 
+ *  
+ */
+public class RadialTreeLayout<V,E> extends TreeLayout<V,E> {
+
+    protected Map<V,PolarPoint> polarLocations;
+
+    /**
+     * Creates an instance for the specified graph with default X and Y distances.
+     */
+    public RadialTreeLayout(Forest<V,E> g) {
+       this(g, DEFAULT_DISTX, DEFAULT_DISTY);
+    }
+
+    /**
+     * Creates an instance for the specified graph and X distance with
+     * default Y distance.
+     */
+    public RadialTreeLayout(Forest<V,E> g, int distx) {
+        this(g, distx, DEFAULT_DISTY);
+    }
+
+    /**
+     * Creates an instance for the specified graph, X distance, and Y distance.
+     */
+    public RadialTreeLayout(Forest<V,E> g, int distx, int disty) {
+       super(g, distx, disty);
+    }
+    
+       @Override
+    protected void buildTree() {
+           super.buildTree();
+           this.polarLocations = new HashMap<V, PolarPoint>();
+        setRadialLocations();
+    }
+
+    @Override
+    public void setSize(Dimension size) {
+       this.size = size;
+        buildTree();
+    }
+
+    @Override
+    protected void setCurrentPositionFor(V vertex) {
+       locations.get(vertex).setLocation(m_currentPoint);
+    }
+
+       @Override
+    public void setLocation(V v, Point2D location)
+    {
+        Point2D c = getCenter();
+        Point2D pv = new Point2D.Double(location.getX() - c.getX(), 
+                location.getY() - c.getY());
+        PolarPoint newLocation = PolarPoint.cartesianToPolar(pv);
+        PolarPoint currentLocation = polarLocations.get(v);
+        if (currentLocation == null)
+               polarLocations.put(v, newLocation);
+        else
+               currentLocation.setLocation(newLocation);
+     }
+       
+       /**
+        * Returns the map from vertices to their locations in polar coordinates.
+        */
+       public Map<V,PolarPoint> getPolarLocations() {
+               return polarLocations;
+       }
+
+       @Override
+    public Point2D transform(V v) {
+               PolarPoint pp = polarLocations.get(v);
+               double centerX = getSize().getWidth()/2;
+               double centerY = getSize().getHeight()/2;
+               Point2D cartesian = PolarPoint.polarToCartesian(pp);
+               cartesian.setLocation(cartesian.getX()+centerX,cartesian.getY()+centerY);
+               return cartesian;
+       }
+       
+       private Point2D getMaxXY() {
+               double maxx = 0;
+               double maxy = 0;
+               for(Point2D p : locations.values()) {
+                       maxx = Math.max(maxx, p.getX());
+                       maxy = Math.max(maxy, p.getY());
+               }
+               return new Point2D.Double(maxx,maxy);
+       }
+       
+       private void setRadialLocations() {
+               Point2D max = getMaxXY();
+               double maxx = max.getX();
+               double maxy = max.getY();
+               maxx = Math.max(maxx, size.width);
+               double theta = 2*Math.PI/maxx;
+
+               double deltaRadius = size.width/2/maxy;
+               for(Map.Entry<V, Point2D> entry : locations.entrySet()) {
+                       V v = entry.getKey();
+                       Point2D p = entry.getValue();
+                       PolarPoint polarPoint = new PolarPoint(p.getX()*theta, (p.getY() - this.distY)*deltaRadius);
+                       polarLocations.put(v, polarPoint);
+               }
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/RadiusGraphElementAccessor.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/RadiusGraphElementAccessor.java
new file mode 100644 (file)
index 0000000..5f12c3c
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2005, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ * 
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ * 
+ *
+ * Created on Apr 12, 2005
+ */
+package edu.uci.ics.jung.algorithms.layout;
+
+import java.awt.Shape;
+import java.awt.geom.Point2D;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import edu.uci.ics.jung.graph.Graph;
+
+
+/**
+ * Simple implementation of PickSupport that returns the vertex or edge
+ * that is closest to the specified location.  This implementation
+ * provides the same picking options that were available in
+ * previous versions of AbstractLayout.
+ * 
+ * <p>No element will be returned that is farther away than the specified 
+ * maximum distance.
+ * 
+ * @author Tom Nelson
+ * @author Joshua O'Madadhain
+ */
+public class RadiusGraphElementAccessor<V, E> implements GraphElementAccessor<V, E> {
+    
+    protected double maxDistance;
+    
+    /**
+     * Creates an instance with an effectively infinite default maximum distance.
+     */
+    public RadiusGraphElementAccessor() {
+        this(Math.sqrt(Double.MAX_VALUE - 1000));
+    }
+    
+    /**
+     * Creates an instance with the specified default maximum distance.
+     */
+    public RadiusGraphElementAccessor(double maxDistance) {
+        this.maxDistance = maxDistance;
+    }
+    
+       /**
+        * Gets the vertex nearest to the location of the (x,y) location selected,
+        * within a distance of <tt>maxDistance</tt>. Iterates through all
+        * visible vertices and checks their distance from the click. Override this
+        * method to provde a more efficient implementation.
+        */
+       public V getVertex(Layout<V,E> layout, double x, double y) {
+           return getVertex(layout, x, y, this.maxDistance);
+       }
+
+       /**
+        * Gets the vertex nearest to the location of the (x,y) location selected,
+        * within a distance of <tt>maxDistance</tt>. Iterates through all
+        * visible vertices and checks their distance from the click. Override this
+        * method to provde a more efficient implementation.
+        * @param x
+        * @param y
+        * @param maxDistance temporarily overrides member maxDistance
+        */
+       public V getVertex(Layout<V,E> layout, double x, double y, double maxDistance) {
+               double minDistance = maxDistance * maxDistance;
+        V closest = null;
+               while(true) {
+                   try {
+                for(V v : layout.getGraph().getVertices()) {
+
+                           Point2D p = layout.transform(v);
+                           double dx = p.getX() - x;
+                           double dy = p.getY() - y;
+                           double dist = dx * dx + dy * dy;
+                           if (dist < minDistance) {
+                               minDistance = dist;
+                               closest = v;
+                           }
+                       }
+                       break;
+                   } catch(ConcurrentModificationException cme) {}
+               }
+               return closest;
+       }
+       
+       public Collection<V> getVertices(Layout<V,E> layout, Shape rectangle) {
+               Set<V> pickedVertices = new HashSet<V>();
+               while(true) {
+                   try {
+                for(V v : layout.getGraph().getVertices()) {
+
+                           Point2D p = layout.transform(v);
+                           if(rectangle.contains(p)) {
+                               pickedVertices.add(v);
+                           }
+                       }
+                       break;
+                   } catch(ConcurrentModificationException cme) {}
+               }
+               return pickedVertices;
+       }
+       
+       /**
+        * Gets the edge nearest to the location of the (x,y) location selected.
+        * Calls the longer form of the call.
+        */
+       public E getEdge(Layout<V,E> layout, double x, double y) {
+           return getEdge(layout, x, y, this.maxDistance);
+       }
+
+       /**
+        * Gets the edge nearest to the location of the (x,y) location selected,
+        * within a distance of <tt>maxDistance</tt>, Iterates through all
+        * visible edges and checks their distance from the click. Override this
+        * method to provide a more efficient implementation.
+        * 
+        * @param x
+        * @param y
+        * @param maxDistance temporarily overrides member maxDistance
+        * @return Edge closest to the click.
+        */
+       public E getEdge(Layout<V,E> layout, double x, double y, double maxDistance) {
+               double minDistance = maxDistance * maxDistance;
+               E closest = null;
+               while(true) {
+                   try {
+                for(E e : layout.getGraph().getEdges()) {
+
+                           // Could replace all this set stuff with getFrom_internal() etc.
+                    Graph<V, E> graph = layout.getGraph();
+                           Collection<V> vertices = graph.getIncidentVertices(e);
+                           Iterator<V> vertexIterator = vertices.iterator();
+                           V v1 = vertexIterator.next();
+                           V v2 = vertexIterator.next();
+                           // Get coords
+                           Point2D p1 = layout.transform(v1);
+                           Point2D p2 = layout.transform(v2);
+                           double x1 = p1.getX();
+                           double y1 = p1.getY();
+                           double x2 = p2.getX();
+                           double y2 = p2.getY();
+                           // Calculate location on line closest to (x,y)
+                           // First, check that v1 and v2 are not coincident.
+                           if (x1 == x2 && y1 == y2)
+                               continue;
+                           double b =
+                               ((y - y1) * (y2 - y1) + (x - x1) * (x2 - x1))
+                               / ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
+                           //
+                           double distance2; // square of the distance
+                           if (b <= 0)
+                               distance2 = (x - x1) * (x - x1) + (y - y1) * (y - y1);
+                           else if (b >= 1)
+                               distance2 = (x - x2) * (x - x2) + (y - y2) * (y - y2);
+                           else {
+                               double x3 = x1 + b * (x2 - x1);
+                               double y3 = y1 + b * (y2 - y1);
+                               distance2 = (x - x3) * (x - x3) + (y - y3) * (y - y3);
+                           }
+                           
+                           if (distance2 < minDistance) {
+                               minDistance = distance2;
+                               closest = e;
+                           }
+                       }
+                       break;
+                   } catch(ConcurrentModificationException cme) {}
+               }
+               return closest;
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/SpringLayout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/SpringLayout.java
new file mode 100644 (file)
index 0000000..d21c2a1
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.layout;
+
+import edu.uci.ics.jung.algorithms.layout.util.RandomLocationTransformer;
+import edu.uci.ics.jung.algorithms.util.IterativeContext;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.Pair;
+
+import org.apache.commons.collections15.Factory;
+import org.apache.commons.collections15.Transformer;
+import org.apache.commons.collections15.functors.ConstantTransformer;
+import org.apache.commons.collections15.map.LazyMap;
+
+import java.awt.Dimension;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.geom.Point2D;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The SpringLayout package represents a visualization of a set of nodes. The
+ * SpringLayout, which is initialized with a Graph, assigns X/Y locations to
+ * each node. When called <code>relax()</code>, the SpringLayout moves the
+ * visualization forward one step.
+ *
+ * @author Danyel Fisher
+ * @author Joshua O'Madadhain
+ */
+public class SpringLayout<V, E> extends AbstractLayout<V,E> implements IterativeContext {
+
+    protected double stretch = 0.70;
+    protected Transformer<E, Integer> lengthFunction;
+    protected int repulsion_range_sq = 100 * 100;
+    protected double force_multiplier = 1.0 / 3.0;
+
+    protected Map<V, SpringVertexData> springVertexData =
+       LazyMap.decorate(new HashMap<V, SpringVertexData>(),
+                       new Factory<SpringVertexData>() {
+                                       public SpringVertexData create() {
+                                               return new SpringVertexData();
+                                       }});
+
+    /**
+     * Constructor for a SpringLayout for a raw graph with associated
+     * dimension--the input knows how big the graph is. Defaults to the unit
+     * length function.
+     */
+    @SuppressWarnings("unchecked")
+    public SpringLayout(Graph<V,E> g) {
+        this(g, new ConstantTransformer(30));
+    }
+
+    /**
+     * Constructor for a SpringLayout for a raw graph with associated component.
+     *
+     * @param g the {@code Graph} to lay out
+     * @param length_function provides a length for each edge
+     */
+    public SpringLayout(Graph<V,E> g, Transformer<E, Integer> length_function)
+    {
+        super(g);
+        this.lengthFunction = length_function;
+    }
+
+    /**
+     * Returns the current value for the stretch parameter.
+     * @see #setStretch(double)
+     */
+    public double getStretch() {
+        return stretch;
+    }
+
+    /**
+     * Sets the dimensions of the available space for layout to {@code size}.
+     */
+       @Override
+       public void setSize(Dimension size) {
+               if(initialized == false)
+                       setInitializer(new RandomLocationTransformer<V>(size));
+               super.setSize(size);
+       }
+
+    /**
+     * <p>Sets the stretch parameter for this instance.  This value
+     * specifies how much the degrees of an edge's incident vertices
+     * should influence how easily the endpoints of that edge
+     * can move (that is, that edge's tendency to change its length).</p>
+     *
+     * <p>The default value is 0.70.  Positive values less than 1 cause
+     * high-degree vertices to move less than low-degree vertices, and
+     * values > 1 cause high-degree vertices to move more than
+     * low-degree vertices.  Negative values will have unpredictable
+     * and inconsistent results.</p>
+     * @param stretch
+     */
+    public void setStretch(double stretch) {
+        this.stretch = stretch;
+    }
+
+    /**
+     * Returns the current value for the node repulsion range.
+     * @see #setRepulsionRange(int)
+     */
+    public int getRepulsionRange() {
+        return (int)(Math.sqrt(repulsion_range_sq));
+    }
+
+    /**
+     * Sets the node repulsion range (in drawing area units) for this instance.
+     * Outside this range, nodes do not repel each other.  The default value
+     * is 100.  Negative values are treated as their positive equivalents.
+     * @param range
+     */
+    public void setRepulsionRange(int range) {
+        this.repulsion_range_sq = range * range;
+    }
+
+    /**
+     * Returns the current value for the edge length force multiplier.
+     * @see #setForceMultiplier(double)
+     */
+    public double getForceMultiplier() {
+        return force_multiplier;
+    }
+
+    /**
+     * Sets the force multiplier for this instance.  This value is used to
+     * specify how strongly an edge "wants" to be its default length
+     * (higher values indicate a greater attraction for the default length),
+     * which affects how much its endpoints move at each timestep.
+     * The default value is 1/3.  A value of 0 turns off any attempt by the
+     * layout to cause edges to conform to the default length.  Negative
+     * values cause long edges to get longer and short edges to get shorter; use
+     * at your own risk.
+     */
+    public void setForceMultiplier(double force) {
+        this.force_multiplier = force;
+    }
+
+    public void initialize() {
+    }
+
+    /**
+     * Relaxation step. Moves all nodes a smidge.
+     */
+    public void step() {
+       try {
+               for(V v : getGraph().getVertices()) {
+                       SpringVertexData svd = springVertexData.get(v);
+                       if (svd == null) {
+                               continue;
+                       }
+                       svd.dx /= 4;
+                       svd.dy /= 4;
+                       svd.edgedx = svd.edgedy = 0;
+                       svd.repulsiondx = svd.repulsiondy = 0;
+               }
+       } catch(ConcurrentModificationException cme) {
+               step();
+       }
+
+       relaxEdges();
+       calculateRepulsion();
+       moveNodes();
+    }
+
+    protected void relaxEdges() {
+       try {
+               for(E e : getGraph().getEdges()) {
+                   Pair<V> endpoints = getGraph().getEndpoints(e);
+                       V v1 = endpoints.getFirst();
+                       V v2 = endpoints.getSecond();
+
+                       Point2D p1 = transform(v1);
+                       Point2D p2 = transform(v2);
+                       if(p1 == null || p2 == null) continue;
+                       double vx = p1.getX() - p2.getX();
+                       double vy = p1.getY() - p2.getY();
+                       double len = Math.sqrt(vx * vx + vy * vy);
+
+                       double desiredLen = lengthFunction.transform(e);
+
+                       // round from zero, if needed [zero would be Bad.].
+                       len = (len == 0) ? .0001 : len;
+
+                       double f = force_multiplier * (desiredLen - len) / len;
+
+                       f = f * Math.pow(stretch, (getGraph().degree(v1) + getGraph().degree(v2) - 2));
+
+                       // the actual movement distance 'dx' is the force multiplied by the
+                       // distance to go.
+                       double dx = f * vx;
+                       double dy = f * vy;
+                       SpringVertexData v1D, v2D;
+                       v1D = springVertexData.get(v1);
+                       v2D = springVertexData.get(v2);
+
+                       v1D.edgedx += dx;
+                       v1D.edgedy += dy;
+                       v2D.edgedx += -dx;
+                       v2D.edgedy += -dy;
+               }
+       } catch(ConcurrentModificationException cme) {
+               relaxEdges();
+       }
+    }
+
+    protected void calculateRepulsion() {
+        try {
+        for (V v : getGraph().getVertices()) {
+            if (isLocked(v)) continue;
+
+            SpringVertexData svd = springVertexData.get(v);
+            if(svd == null) continue;
+            double dx = 0, dy = 0;
+
+            for (V v2 : getGraph().getVertices()) {
+                if (v == v2) continue;
+                Point2D p = transform(v);
+                Point2D p2 = transform(v2);
+                if(p == null || p2 == null) continue;
+                double vx = p.getX() - p2.getX();
+                double vy = p.getY() - p2.getY();
+                double distanceSq = p.distanceSq(p2);
+                if (distanceSq == 0) {
+                    dx += Math.random();
+                    dy += Math.random();
+                } else if (distanceSq < repulsion_range_sq) {
+                    double factor = 1;
+                    dx += factor * vx / distanceSq;
+                    dy += factor * vy / distanceSq;
+                }
+            }
+            double dlen = dx * dx + dy * dy;
+            if (dlen > 0) {
+                dlen = Math.sqrt(dlen) / 2;
+                svd.repulsiondx += dx / dlen;
+                svd.repulsiondy += dy / dlen;
+            }
+        }
+        } catch(ConcurrentModificationException cme) {
+            calculateRepulsion();
+        }
+    }
+
+    protected void moveNodes()
+    {
+        synchronized (getSize()) {
+            try {
+                for (V v : getGraph().getVertices()) {
+                    if (isLocked(v)) continue;
+                    SpringVertexData vd = springVertexData.get(v);
+                    if(vd == null) continue;
+                    Point2D xyd = transform(v);
+
+                    vd.dx += vd.repulsiondx + vd.edgedx;
+                    vd.dy += vd.repulsiondy + vd.edgedy;
+
+                    // keeps nodes from moving any faster than 5 per time unit
+                    xyd.setLocation(xyd.getX()+Math.max(-5, Math.min(5, vd.dx)),
+                               xyd.getY()+Math.max(-5, Math.min(5, vd.dy)));
+
+                    Dimension d = getSize();
+                    int width = d.width;
+                    int height = d.height;
+
+                    if (xyd.getX() < 0) {
+                        xyd.setLocation(0, xyd.getY());
+                    } else if (xyd.getX() > width) {
+                        xyd.setLocation(width, xyd.getY());
+                    }
+                    if (xyd.getY() < 0) {
+                        xyd.setLocation(xyd.getX(), 0);
+                    } else if (xyd.getY() > height) {
+                        xyd.setLocation(xyd.getX(), height);
+                    }
+
+                }
+            } catch(ConcurrentModificationException cme) {
+                moveNodes();
+            }
+        }
+    }
+
+    protected static class SpringVertexData {
+        protected double edgedx;
+        protected double edgedy;
+        protected double repulsiondx;
+        protected double repulsiondy;
+
+        /** movement speed, x */
+        protected double dx;
+
+        /** movement speed, y */
+        protected double dy;
+    }
+
+
+    /**
+     * Used for changing the size of the layout in response to a component's size.
+     */
+    public class SpringDimensionChecker extends ComponentAdapter {
+        @Override
+        public void componentResized(ComponentEvent e) {
+            setSize(e.getComponent().getSize());
+        }
+    }
+
+    /**
+     * This one is an incremental visualization
+     */
+    public boolean isIncremental() {
+        return true;
+    }
+
+    /**
+     * For now, we pretend it never finishes.
+     */
+    public boolean done() {
+        return false;
+    }
+
+    /**
+     * No effect.
+     */
+       public void reset() {
+       }
+}
\ No newline at end of file
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/SpringLayout2.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/SpringLayout2.java
new file mode 100644 (file)
index 0000000..e62a30c
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ * 
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.layout;
+
+import java.awt.Dimension;
+import java.awt.geom.Point2D;
+import java.util.ConcurrentModificationException;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * The SpringLayout package represents a visualization of a set of nodes. The
+ * SpringLayout, which is initialized with a Graph, assigns X/Y locations to
+ * each node. When called <code>relax()</code>, the SpringLayout moves the
+ * visualization forward one step.
+ * 
+ * 
+ * 
+ * @author Danyel Fisher
+ * @author Joshua O'Madadhain
+ */
+public class SpringLayout2<V, E> extends SpringLayout<V,E> 
+{
+    protected int currentIteration;
+    protected int averageCounter;
+    protected int loopCountMax = 4;
+    protected boolean done;
+    
+    protected Point2D averageDelta = new Point2D.Double();
+    
+    /**
+     * Constructor for a SpringLayout for a raw graph with associated
+     * dimension--the input knows how big the graph is. Defaults to the unit
+     * length function.
+     */
+    @SuppressWarnings("unchecked")
+    public SpringLayout2(Graph<V,E> g) {
+        super(g);
+    }
+
+    /**
+     * Constructor for a SpringLayout for a raw graph with associated component.
+     *
+     * @param g the {@code Graph} to lay out
+     * @param length_function provides a length for each edge
+     */
+    public SpringLayout2(Graph<V,E> g, Transformer<E, Integer> length_function)
+    {
+        super(g, length_function);
+    }
+
+    /**
+     * Relaxation step. Moves all nodes a smidge.
+     */
+    @Override
+    public void step() {
+        super.step();
+       currentIteration++;
+       testAverageDeltas();
+    }
+    
+    private void testAverageDeltas() {
+       double dx = this.averageDelta.getX();
+       double dy = this.averageDelta.getY();
+       if(Math.abs(dx) < .001 && Math.abs(dy) < .001) {
+               done = true;
+               System.err.println("done, dx="+dx+", dy="+dy);
+       }
+        if(currentIteration > loopCountMax) {
+               this.averageDelta.setLocation(0,0);
+               averageCounter = 0;
+               currentIteration = 0;
+        }
+    }
+
+    @Override
+    protected void moveNodes() {
+        synchronized (getSize()) {
+            try {
+                for (V v : getGraph().getVertices()) {
+                    if (isLocked(v)) continue;
+                    SpringVertexData vd = springVertexData.get(v);
+                    if(vd == null) continue;
+                    Point2D xyd = transform(v);
+                    
+                    vd.dx += vd.repulsiondx + vd.edgedx;
+                    vd.dy += vd.repulsiondy + vd.edgedy;
+                    
+//                    int currentCount = currentIteration % this.loopCountMax;
+//                    System.err.println(averageCounter+" --- vd.dx="+vd.dx+", vd.dy="+vd.dy);
+//                    System.err.println("averageDelta was "+averageDelta);
+
+                    averageDelta.setLocation(
+                               ((averageDelta.getX() * averageCounter) + vd.dx) / (averageCounter+1),
+                               ((averageDelta.getY() * averageCounter) + vd.dy) / (averageCounter+1)
+                               );
+//                    System.err.println("averageDelta now "+averageDelta);
+//                    System.err.println();
+                    averageCounter++;
+                    
+                    // keeps nodes from moving any faster than 5 per time unit
+                    xyd.setLocation(xyd.getX()+Math.max(-5, Math.min(5, vd.dx)),
+                               xyd.getY()+Math.max(-5, Math.min(5, vd.dy)));
+                    
+                    Dimension d = getSize();
+                    int width = d.width;
+                    int height = d.height;
+                    
+                    if (xyd.getX() < 0) {
+                        xyd.setLocation(0, xyd.getY());//                     setX(0);
+                    } else if (xyd.getX() > width) {
+                        xyd.setLocation(width, xyd.getY());             //setX(width);
+                    }
+                    if (xyd.getY() < 0) {
+                        xyd.setLocation(xyd.getX(),0);//setY(0);
+                    } else if (xyd.getY() > height) {
+                        xyd.setLocation(xyd.getX(), height);      //setY(height);
+                    }
+                    
+                }
+            } catch(ConcurrentModificationException cme) {
+                moveNodes();
+            }
+        }
+    }
+
+    @Override
+    public boolean done() {
+        return done;
+    }
+
+}
\ No newline at end of file
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/StaticLayout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/StaticLayout.java
new file mode 100644 (file)
index 0000000..31b3255
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Created on Jul 21, 2005
+ *
+ * Copyright (c) 2005, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.layout;
+
+import java.awt.Dimension;
+import java.awt.geom.Point2D;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * StaticLayout places the vertices in the locations specified by its Transformer<V,Point2D>
+ * initializer. Vertex locations can be placed in a Map<V,Point2D> and then supplied to
+ * this layout as follows:
+ * <code>
+            Transformer<V,Point2D> vertexLocations =
+               TransformerUtils.mapTransformer(map);
+ * </code>
+ * @author Tom Nelson - tomnelson@dev.java.net
+ *
+ * @param <V>
+ * @param <E>
+ */
+public class StaticLayout<V, E> extends AbstractLayout<V,E> {
+       
+    /**
+     * Creates an instance for the specified graph, locations, and size.
+     */
+    public StaticLayout(Graph<V,E> graph, Transformer<V,Point2D> initializer, Dimension size) {
+        super(graph, initializer, size);
+    }
+    
+    /**
+     * Creates an instance for the specified graph and locations, with default size.
+     */
+    public StaticLayout(Graph<V,E> graph, Transformer<V,Point2D> initializer) {
+        super(graph, initializer);
+    }
+    
+    /**
+     * Creates an instance for the specified graph and default size; vertex locations
+     * are randomly assigned.
+     */
+    public StaticLayout(Graph<V,E> graph) {
+       super(graph);
+    }
+    
+    /**
+     * Creates an instance for the specified graph and size.
+     */
+    public StaticLayout(Graph<V,E> graph, Dimension size) {
+       super(graph, size);
+    }
+    
+    public void initialize() {}
+
+       public void reset() {}
+
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/TreeLayout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/TreeLayout.java
new file mode 100644 (file)
index 0000000..4bebd3a
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2005, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ *
+ * Created on Jul 9, 2005
+ */
+
+package edu.uci.ics.jung.algorithms.layout;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.geom.Point2D;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections15.Transformer;
+import org.apache.commons.collections15.map.LazyMap;
+
+import edu.uci.ics.jung.graph.Forest;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.TreeUtils;
+
+/**
+ * @author Karlheinz Toni
+ * @author Tom Nelson - converted to jung2
+ *  
+ */
+
+public class TreeLayout<V,E> implements Layout<V,E> {
+
+       protected Dimension size = new Dimension(600,600);
+       protected Forest<V,E> graph;
+       protected Map<V,Integer> basePositions = new HashMap<V,Integer>();
+
+    protected Map<V, Point2D> locations = 
+       LazyMap.decorate(new HashMap<V, Point2D>(),
+                       new Transformer<V,Point2D>() {
+                                       public Point2D transform(V arg0) {
+                                               return new Point2D.Double();
+                                       }});
+    
+    protected transient Set<V> alreadyDone = new HashSet<V>();
+
+    /**
+     * The default horizontal vertex spacing.  Initialized to 50.
+     */
+    public static int DEFAULT_DISTX = 50;
+    
+    /**
+     * The default vertical vertex spacing.  Initialized to 50.
+     */
+    public static int DEFAULT_DISTY = 50;
+    
+    /**
+     * The horizontal vertex spacing.  Defaults to {@code DEFAULT_XDIST}.
+     */
+    protected int distX = 50;
+    
+    /**
+     * The vertical vertex spacing.  Defaults to {@code DEFAULT_YDIST}.
+     */
+    protected int distY = 50;
+    
+    protected transient Point m_currentPoint = new Point();
+
+    /**
+     * Creates an instance for the specified graph with default X and Y distances.
+     */
+    public TreeLayout(Forest<V,E> g) {
+       this(g, DEFAULT_DISTX, DEFAULT_DISTY);
+    }
+
+    /**
+     * Creates an instance for the specified graph and X distance with
+     * default Y distance.
+     */
+    public TreeLayout(Forest<V,E> g, int distx) {
+        this(g, distx, DEFAULT_DISTY);
+    }
+
+    /**
+     * Creates an instance for the specified graph, X distance, and Y distance.
+     */
+    public TreeLayout(Forest<V,E> g, int distx, int disty) {
+        if (g == null)
+            throw new IllegalArgumentException("Graph must be non-null");
+        if (distx < 1 || disty < 1)
+            throw new IllegalArgumentException("X and Y distances must each be positive");
+       this.graph = g;
+        this.distX = distx;
+        this.distY = disty;
+        buildTree();
+    }
+    
+       protected void buildTree() {
+        this.m_currentPoint = new Point(0, 20);
+        Collection<V> roots = TreeUtils.getRoots(graph);
+        if (roots.size() > 0 && graph != null) {
+                       calculateDimensionX(roots);
+                       for(V v : roots) {
+                       calculateDimensionX(v);
+                       m_currentPoint.x += this.basePositions.get(v)/2 + this.distX;
+                       buildTree(v, this.m_currentPoint.x);
+               }
+        }
+        int width = 0;
+        for(V v : roots) {
+               width += basePositions.get(v);
+        }
+    }
+
+    protected void buildTree(V v, int x) {
+
+        if (!alreadyDone.contains(v)) {
+            alreadyDone.add(v);
+
+            //go one level further down
+            this.m_currentPoint.y += this.distY;
+            this.m_currentPoint.x = x;
+
+            this.setCurrentPositionFor(v);
+
+            int sizeXofCurrent = basePositions.get(v);
+
+            int lastX = x - sizeXofCurrent / 2;
+
+            int sizeXofChild;
+            int startXofChild;
+
+            for (V element : graph.getSuccessors(v)) {
+                sizeXofChild = this.basePositions.get(element);
+                startXofChild = lastX + sizeXofChild / 2;
+                buildTree(element, startXofChild);
+                lastX = lastX + sizeXofChild + distX;
+            }
+            this.m_currentPoint.y -= this.distY;
+        }
+    }
+    
+    private int calculateDimensionX(V v) {
+
+        int size = 0;
+        int childrenNum = graph.getSuccessors(v).size();
+
+        if (childrenNum != 0) {
+            for (V element : graph.getSuccessors(v)) {
+                size += calculateDimensionX(element) + distX;
+            }
+        }
+        size = Math.max(0, size - distX);
+        basePositions.put(v, size);
+
+        return size;
+    }
+
+    private int calculateDimensionX(Collection<V> roots) {
+
+       int size = 0;
+       for(V v : roots) {
+               int childrenNum = graph.getSuccessors(v).size();
+
+               if (childrenNum != 0) {
+                       for (V element : graph.getSuccessors(v)) {
+                               size += calculateDimensionX(element) + distX;
+                       }
+               }
+               size = Math.max(0, size - distX);
+               basePositions.put(v, size);
+       }
+
+       return size;
+    }
+    
+    /**
+     * This method is not supported by this class.  The size of the layout
+     * is determined by the topology of the tree, and by the horizontal 
+     * and vertical spacing (optionally set by the constructor).
+     */
+    public void setSize(Dimension size) {
+        throw new UnsupportedOperationException("Size of TreeLayout is set" +
+                " by vertex spacing in constructor");
+    }
+
+    protected void setCurrentPositionFor(V vertex) {
+       int x = m_currentPoint.x;
+       int y = m_currentPoint.y;
+       if(x < 0) size.width -= x;
+       
+       if(x > size.width-distX) 
+               size.width = x + distX;
+       
+       if(y < 0) size.height -= y;
+       if(y > size.height-distY) 
+               size.height = y + distY;
+       locations.get(vertex).setLocation(m_currentPoint);
+
+    }
+
+       public Graph<V,E> getGraph() {
+               return graph;
+       }
+
+       public Dimension getSize() {
+               return size;
+       }
+
+       public void initialize() {
+
+       }
+
+       public boolean isLocked(V v) {
+               return false;
+       }
+
+       public void lock(V v, boolean state) {
+       }
+
+       public void reset() {
+       }
+
+       public void setGraph(Graph<V,E> graph) {
+               if(graph instanceof Forest) {
+                       this.graph = (Forest<V,E>)graph;
+                       buildTree();
+               } else {
+                       throw new IllegalArgumentException("graph must be a Forest");
+               }
+       }
+
+       public void setInitializer(Transformer<V, Point2D> initializer) {
+       }
+       
+    /**
+     * Returns the center of this layout's area.
+     */
+       public Point2D getCenter() {
+               return new Point2D.Double(size.getWidth()/2,size.getHeight()/2);
+       }
+
+       public void setLocation(V v, Point2D location) {
+               locations.get(v).setLocation(location);
+       }
+       
+       public Point2D transform(V v) {
+               return locations.get(v);
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/package.html
new file mode 100644 (file)
index 0000000..a5ed0d0
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 
+-->
+</head>
+<body>
+
+Algorithms for assigning 2D coordinates (typically used for graph visualizations) 
+to vertices.
+Current layout algorithms include:
+<ul>
+<li/><code>Layout, AbstractLayout</code>: interface and abstract class defining the Layout contract and handling
+some common implementation details
+<li/><code>AggregateLayout</code>: allows multiple layouts to be combined and manipulated as one layout
+<li/><code>BalloonLayout</code>: places vertices on nested circles (trees/forests only)
+<li/><code>CircleLayout</code>: places vertices on a circle
+<li/><code>DAGLayout</code>: places vertices in a hierarchy (directed acyclic graphs only)
+<li/><code>FRLayout</code>: Fruchterman-Reingold algorithm (force-directed)
+<li/><code>ISOMLayout</code>: self-organizing map layout
+<li/><code>KKLayout</code>: Kamada-Kawai algorithm (tries to maintain specified distances)
+<li/><code>RadialTreeLayout</code>: places vertices on concentric circles (trees only)
+<li/><code>SpringLayout</code>: simple force-directed layout
+<li/><code>StaticLayout</code>: places vertices at user-specified locations
+<li/><code>TreeLayout</code>: simple tree/forest layout
+</ul>
+
+Rendering and other aspects of visualization are handled in the <code>visualization</code> package.
+
+</body>
+</html>
+
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/util/RandomLocationTransformer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/util/RandomLocationTransformer.java
new file mode 100644 (file)
index 0000000..34428b1
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Created on Jul 19, 2005
+ *
+ * Copyright (c) 2005, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.layout.util;
+
+import java.awt.Dimension;
+import java.awt.geom.Point2D;
+import java.util.Date;
+import java.util.Random;
+
+import org.apache.commons.collections15.Transformer;
+
+/**
+ * Transforms the input type into a random location within
+ * the bounds of the Dimension property.
+ * This is used as the backing Transformer for the LazyMap
+ * for many Layouts,
+ * and provides a random location for unmapped vertices
+ * the first time they are accessed.
+ * 
+ * @author Tom Nelson
+ *
+ * @param <V>
+ */
+public class RandomLocationTransformer<V> implements Transformer<V,Point2D> {
+
+       Dimension d;
+       Random random;
+    
+    /**
+     * Creates an instance with the specified size which uses the current time 
+     * as the random seed.
+     */
+    public RandomLocationTransformer(Dimension d) {
+       this(d, new Date().getTime());
+    }
+    
+    /**
+     * Creates an instance with the specified dimension and random seed.
+     * @param d
+     * @param seed
+     */
+    public RandomLocationTransformer(final Dimension d, long seed) {
+       this.d = d;
+       this.random = new Random(seed);
+    }
+    
+    public Point2D transform(V v) {
+        return new Point2D.Double(random.nextDouble() * d.width, random.nextDouble() * d.height);
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/util/Relaxer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/util/Relaxer.java
new file mode 100644 (file)
index 0000000..a31113f
--- /dev/null
@@ -0,0 +1,43 @@
+package edu.uci.ics.jung.algorithms.layout.util;
+
+/**
+ * Interface for operating the relax iterations on a layout.
+ * 
+ * @author Tom Nelson - tomnelson@dev.java.net
+ *
+ */
+public interface Relaxer {
+       
+       /**
+        * Execute a loop of steps in a new Thread,
+        * firing an event after each step.
+        */
+       void relax();
+       
+       /**
+        * Execute a loop of steps in the calling
+        * thread, firing no events.
+        */
+       void prerelax();
+       
+       /**
+        * Make the relaxer thread wait.
+        */
+       void pause();
+       
+       /**
+        * Make the relaxer thread resume.
+        *
+        */
+       void resume();
+       
+       /**
+        * Set flags to stop the relaxer thread.
+        */
+       void stop();
+
+       /**
+        * Sets the sleep time.
+        */
+       void setSleepTime(long i);
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/util/VisRunner.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/util/VisRunner.java
new file mode 100644 (file)
index 0000000..14f6dfc
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2005, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ *
+ * 
+ */
+package edu.uci.ics.jung.algorithms.layout.util;
+
+import edu.uci.ics.jung.algorithms.util.IterativeContext;
+
+/**
+ * 
+ * Implementation of a relaxer thread for layouts.
+ * Extracted from the {@code VisualizationModel} in previous
+ * versions of JUNG.
+ * 
+ * @author Tom Nelson - tomnelson@dev.java.net
+ *
+ */
+public class VisRunner implements Relaxer, Runnable {
+       
+       protected boolean running;
+       protected IterativeContext process;
+       protected boolean stop;
+       protected boolean manualSuspend;
+       protected Thread thread;
+       
+       /**
+        * how long the relaxer thread pauses between iteration loops.
+        */
+       protected long sleepTime = 100L;
+
+       
+       /**
+        * Creates an instance for the specified process.
+        */
+       public VisRunner(IterativeContext process) {
+               this.process = process;
+       }
+
+       /**
+        * @return the relaxerThreadSleepTime
+        */
+       public long getSleepTime() {
+               return sleepTime;
+       }
+
+       /**
+        * @param sleepTime the sleep time to set for this thread
+        */
+       public void setSleepTime(long sleepTime) {
+               this.sleepTime = sleepTime;
+       }
+       
+       public void prerelax() {
+               manualSuspend = true;
+               long timeNow = System.currentTimeMillis();
+               while (System.currentTimeMillis() - timeNow < 500 && !process.done()) {
+                       process.step();
+               }
+               manualSuspend = false;
+       }
+
+       public void pause() {
+               manualSuspend = true;
+       }
+
+       public void relax() {
+               // in case its running
+               stop();
+               stop = false;
+               thread = new Thread(this);
+               thread.setPriority(Thread.MIN_PRIORITY);
+               thread.start();
+       }
+       
+       /**
+        * Used for synchronization.
+        */
+       public Object pauseObject = new String("PAUSE OBJECT");
+
+       public void resume() {
+               manualSuspend = false;
+               if(running == false) {
+                       prerelax();
+                       relax();
+               } else {
+                       synchronized(pauseObject) {
+                               pauseObject.notifyAll();
+                       }
+               }
+       }
+
+       public synchronized void stop() {
+               if(thread != null) {
+                       manualSuspend = false;
+                       stop = true;
+                       // interrupt the relaxer, in case it is paused or sleeping
+                       // this should ensure that visRunnerIsRunning gets set to false
+                       try { thread.interrupt(); }
+                       catch(Exception ex) {
+                               // the applet security manager may have prevented this.
+                               // just sleep for a second to let the thread stop on its own
+                               try { Thread.sleep(1000); }
+                               catch(InterruptedException ie) {} // ignore
+                       }
+                       synchronized (pauseObject) {
+                               pauseObject.notifyAll();
+                       }
+               }
+       }
+
+       public void run() {
+           running = true;
+           try {
+               while (!process.done() && !stop) {
+                   synchronized (pauseObject) {
+                       while (manualSuspend && !stop) {
+                           try {
+                               pauseObject.wait();
+                           } catch (InterruptedException e) {
+                               // ignore
+                           }
+                       }
+                   }
+                   process.step();
+                   
+                   if (stop)
+                       return;
+                   
+                   try {
+                       Thread.sleep(sleepTime);
+                   } catch (InterruptedException ie) {
+                       // ignore
+                   }
+               }
+
+           } finally {
+               running = false;
+           }
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/util/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/util/package.html
new file mode 100644 (file)
index 0000000..356f7d5
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 
+-->
+</head>
+<body>
+
+Utility classes for updating layout positions.
+
+</body>
+</html>
+
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/matrix/MatrixElementOperations.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/matrix/MatrixElementOperations.java
new file mode 100644 (file)
index 0000000..1124bdf
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.matrix;
+
+import java.util.Map;
+
+
+/**
+ * An interface for specifying the behavior of graph/matrix operations
+ * for a particular element type.
+ * <P>
+ * Graph/matrix multiplication requires the definition of two operations: 
+ * <p>
+ * <ol>
+ * <li>
+ * Calculating an aggregate property of paths of length 2 between two
+ * vertices v1 and v2 (analogous to element multiplication in matrix
+ * arithmetic); this is handled by computePathData().
+ * </li>
+ * <li>
+ * Aggregating the properties of all such paths, and assigning the result to
+ * a new edge in the output graph (analogous to element addition in matrix
+ * arithmetic); this is handled by mergePaths().
+ * </li>
+ * </ol>
+ * <p>
+ * Together, computePathData() and mergePaths() specify how the equivalent of
+ * the vector inner (dot) product is to function.
+ * <p>
+ * For instance, to implement the equivalent of standard matrix multiplication
+ * on two graphs, computePathData() should return the products of the 
+ * weights of a two-edge path, and mergePaths() should add
+ * the output of computePathData() to an existing edge (or possibly create such
+ * an edge if none exists).
+ * 
+ * @author Joshua O'Madadhain
+ */
+public interface MatrixElementOperations<E>
+{
+    /**
+     * If either e or pathData is null, the effect of mergePaths() is
+     * implementation-dependent.
+     * 
+     * @param e                (possibly) existing edge in the output graph which
+     *                                         represents a path in the input graph(s)
+     * 
+     * @param pathData data (which represents another path with the same source
+     * and destination as e in the input graphs) which is to be merged into e
+     */
+    public void mergePaths(E e, Object pathData); 
+    
+    /**
+     * If either e1 or e2 is null, the Object reference returned should be null.
+     * 
+     * @param e1 first edge from 2-edge path in input graph(s)
+     * @param e2 second edge from 2-edge path in input graph(s)
+     * @return aggregation of data from the edges of the 2-edge path
+     * (from source of e1 to destination of e2) comprised of (e1, e2)
+     */
+    public Number computePathData(E e1, E e2);
+    
+    /**
+     * Returns a map from edges to values.
+     */
+    public Map<E,Number> getEdgeData();
+}
\ No newline at end of file
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/matrix/RealMatrixElementOperations.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/matrix/RealMatrixElementOperations.java
new file mode 100644 (file)
index 0000000..ada1406
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.matrix;
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Implements the basic matrix operations on double-precision values.  Assumes
+ * that the edges have a MutableDouble value.
+ * 
+ * @author Joshua O'Madadhain
+ */
+public class RealMatrixElementOperations<E> implements MatrixElementOperations<E>
+{
+    private Map<E,Number> edgeData = new HashMap<E,Number>();
+
+    /**
+     * Creates an instance using the specified edge values.
+     */
+    public RealMatrixElementOperations(Map<E,Number> edgeData)
+    {
+        this.edgeData = edgeData;
+    }
+
+       /**
+        * @see MatrixElementOperations#mergePaths(Object, Object)
+        */
+       public void mergePaths(E e, Object pathData) 
+    {
+
+        Number pd = (Number)pathData;
+        Number ed = edgeData.get(e);
+        if (ed == null) {
+               edgeData.put(e, pd);
+
+        } else {
+               edgeData.put(e, ed.doubleValue()+pd.doubleValue());
+
+        }
+
+       }
+
+       /**
+        * @see MatrixElementOperations#computePathData(Object, Object)
+        */
+       public Number computePathData(E e1, E e2) 
+    {
+        double d1 = edgeData.get(e1).doubleValue();
+        double d2 = edgeData.get(e2).doubleValue();
+        return d1*d2;
+       }
+
+       /**
+        * @return the edgeData
+        */
+       public Map<E, Number> getEdgeData() {
+               return edgeData;
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/matrix/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/matrix/package.html
new file mode 100644 (file)
index 0000000..6025a41
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+-->
+</head>
+<body>
+
+Mechanisms for dealing with graphs as matrices.  These include conversion to and
+from Colt matrices, and some matrix algorithms.
+</body>
+</html>
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/metrics/Metrics.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/metrics/Metrics.java
new file mode 100644 (file)
index 0000000..1dfcf12
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2008, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ * Created on Jun 7, 2008
+ * 
+ */
+package edu.uci.ics.jung.algorithms.metrics;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * A class consisting of static methods for calculating graph metrics.
+ */
+public class Metrics 
+{
+    /**
+     * Returns a <code>Map</code> of vertices to their clustering coefficients.
+     * The clustering coefficient cc(v) of a vertex v is defined as follows:
+     * <ul>
+     * <li/><code>degree(v) == {0,1}</code>: 0
+     * <li/><code>degree(v) == n, n &gt;= 2</code>: given S, the set of neighbors
+     * of <code>v</code>: cc(v) = (the sum over all w in S of the number of 
+     * other elements of w that are neighbors of w) / ((|S| * (|S| - 1) / 2).
+     * Less formally, the fraction of <code>v</code>'s neighbors that are also
+     * neighbors of each other. 
+     * <p><b>Note</b>: This algorithm treats its argument as an undirected graph;
+     * edge direction is ignored. 
+     * @param graph the graph whose clustering coefficients are to be calculated
+     * @see "The structure and function of complex networks, M.E.J. Newman, aps.arxiv.org/abs/cond-mat/0303516"
+     */
+    public static <V,E> Map<V, Double> clusteringCoefficients(Graph<V,E> graph)
+    {
+        Map<V,Double> coefficients = new HashMap<V,Double>();
+        
+        for (V v : graph.getVertices())
+        {
+            int n = graph.getNeighborCount(v);
+            if (n < 2)
+                coefficients.put(v, new Double(0));
+            else
+            {
+                // how many of v's neighbors are connected to each other?
+                ArrayList<V> neighbors = new ArrayList<V>(graph.getNeighbors(v));
+                double edge_count = 0;
+                for (int i = 0; i < n; i++)
+                {
+                    V w = neighbors.get(i);
+                    for (int j = i+1; j < n; j++ )
+                    {
+                        V x = neighbors.get(j);
+                        edge_count += graph.isNeighbor(w, x) ? 1 : 0;
+                    }
+                }
+                double possible_edges = (n * (n - 1))/2.0;
+                coefficients.put(v, new Double(edge_count / possible_edges));
+            }
+        }
+        
+        return coefficients;
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/metrics/StructuralHoles.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/metrics/StructuralHoles.java
new file mode 100644 (file)
index 0000000..aec84b9
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * Created on Sep 19, 2005
+ *
+ * Copyright (c) 2005, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.metrics;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * Calculates some of the measures from Burt's text "Structural Holes: 
+ * The Social Structure of Competition".
+ * 
+ * <p><b>Notes</b>: 
+ * <ul>
+ * <li/>Each of these measures assumes that each edge has an associated 
+ * non-null weight whose value is accessed through the specified 
+ * <code>Transformer</code> instance.
+ * <li/>Nonexistent edges are treated as edges with weight 0 for purposes 
+ * of edge weight calculations.
+ * </ul>
+ *  
+ * <p>Based on code donated by Jasper Voskuilen and 
+ * Diederik van Liere of the Department of Information and Decision Sciences
+ * at Erasmus University.</p>
+ * 
+ * @author Joshua O'Madadhain
+ * @author Jasper Voskuilen
+ * @see "Ronald Burt, Structural Holes: The Social Structure of Competition"
+ * @author Tom Nelson - converted to jung2
+ */
+public class StructuralHoles<V,E> {
+       
+    protected Transformer<E, ? extends Number> edge_weight;
+    protected Graph<V,E> g;
+    
+    /**
+     * Creates a <code>StructuralHoles</code> instance based on the 
+     * edge weights specified by <code>nev</code>.
+     */
+    public StructuralHoles(Graph<V,E> graph, Transformer<E, ? extends Number> nev) 
+    {
+        this.g = graph;
+        this.edge_weight = nev;
+    }
+
+    /**
+     * Burt's measure of the effective size of a vertex's network.  Essentially, the
+     * number of neighbors minus the average degree of those in <code>v</code>'s neighbor set,
+     * not counting ties to <code>v</code>.  Formally: 
+     * <pre>
+     * effectiveSize(v) = v.degree() - (sum_{u in N(v)} sum_{w in N(u), w !=u,v} p(v,w)*m(u,w))
+     * </pre>
+     * where 
+     * <ul>
+     * <li/><code>N(a) = a.getNeighbors()</code>
+     * <li/><code>p(v,w) =</code> normalized mutual edge weight of v and w
+     * <li/><code>m(u,w)</code> = maximum-scaled mutual edge weight of u and w
+     * </ul>
+     * @see #normalizedMutualEdgeWeight(Object, Object)
+     * @see #maxScaledMutualEdgeWeight(Object, Object) 
+     */
+    public double effectiveSize(V v)
+    {
+        double result = g.degree(v);
+        for(V u : g.getNeighbors(v)) {
+
+            for(V w : g.getNeighbors(u)) {
+
+                if (w != v && w != u)
+                    result -= normalizedMutualEdgeWeight(v,w) * 
+                              maxScaledMutualEdgeWeight(u,w);
+            }
+        }
+        return result;
+    }
+    
+    /**
+     * Returns the effective size of <code>v</code> divided by the number of 
+     * alters in <code>v</code>'s network.  (In other words, 
+     * <code>effectiveSize(v) / v.degree()</code>.)
+     * If <code>v.degree() == 0</code>, returns 0.
+     */
+    public double efficiency(V v) {
+        double degree = g.degree(v);
+        
+        if (degree == 0)
+            return 0;
+        else
+            return effectiveSize(v) / degree;
+    }
+
+    /**
+     * Burt's constraint measure (equation 2.4, page 55 of Burt, 1992). Essentially a
+     * measure of the extent to which <code>v</code> is invested in people who are invested in
+     * other of <code>v</code>'s alters (neighbors).  The "constraint" is characterized
+     * by a lack of primary holes around each neighbor.  Formally:
+     * <pre>
+     * constraint(v) = sum_{w in MP(v), w != v} localConstraint(v,w)
+     * </pre>
+     * where MP(v) is the subset of v's neighbors that are both predecessors and successors of v. 
+     * @see #localConstraint(Object, Object)
+     */
+    public double constraint(V v) {
+        double result = 0;
+        for(V w : g.getSuccessors(v)) {
+
+            if (v != w && g.isPredecessor(v,w))
+            {
+                result += localConstraint(v, w);
+            }
+        }
+
+        return result;
+    }
+
+    
+    /**
+     * Calculates the hierarchy value for a given vertex.  Returns <code>NaN</code> when
+     * <code>v</code>'s degree is 0, and 1 when <code>v</code>'s degree is 1.
+     * Formally:
+     * <pre>
+     * hierarchy(v) = (sum_{v in N(v), w != v} s(v,w) * log(s(v,w))}) / (v.degree() * Math.log(v.degree()) 
+     * </pre>
+     * where
+     * <ul>
+     * <li/><code>N(v) = v.getNeighbors()</code> 
+     * <li/><code>s(v,w) = localConstraint(v,w) / (aggregateConstraint(v) / v.degree())</code>
+     * </ul>
+     * @see #localConstraint(Object, Object)
+     * @see #aggregateConstraint(Object)
+     */
+    public double hierarchy(V v)
+    {
+        double v_degree = g.degree(v);
+        
+        if (v_degree == 0)
+            return Double.NaN;
+        if (v_degree == 1)
+            return 1;
+        
+        double v_constraint = aggregateConstraint(v);
+
+        double numerator = 0;
+        for (V w : g.getNeighbors(v)) {
+        
+            if (v != w)
+            {
+                double sl_constraint = localConstraint(v, w) / (v_constraint / v_degree);
+                numerator += sl_constraint * Math.log(sl_constraint);
+            }
+        }
+
+        return numerator / (v_degree * Math.log(v_degree));
+    }
+
+    /**
+     * Returns the local constraint on <code>v</code> from a lack of primary holes 
+     * around its neighbor <code>v2</code>.
+     * Based on Burt's equation 2.4.  Formally:
+     * <pre>
+     * localConstraint(v1, v2) = ( p(v1,v2) + ( sum_{w in N(v)} p(v1,w) * p(w, v2) ) )^2
+     * </pre>
+     * where 
+     * <ul>
+     * <li/><code>N(v) = v.getNeighbors()</code>
+     * <li/><code>p(v,w) =</code> normalized mutual edge weight of v and w
+     * </ul>
+     * @see #normalizedMutualEdgeWeight(Object, Object)
+     */
+    public double localConstraint(V v1, V v2) 
+    {
+        double nmew_vw = normalizedMutualEdgeWeight(v1, v2);
+        double inner_result = 0;
+        for (V w : g.getNeighbors(v1)) {
+
+            inner_result += normalizedMutualEdgeWeight(v1,w) * 
+                normalizedMutualEdgeWeight(w,v2);
+        }
+        return (nmew_vw + inner_result) * (nmew_vw + inner_result);
+    }
+    
+    /**
+     * The aggregate constraint on <code>v</code>.  Based on Burt's equation 2.7.  
+     * Formally:
+     * <pre>
+     * aggregateConstraint(v) = sum_{w in N(v)} localConstraint(v,w) * O(w)
+     * </pre>
+     * where
+     * <ul>
+     * <li/><code>N(v) = v.getNeighbors()</code>
+     * <li/><code>O(w) = organizationalMeasure(w)</code>
+     * </ul>
+     */
+    public double aggregateConstraint(V v)
+    {
+        double result = 0;
+        for (V w : g.getNeighbors(v)) {
+
+            result += localConstraint(v, w) * organizationalMeasure(g, w);
+        }
+        return result;
+    }
+    
+    /**
+     * A measure of the organization of individuals within the subgraph 
+     * centered on <code>v</code>.  Burt's text suggests that this is 
+     * in some sense a measure of how "replaceable" <code>v</code> is by 
+     * some other element of this subgraph.  Should be a number in the
+     * closed interval [0,1].
+     * 
+     * <p>This implementation returns 1.  Users may wish to override this
+     * method in order to define their own behavior.</p>
+     */
+    protected double organizationalMeasure(Graph<V,E> g, V v) {
+        return 1.0;
+    }
+    
+   
+    /**
+     * Returns the proportion of <code>v1</code>'s network time and energy invested
+     * in the relationship with <code>v2</code>.  Formally:
+     * <pre>
+     * normalizedMutualEdgeWeight(a,b) = mutual_weight(a,b) / (sum_c mutual_weight(a,c))
+     * </pre>
+     * Returns 0 if either numerator or denominator = 0, or if <code>v1 == v2</code>.
+     * @see #mutualWeight(Object, Object)
+     */
+    protected double normalizedMutualEdgeWeight(V v1, V v2)
+    {
+        if (v1 == v2)
+            return 0;
+        
+        double numerator = mutualWeight(v1, v2);
+        
+        if (numerator == 0)
+            return 0;
+        
+        double denominator = 0;
+        for (V v : g.getNeighbors(v1)) {
+            denominator += mutualWeight(v1, v);
+        }
+        if (denominator == 0)
+            return 0;
+        
+        return numerator / denominator;
+    }
+    
+    /**
+     * Returns the weight of the edge from <code>v1</code> to <code>v2</code>
+     * plus the weight of the edge from <code>v2</code> to <code>v1</code>;
+     * if either edge does not exist, it is treated as an edge with weight 0. 
+     * Undirected edges are treated as two antiparallel directed edges (that
+     * is, if there is one undirected edge with weight <i>w</i> connecting 
+     * <code>v1</code> to <code>v2</code>, the value returned is 2<i>w</i>).
+     * Ignores parallel edges; if there are any such, one is chosen at random.
+     * Throws <code>NullPointerException</code> if either edge is 
+     * present but not assigned a weight by the constructor-specified
+     * <code>NumberEdgeValue</code>.
+     */
+    protected double mutualWeight(V v1, V v2)
+    {
+        E e12 = g.findEdge(v1,v2);
+        E e21 = g.findEdge(v2,v1);
+        double w12 = (e12 != null ? edge_weight.transform(e12).doubleValue() : 0);
+        double w21 = (e21 != null ? edge_weight.transform(e21).doubleValue() : 0);
+        
+        return w12 + w21;
+    }
+    
+    /**
+     * The marginal strength of v1's relation with contact vertex2.
+     * Formally:
+     * <pre>
+     * normalized_mutual_weight = mutual_weight(a,b) / (max_c mutual_weight(a,c))
+     * </pre>
+     * Returns 0 if either numerator or denominator is 0, or if <code>v1 == v2</code>.
+     * @see #mutualWeight(Object, Object)
+     */
+    protected double maxScaledMutualEdgeWeight(V v1, V v2)
+    {
+        if (v1 == v2)
+            return 0;
+
+        double numerator = mutualWeight(v1, v2);
+
+        if (numerator == 0)
+            return 0;
+        
+        double denominator = 0;
+        for (V w : g.getNeighbors(v1)) {
+
+            if (v2 != w)
+                denominator = Math.max(numerator, mutualWeight(v1, w));
+        }
+        
+        if (denominator == 0)
+            return 0;
+        
+        return numerator / denominator;
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/metrics/TriadicCensus.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/metrics/TriadicCensus.java
new file mode 100644 (file)
index 0000000..634eb3b
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.metrics;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.collections15.CollectionUtils;
+
+import edu.uci.ics.jung.graph.DirectedGraph;
+import edu.uci.ics.jung.graph.Graph;
+
+
+/**
+ * TriadicCensus is a standard social network tool that counts, for each of the 
+ * different possible configurations of three vertices, the number of times
+ * that that configuration occurs in the given graph.
+ * This may then be compared to the set of expected counts for this particular
+ * graph or to an expected sample. This is often used in p* modeling.
+ * <p>
+ * To use this class, 
+ * <pre>
+ * long[] triad_counts = TriadicCensus(dg);
+ * </pre>
+ * where <code>dg</code> is a <code>DirectedGraph</code>.
+ * ith element of the array (for i in [1,16]) is the number of 
+ * occurrences of the corresponding triad type.
+ * (The 0th element is not meaningful; this array is effectively 1-based.)
+ * To get the name of the ith triad (e.g. "003"), 
+ * look at the global constant array c.TRIAD_NAMES[i]
+ * <p>
+ * Triads are named as 
+ * (number of pairs that are mutually tied)
+ * (number of pairs that are one-way tied)
+ * (number of non-tied pairs)
+ * in the triple. Since there are be only three pairs, there is a finite
+ * set of these possible triads.
+ * <p>
+ * In fact, there are exactly 16, conventionally sorted by the number of 
+ * realized edges in the triad:
+ * <table>
+ * <tr><th>Number</th> <th>Configuration</th> <th>Notes</th></tr>
+ * <tr><td>1</td><td>003</td><td>The empty triad</td></tr>
+ * <tr><td>2</td><td>012</td><td></td></tr>
+ * <tr><td>3</td><td>102</td><td></td></tr>
+ * <tr><td>4</td><td>021D</td><td>"Down": the directed edges point away</td></tr>
+ * <tr><td>5</td><td>021U</td><td>"Up": the directed edges meet</td></tr>
+ * <tr><td>6</td><td>021C</td><td>"Circle": one in, one out</td></tr>
+ * <tr><td>7</td><td>111D</td><td>"Down": 021D but one edge is mutual</td></tr>
+ * <tr><td>8</td><td>111U</td><td>"Up": 021U but one edge is mutual</td></tr>
+ * <tr><td>9</td><td>030T</td><td>"Transitive": two point to the same vertex</td></tr>
+ * <tr><td>10</td><td>030C</td><td>"Circle": A->B->C->A</td></tr>
+ * <tr><td>11</td><td>201</td><td></td></tr>
+ * <tr><td>12</td><td>120D</td><td>"Down": 021D but the third edge is mutual</td></tr>
+ * <tr><td>13</td><td>120U</td><td>"Up": 021U but the third edge is mutual</td></tr>
+ * <tr><td>14</td><td>120C</td><td>"Circle": 021C but the third edge is mutual</td></tr>
+ * <tr><td>15</td><td>210</td><td></td></tr>
+ * <tr><td>16</td><td>300</td><td>The complete</td></tr>
+ * </table>
+ * <p>
+ * This implementation takes O( m ), m is the number of edges in the graph. 
+ * <br>
+ * It is based on 
+ * <a href="http://vlado.fmf.uni-lj.si/pub/networks/doc/triads/triads.pdf">
+ * A subquadratic triad census algorithm for large sparse networks 
+ * with small maximum degree</a>
+ * Vladimir Batagelj and Andrej Mrvar, University of Ljubljana
+ * Published in Social Networks.
+ * @author Danyel Fisher
+ * @author Tom Nelson - converted to jung2
+ *
+ */
+public class TriadicCensus {
+
+       // NOTE THAT THIS RETURNS STANDARD 1-16 COUNT!
+
+       // and their types
+       public static final String[] TRIAD_NAMES = { "N/A", "003", "012", "102", "021D",
+                       "021U", "021C", "111D", "111U", "030T", "030C", "201", "120D",
+                       "120U", "120C", "210", "300" };
+
+       public static final int MAX_TRIADS = TRIAD_NAMES.length;
+
+       /**
+     * Returns an array whose ith element (for i in [1,16]) is the number of 
+     * occurrences of the corresponding triad type in <code>g</code>.
+     * (The 0th element is not meaningful; this array is effectively 1-based.)
+        * 
+        * @param g
+        */
+    public static <V,E> long[] getCounts(DirectedGraph<V,E> g) {
+        long[] count = new long[MAX_TRIADS];
+
+        List<V> id = new ArrayList<V>(g.getVertices());
+
+               // apply algorithm to each edge, one at at time
+               for (int i_v = 0; i_v < g.getVertexCount(); i_v++) {
+                       V v = id.get(i_v);
+                       for(V u : g.getNeighbors(v)) {
+                               int triType = -1;
+                               if (id.indexOf(u) <= i_v)
+                                       continue;
+                               Set<V> neighbors = new HashSet<V>(CollectionUtils.union(g.getNeighbors(u), g.getNeighbors(v)));
+                               neighbors.remove(u);
+                               neighbors.remove(v);
+                               if (g.isSuccessor(v,u) && g.isSuccessor(u,v)) {
+                                       triType = 3;
+                               } else {
+                                       triType = 2;
+                               }
+                               count[triType] += g.getVertexCount() - neighbors.size() - 2;
+                               for (V w : neighbors) {
+                                       if (shouldCount(g, id, u, v, w)) {
+                                               count [ triType ( triCode(g, u, v, w) ) ] ++;
+                                       }
+                               }
+                       }
+               }
+               int sum = 0;
+               for (int i = 2; i <= 16; i++) {
+                       sum += count[i];
+               }
+               int n = g.getVertexCount();
+               count[1] = n * (n-1) * (n-2) / 6 - sum;
+               return count;           
+       }
+
+       /**
+        * This is the core of the technique in the paper. Returns an int from 0 to
+        * 65 based on: WU -> 32 UW -> 16 WV -> 8 VW -> 4 UV -> 2 VU -> 1
+        * 
+        */
+       public static <V,E> int triCode(Graph<V,E> g, V u, V v, V w) {
+               int i = 0;
+               i += link(g, v, u ) ? 1 : 0;
+               i += link(g, u, v ) ? 2 : 0;
+               i += link(g, v, w ) ? 4 : 0;
+               i += link(g, w, v ) ? 8 : 0;
+               i += link(g, u, w ) ? 16 : 0;
+               i += link(g, w, u ) ? 32 : 0;
+               return i;
+       }
+
+       protected static <V,E> boolean link(Graph<V,E> g, V a, V b) {
+               return g.isPredecessor(b, a);
+       }
+       
+       
+       /**
+        * Simply returns the triCode. 
+        * @param triCode
+        * @return the string code associated with the numeric type
+        */
+       public static int triType( int triCode ) {
+               return codeToType[ triCode ];
+       }
+
+       /**
+        * For debugging purposes, this is copied straight out of the paper which
+        * means that they refer to triad types 1-16.
+        */
+       protected static final int[] codeToType = { 1, 2, 2, 3, 2, 4, 6, 8, 2, 6, 5, 7, 3, 8,
+                       7, 11, 2, 6, 4, 8, 5, 9, 9, 13, 6, 10, 9, 14, 7, 14, 12, 15, 2, 5,
+                       6, 7, 6, 9, 10, 14, 4, 9, 9, 12, 8, 13, 14, 15, 3, 7, 8, 11, 7, 12,
+                       14, 15, 8, 14, 13, 15, 11, 15, 15, 16 };
+
+       /**
+        * Make sure we have a canonical ordering: Returns true if u < w, or v < w <
+        * u and v doesn't link to w
+        * 
+        * @param id
+        * @param u
+        * @param v
+        * @param w
+        * @return true if u < w, or if v < w < u and v doesn't link to w; false otherwise
+        */
+       protected static <V,E> boolean shouldCount(Graph<V,E> g, List<V> id, V u, V v, V w) {
+               int i_u = id.indexOf(u);
+               int i_w = id.indexOf(w);
+               if (i_u < i_w)
+                       return true;
+               int i_v = id.indexOf(v);
+               if ((i_v < i_w) && (i_w < i_u) && (!g.isNeighbor(w,v)))
+                       return true;
+               return false;
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/metrics/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/metrics/package.html
new file mode 100644 (file)
index 0000000..ce5144b
--- /dev/null
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+-->
+</head>
+<body>
+
+Specialized measures for graph properties.  These currently include:
+
+<ul>
+<li/><code>StructuralHoles</code>: calculates some of Burt's 'structural holes' 
+measures (e.g. efficiency, hierarchy, constraint). 
+<li/><code>TriadicCensus</code>: returns counts for each triad type found in a 
+graph.
+</ul>
+
+</body>
+</html>
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/package.html
new file mode 100644 (file)
index 0000000..f9d2e25
--- /dev/null
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. 
+ Permission to use, copy, modify, and distribute this software and its documentation 
+ for educational, research and non-profit purposes, without fee, and without a written 
+ agreement is hereby granted, provided that the above copyright notice, this paragraph 
+ and the following two paragraphs appear in all copies. This software program and 
+ documentation are copyrighted by The Regents of the University of California 
+ ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING 
+SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA 
+DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR 
+ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH 
+PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, 
+INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, 
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE 
+UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
+PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, 
+AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, 
+SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+-->
+</head>
+<body>
+
+<p>Algorithms for graphs and networks.</p>
+
+<p>These algorithms are divided into categories as follows:
+<ul>
+<li/><b>blockmodel</b>: dividing graph elements (typically vertices) into 
+equivalence classes, 
+generally by topological properties (e.g. structural equivalence)
+<li/><b>cluster</b>: identifying coherent (not necessarily disjoint) groups of elements
+(e.g. weakly connected components, edge betweenness clustering)
+<li/><b>filters</b>: removing parts of a graph according to specified criteria
+<li/><b>flows</b>: calculating properties relating to network flows 
+(e.g. max flow/min cut)
+<li/><b>generators</b>: creating graphs with certain properties
+<li/><b>importance (<i>deprecated</i>)</b>: assigning values to vertices/edges 
+based on topological properties
+<li/><b>layout</b>: arrangement of graph elements, generally for visualization
+<li/><b>metrics</b>: calculating structural properties (triad census, structural 
+holes)
+<li/><b>scoring</b>: assigning values (denoting significance, influence, 
+centrality, etc.) to vertices/edges based on topological properties,
+e.g. PageRank, HITS, betweenness centrality (replaces "importance", above)
+<li/><b>shortestpath</b>: calculation of shortest paths between vertices
+<li/><b>util</b>: low-level utility classes used in a variety of algorithms
+</ul>
+
+</body>
+</html>
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/AbstractIterativeScorer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/AbstractIterativeScorer.java
new file mode 100644 (file)
index 0000000..70d677b
--- /dev/null
@@ -0,0 +1,368 @@
+/*
+ * Created on Jul 6, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.scoring.util.DelegateToEdgeTransformer;
+import edu.uci.ics.jung.algorithms.scoring.util.VEPair;
+import edu.uci.ics.jung.algorithms.util.IterativeContext;
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * An abstract class for algorithms that assign scores to vertices based on iterative methods.
+ * Generally, any (concrete) subclass will function by creating an instance, and then either calling
+ * <code>evaluate</code> (if the user wants to iterate until the algorithms is 'done') or 
+ * repeatedly call <code>step</code> (if the user wants to observe the values at each step).
+ */
+public abstract class AbstractIterativeScorer<V,E,T> implements IterativeContext, VertexScorer<V,T>
+{
+    /**
+     * Maximum number of iterations to use before terminating.  Defaults to 100.
+     */
+    protected int max_iterations;
+    
+    /**
+     * Minimum change from one step to the next; if all changes are <= tolerance, 
+     * no further updates will occur.
+     * Defaults to 0.001.
+     */
+    protected double tolerance;
+    
+    /**
+     * The graph on which the calculations are to be made.
+     */
+    protected Hypergraph<V,E> graph;
+    
+    /**
+     * The total number of iterations used so far.
+     */
+    protected int total_iterations;
+    
+    /**
+     * The edge weights used by this algorithm.
+     */
+    protected Transformer<VEPair<V,E>, ? extends Number> edge_weights;
+    
+    /**
+     * Indicates whether the output and current values are in a 'swapped' state.
+     * Intended for internal use only.
+     */
+    protected boolean output_reversed;
+    
+    /**
+     * The map in which the output values are stored.
+     */
+    private Map<V, T> output;
+    
+    /**
+     * The map in which the current values are stored.
+     */
+    private Map<V, T> current_values;
+    
+    /**
+     * A flag representing whether this instance tolerates disconnected graphs.
+     * Instances that do not accept disconnected graphs may have unexpected behavior
+     * on disconnected graphs; they are not guaranteed to do an explicit check.
+     * Defaults to true.
+     */
+    private boolean accept_disconnected_graph;
+
+
+    protected boolean hyperedges_are_self_loops = false;
+
+    /**
+     * Sets the output value for this vertex.
+     * @param v the vertex whose output value is to be set
+     * @param value the value to set
+     */
+    protected void setOutputValue(V v, T value)
+    {
+        output.put(v, value);
+    }
+    
+    /**
+     * Gets the output value for this vertex.
+     * @param v the vertex whose output value is to be retrieved
+     * @return the output value for this vertex
+     */
+    protected T getOutputValue(V v)
+    {
+        return output.get(v);
+    }
+    
+    /**
+     * Gets the current value for this vertex
+     * @param v the vertex whose current value is to be retrieved
+     * @return the current value for this vertex
+     */
+    protected T getCurrentValue(V v)
+    {
+        return current_values.get(v);
+    }
+    
+    /**
+     * Sets the current value for this vertex.
+     * @param v the vertex whose current value is to be set
+     * @param value the current value to set
+     */
+    protected void setCurrentValue(V v, T value)
+    {
+        current_values.put(v, value);
+    }
+    
+    /**
+     * The largest change seen so far among all vertex scores.
+     */
+    protected double max_delta;
+    
+    /**
+     * Creates an instance for the specified graph and edge weights.
+     * @param g the graph for which the instance is to be created
+     * @param edge_weights the edge weights for this instance
+     */
+    public AbstractIterativeScorer(Hypergraph<V,E> g, Transformer<E, ? extends Number> edge_weights)
+    {
+        this.graph = g;
+        this.max_iterations = 100;
+        this.tolerance = 0.001;
+        this.accept_disconnected_graph = true;
+        setEdgeWeights(edge_weights);
+    }
+    
+    /**
+     * Creates an instance for the specified graph <code>g</code>.
+     * NOTE: This constructor does not set the internal 
+     * <code>edge_weights</code> variable.  If this variable is used by 
+     * the subclass which invoked this constructor, it must be initialized
+     * by that subclass.
+     * @param g the graph for which the instance is to be created
+     */
+    public AbstractIterativeScorer(Hypergraph<V,E> g)
+    {
+       this.graph = g;
+        this.max_iterations = 100;
+        this.tolerance = 0.001;
+        this.accept_disconnected_graph = true;
+    }
+    
+    /**
+     * Initializes the internal state for this instance.
+     */
+    protected void initialize()
+    {
+        this.total_iterations = 0;
+        this.max_delta = Double.MIN_VALUE;
+        this.output_reversed = true;
+        this.current_values = new HashMap<V, T>();
+        this.output = new HashMap<V, T>();
+    }
+    
+    /**
+     * Steps through this scoring algorithm until a termination condition is reached.
+     */
+    public void evaluate()
+    {
+        do
+            step();
+        while (!done());
+    }
+    
+    /**
+     * Returns true if the total number of iterations is greater than or equal to 
+     * <code>max_iterations</code>
+     * or if the maximum value change observed is less than <code>tolerance</code>.
+     */
+    public boolean done()
+    {
+        return total_iterations >= max_iterations || max_delta < tolerance;
+    }
+
+    /**
+     * Performs one step of this algorithm; updates the state (value) for each vertex.
+     */
+    public void step()
+    {
+        swapOutputForCurrent();
+        
+        for (V v : graph.getVertices())
+        {
+            double diff = update(v);
+            updateMaxDelta(v, diff);
+        }
+        total_iterations++;
+        afterStep();
+    }
+
+    /**
+     * 
+     */
+    protected void swapOutputForCurrent()
+    {
+        Map<V, T> tmp = output;
+        output = current_values;
+        current_values = tmp;
+        output_reversed = !output_reversed;
+    }
+
+    /**
+     * Updates the value for <code>v</code>.
+     * This is the key 
+     * @param v the vertex whose value is to be updated
+     * @return
+     */
+    protected abstract double update(V v);
+
+    protected void updateMaxDelta(V v, double diff)
+    {
+        max_delta = Math.max(max_delta, diff);
+    }
+    
+    protected void afterStep() {}
+    
+    public T getVertexScore(V v)
+    {
+        if (!graph.containsVertex(v))
+            throw new IllegalArgumentException("Vertex " + v + " not an element of this graph");
+        
+        return output.get(v);
+    }
+
+    /**
+     * Returns the maximum number of iterations that this instance will use.
+     * @return the maximum number of iterations that <code>evaluate</code> will use
+     * prior to terminating
+     */
+    public int getMaxIterations()
+    {
+        return max_iterations;
+    }
+
+    /**
+     * Returns the number of iterations that this instance has used so far.
+     * @return the number of iterations that this instance has used so far
+     */
+    public int getIterations()
+    {
+       return total_iterations;
+    }
+    
+    /**
+     * Sets the maximum number of times that <code>evaluate</code> will call <code>step</code>.
+     * @param max_iterations the maximum 
+     */
+    public void setMaxIterations(int max_iterations)
+    {
+        this.max_iterations = max_iterations;
+    }
+
+    /**
+     * Gets the size of the largest change (difference between the current and previous values)
+     * for any vertex that can be tolerated.  Once all changes are less than this value, 
+     * <code>evaluate</code> will terminate.
+     * @return the size of the largest change that evaluate() will permit
+     */
+    public double getTolerance()
+    {
+        return tolerance;
+    }
+
+    /**
+     * Sets the size of the largest change (difference between the current and previous values)
+     * for any vertex that can be tolerated.
+     * @param tolerance the size of the largest change that evaluate() will permit
+     */
+    public void setTolerance(double tolerance)
+    {
+        this.tolerance = tolerance;
+    }
+    
+    /**
+     * Returns the Transformer that this instance uses to associate edge weights with each edge.
+     * @return the Transformer that associates an edge weight with each edge
+     */
+    public Transformer<VEPair<V,E>, ? extends Number> getEdgeWeights()
+    {
+        return edge_weights;
+    }
+
+    /**
+     * Sets the Transformer that this instance uses to associate edge weights with each edge
+     * @param edge_weights the Transformer to use to associate an edge weight with each edge
+     * @see edu.uci.ics.jung.algorithms.scoring.util.UniformDegreeWeight
+     */
+    public void setEdgeWeights(Transformer<E, ? extends Number> edge_weights)
+    {
+        this.edge_weights = new DelegateToEdgeTransformer<V,E>(edge_weights);
+    }
+    
+    /**
+     * Gets the edge weight for <code>e</code> in the context of its (incident) vertex <code>v</code>.
+     * @param v the vertex incident to e as a context in which the edge weight is to be calculated
+     * @param e the edge whose weight is to be returned
+     * @return the edge weight for <code>e</code> in the context of its (incident) vertex <code>v</code>
+     */
+    protected Number getEdgeWeight(V v, E e)
+    {
+        return edge_weights.transform(new VEPair<V,E>(v,e));
+    }
+    
+    /**
+     * Collects the 'potential' from v (its current value) if it has no outgoing edges; this
+     * can then be redistributed among the other vertices as a means of normalization.
+     * @param v
+     */
+    protected void collectDisappearingPotential(V v) {}
+
+    /**
+     * Specifies whether this instance should accept vertices with no outgoing edges.
+     * @param accept true if this instance should accept vertices with no outgoing edges, false otherwise
+     */
+    public void acceptDisconnectedGraph(boolean accept)
+    {
+        this.accept_disconnected_graph = accept;
+    }
+    
+    /**
+     * Returns true if this instance accepts vertices with no outgoing edges, and false otherwise.
+     * @return true if this instance accepts vertices with no outgoing edges, otherwise false
+     */
+    public boolean isDisconnectedGraphOK()
+    {
+        return this.accept_disconnected_graph;
+    }
+    
+    /**
+     * Specifies whether hyperedges are to be treated as self-loops.  If they
+     * are, then potential will flow along a hyperedge a vertex to itself, 
+     * just as it does to all other vertices incident to that hyperedge. 
+     * @param arg if {@code true}, hyperedges are treated as self-loops
+     */
+    public void setHyperedgesAreSelfLoops(boolean arg) 
+    {
+       this.hyperedges_are_self_loops = arg;
+    }
+
+    /**
+     * Returns the effective number of vertices incident to this edge.  If
+     * the graph is a binary relation or if hyperedges are treated as self-loops,
+     * the value returned is {@code graph.getIncidentCount(e)}; otherwise it is
+     * {@code graph.getIncidentCount(e) - 1}.
+     */
+    protected int getAdjustedIncidentCount(E e) 
+    {
+        return graph.getIncidentCount(e) - (hyperedges_are_self_loops ? 0 : 1);
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/AbstractIterativeScorerWithPriors.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/AbstractIterativeScorerWithPriors.java
new file mode 100644 (file)
index 0000000..6883e26
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Created on Jul 14, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * An abstract class for iterative random-walk-based vertex scoring algorithms 
+ * that have a 
+ * fixed probability, for each vertex, of 'jumping' to that vertex at each
+ * step in the algorithm (rather than following a link out of that vertex).
+ *
+ * @param <V> the vertex type
+ * @param <E> the edge type
+ * @param <S> the score type
+ */
+public abstract class AbstractIterativeScorerWithPriors<V,E,S> extends
+        AbstractIterativeScorer<V,E,S> implements VertexScorer<V,S>
+{
+    /**
+     * The prior probability of each vertex being visited on a given 
+     * 'jump' (non-link-following) step.
+     */
+    protected Transformer<V,? extends S> vertex_priors;
+
+    /**
+     * The probability of making a 'jump' at each step.
+     */
+    protected double alpha;
+
+    /**
+     * Creates an instance for the specified graph, edge weights, vertex
+     * priors, and jump probability.
+     * @param g the graph whose vertices are to be assigned scores
+     * @param edge_weights the edge weights to use in the score assignment
+     * @param vertex_priors the prior probabilities of each vertex being 'jumped' to
+     * @param alpha the probability of making a 'jump' at each step
+     */
+    public AbstractIterativeScorerWithPriors(Hypergraph<V,E> g,
+            Transformer<E,? extends Number> edge_weights, 
+            Transformer<V,? extends S> vertex_priors, double alpha)
+    {
+        super(g, edge_weights);
+        this.vertex_priors = vertex_priors;
+        this.alpha = alpha;
+        initialize();
+    }
+
+    /**
+     * Creates an instance for the specified graph, vertex priors, and jump
+     * probability, with edge weights specified by the subclass.
+     * @param g the graph whose vertices are to be assigned scores
+     * @param vertex_priors the prior probabilities of each vertex being 'jumped' to
+     * @param alpha the probability of making a 'jump' at each step
+     */
+    public AbstractIterativeScorerWithPriors(Hypergraph<V,E> g, 
+               Transformer<V,? extends S> vertex_priors, double alpha)
+    {
+        super(g);
+        this.vertex_priors = vertex_priors;
+        this.alpha = alpha;
+        initialize();
+    }
+
+    /**
+     * Initializes the state of this instance.
+     */
+    @Override
+    public void initialize()
+    {
+        super.initialize();
+        // initialize output values to priors
+        // (output and current are swapped before each step(), so current will
+        // have priors when update()s start happening)
+        for (V v : graph.getVertices())
+            setOutputValue(v, getVertexPrior(v));
+    }
+    
+    /**
+     * Returns the prior probability for <code>v</code>.
+     * @param v the vertex whose prior probability is being queried
+     * @return the prior probability for <code>v</code>
+     */
+    protected S getVertexPrior(V v)
+    {
+        return vertex_priors.transform(v);
+    }
+
+    /**
+     * Returns a Transformer which maps each vertex to its prior probability.
+     * @return a Transformer which maps each vertex to its prior probability
+     */
+    public Transformer<V, ? extends S> getVertexPriors()
+    {
+        return vertex_priors;
+    }
+
+    /**
+     * Returns the probability of making a 'jump' (non-link-following step).
+     * @return the probability of making a 'jump' (non-link-following step)
+     */
+    public double getAlpha()
+    {
+        return alpha;
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/BarycenterScorer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/BarycenterScorer.java
new file mode 100644 (file)
index 0000000..1c9c178
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Created on Jul 12, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.shortestpath.Distance;
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * Assigns scores to each vertex according to the sum of its distances to all other vertices.
+ */
+public class BarycenterScorer<V,E> extends DistanceCentralityScorer<V, E>
+{
+    /**
+     * Creates an instance with the specified graph and distance metric.
+     * @param graph the input graph
+     * @param distance the distance metric to use
+     */
+    public BarycenterScorer(Hypergraph<V,E> graph, Distance<V> distance)
+    {
+        super(graph, distance, false);
+    }
+    
+    /**
+     * Creates an instance with the specified graph and edge weights.
+     * Will generate a <code>Distance</code> metric internally based on the edge weights. 
+     * @param graph the input graph
+     * @param edge_weights the edge weights to use to calculate vertex/vertex distances
+     */
+    public BarycenterScorer(Hypergraph<V,E> graph, Transformer<E, ? extends Number> edge_weights)
+    {
+        super(graph, edge_weights, false);
+    }
+
+    /**
+     * Creates an instance with the specified graph.
+     * Will generate a <code>Distance</code> metric internally assuming that the
+     * graph is unweighted. 
+     * @param graph the input graph
+     */
+    public BarycenterScorer(Hypergraph<V,E> graph)
+    {
+        super(graph, false);
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/BetweennessCentrality.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/BetweennessCentrality.java
new file mode 100644 (file)
index 0000000..5cfeb16
--- /dev/null
@@ -0,0 +1,351 @@
+/**
+ * Copyright (c) 2008, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ * Created on Sep 16, 2008
+ * 
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Stack;
+
+import org.apache.commons.collections15.Transformer;
+import org.apache.commons.collections15.functors.ConstantTransformer;
+
+import edu.uci.ics.jung.algorithms.util.MapBinaryHeap;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.UndirectedGraph;
+
+/**
+ * Computes betweenness centrality for each vertex and edge in the graph.
+ * 
+ * @see "Ulrik Brandes: A Faster Algorithm for Betweenness Centrality. Journal of Mathematical Sociology 25(2):163-177, 2001."
+ */
+public class BetweennessCentrality<V, E> 
+       implements VertexScorer<V, Double>, EdgeScorer<E, Double> 
+{
+       protected Graph<V,E> graph;
+       protected Map<V, Double> vertex_scores;
+       protected Map<E, Double> edge_scores;
+       protected Map<V, BetweennessData> vertex_data;
+               
+       /**
+        * Calculates betweenness scores based on the all-pairs unweighted shortest paths
+        * in the graph.
+        * @param graph the graph for which the scores are to be calculated
+        */
+       @SuppressWarnings("unchecked")
+       public BetweennessCentrality(Graph<V, E> graph) 
+       {
+               initialize(graph);
+               computeBetweenness(new LinkedList<V>(), new ConstantTransformer(1));
+       }
+
+       /**
+        * Calculates betweenness scores based on the all-pairs weighted shortest paths in the
+        * graph.
+        * 
+        * <p>NOTE: This version of the algorithm may not work correctly on all graphs; we're still
+        * working out the bugs.  Use at your own risk.
+        * @param graph the graph for which the scores are to be calculated
+        * @param edge_weights the edge weights to be used in the path length calculations
+        */
+       public BetweennessCentrality(Graph<V, E> graph, 
+                       Transformer<E, ? extends Number> edge_weights) 
+       {
+               // reject negative-weight edges up front
+               for (E e : graph.getEdges())
+               {
+                       double e_weight = edge_weights.transform(e).doubleValue();
+               if (e_weight < 0)
+                       throw new IllegalArgumentException(String.format(
+                                       "Weight for edge '%s' is < 0: %d", e, e_weight)); 
+               }
+                       
+               initialize(graph);
+               computeBetweenness(new MapBinaryHeap<V>(new BetweennessComparator()), 
+                       edge_weights);
+       }
+
+       protected void initialize(Graph<V,E> graph)
+       {
+               this.graph = graph;
+               this.vertex_scores = new HashMap<V, Double>();
+               this.edge_scores = new HashMap<E, Double>();
+               this.vertex_data = new HashMap<V, BetweennessData>();
+               
+               for (V v : graph.getVertices())
+                       this.vertex_scores.put(v, 0.0);
+               
+               for (E e : graph.getEdges())
+                       this.edge_scores.put(e, 0.0);
+       }
+       
+       protected void computeBetweenness(Queue<V> queue, 
+                       Transformer<E, ? extends Number> edge_weights)
+       {
+               for (V v : graph.getVertices())
+               {
+                       // initialize the betweenness data for this new vertex
+                       for (V s : graph.getVertices()) 
+                               this.vertex_data.put(s, new BetweennessData());
+
+//                     if (v.equals(new Integer(0)))
+//                             System.out.println("pause");
+                       
+            vertex_data.get(v).numSPs = 1;
+            vertex_data.get(v).distance = 0;
+
+            Stack<V> stack = new Stack<V>();
+//            Buffer<V> queue = new UnboundedFifoBuffer<V>();
+//            queue.add(v);
+            queue.offer(v);
+
+            while (!queue.isEmpty()) 
+            {
+//                V w = queue.remove();
+               V w = queue.poll();
+                stack.push(w);
+               BetweennessData w_data = vertex_data.get(w);
+                
+                for (E e : graph.getOutEdges(w))
+                {
+                       // TODO (jrtom): change this to getOtherVertices(w, e)
+                       V x = graph.getOpposite(w, e);
+                       if (x.equals(w))
+                               continue;
+                       double wx_weight = edge_weights.transform(e).doubleValue();
+                       
+                       
+//                for(V x : graph.getSuccessors(w)) 
+//                {
+//                     if (x.equals(w))
+//                             continue;
+                       
+                       // FIXME: the other problem is that I need to 
+                       // keep putting the neighbors of things we've just 
+                       // discovered in the queue, if they're undiscovered or
+                       // at greater distance.
+                       
+                       // FIXME: this is the problem, right here, I think: 
+                       // need to update position in queue if distance changes
+                       // (which can only happen with weighted edges).
+                       // for each outgoing edge e from w, get other end x
+                       // if x not already visited (dist x < 0)
+                       //   set x's distance to w's dist + edge weight
+                       //   add x to queue; pri in queue is x's dist
+                       // if w's dist + edge weight < x's dist 
+                       //   update x's dist
+                       //   update x in queue (MapBinaryHeap)
+                       //   clear x's incoming edge list
+                       // if w's dist + edge weight = x's dist
+                       //   add e to x's incoming edge list
+                       
+                       BetweennessData x_data = vertex_data.get(x);
+                       double x_potential_dist = w_data.distance + wx_weight;
+                       
+                    if (x_data.distance < 0) 
+                    {
+//                        queue.add(x);
+//                        vertex_data.get(x).distance = vertex_data.get(w).distance + 1;
+                       x_data.distance = x_potential_dist;
+                       queue.offer(x);
+                    }
+                    
+                    // note:
+                    // (1) this can only happen with weighted edges
+                    // (2) x's SP count and incoming edges are updated below 
+                    if (x_data.distance > x_potential_dist)
+                    {
+                       x_data.distance = x_potential_dist;
+                       // invalidate previously identified incoming edges
+                       // (we have a new shortest path distance to x)
+                       x_data.incomingEdges.clear(); 
+                        // update x's position in queue
+                       ((MapBinaryHeap<V>)queue).update(x);
+                    }
+//                  if (vertex_data.get(x).distance == vertex_data.get(w).distance + 1) 
+                    // 
+//                    if (x_data.distance == x_potential_dist) 
+//                    {
+//                        x_data.numSPs += w_data.numSPs;
+////                        vertex_data.get(x).predecessors.add(w);
+//                        x_data.incomingEdges.add(e);
+//                    }
+                }
+                for (E e: graph.getOutEdges(w))
+                {
+                       V x = graph.getOpposite(w, e);
+                       if (x.equals(w))
+                               continue;
+                       double e_weight = edge_weights.transform(e).doubleValue();
+                       BetweennessData x_data = vertex_data.get(x);
+                       double x_potential_dist = w_data.distance + e_weight;
+                    if (x_data.distance == x_potential_dist) 
+                    {
+                        x_data.numSPs += w_data.numSPs;
+//                        vertex_data.get(x).predecessors.add(w);
+                        x_data.incomingEdges.add(e);
+                    }
+                }
+            }
+               while (!stack.isEmpty()) 
+               {
+                   V x = stack.pop();
+
+//                 for (V w : vertex_data.get(x).predecessors) 
+                   for (E e : vertex_data.get(x).incomingEdges)
+                   {
+                       V w = graph.getOpposite(x, e);
+                       double partialDependency = 
+                               vertex_data.get(w).numSPs / vertex_data.get(x).numSPs *
+                               (1.0 + vertex_data.get(x).dependency);
+                       vertex_data.get(w).dependency +=  partialDependency;
+//                     E w_x = graph.findEdge(w, x);
+//                     double w_x_score = edge_scores.get(w_x).doubleValue();
+//                     w_x_score += partialDependency;
+//                     edge_scores.put(w_x, w_x_score);
+                       double e_score = edge_scores.get(e).doubleValue();
+                       edge_scores.put(e, e_score + partialDependency);
+                   }
+                   if (!x.equals(v)) 
+                   {
+                       double x_score = vertex_scores.get(x).doubleValue();
+                       x_score += vertex_data.get(x).dependency;
+                       vertex_scores.put(x, x_score);
+                   }
+               }
+        }
+
+        if(graph instanceof UndirectedGraph) 
+        {
+               for (V v : graph.getVertices()) { 
+                       double v_score = vertex_scores.get(v).doubleValue();
+                       v_score /= 2.0;
+                       vertex_scores.put(v, v_score);
+               }
+               for (E e : graph.getEdges()) {
+                       double e_score = edge_scores.get(e).doubleValue();
+                       e_score /= 2.0;
+                       edge_scores.put(e, e_score);
+               }
+        }
+
+        vertex_data.clear();
+       }
+
+//     protected void computeWeightedBetweenness(Transformer<E, ? extends Number> edge_weights)
+//     {
+//             for (V v : graph.getVertices())
+//             {
+//                     // initialize the betweenness data for this new vertex
+//                     for (V s : graph.getVertices()) 
+//                             this.vertex_data.put(s, new BetweennessData());
+//            vertex_data.get(v).numSPs = 1;
+//            vertex_data.get(v).distance = 0;
+//
+//            Stack<V> stack = new Stack<V>();
+////            Buffer<V> queue = new UnboundedFifoBuffer<V>();
+//            SortedSet<V> pqueue = new TreeSet<V>(new BetweennessComparator());
+////          queue.add(v);
+//            pqueue.add(v);
+//
+////            while (!queue.isEmpty()) 
+//            while (!pqueue.isEmpty()) 
+//            {
+////              V w = queue.remove();
+//             V w = pqueue.first();
+//             pqueue.remove(w);
+//                stack.push(w);
+//
+////                for(V x : graph.getSuccessors(w)) 
+//                for (E e : graph.getOutEdges(w))
+//                {
+//                     // TODO (jrtom): change this to getOtherVertices(w, e)
+//                     V x = graph.getOpposite(w, e);
+//                     if (x.equals(w))
+//                             continue;
+//                     double e_weight = edge_weights.transform(e).doubleValue();
+//                     
+//                    if (vertex_data.get(x).distance < 0) 
+//                    {
+////                        queue.add(x);
+//                     pqueue.add(v);
+////                        vertex_data.get(x).distance = vertex_data.get(w).distance + 1;
+//                        vertex_data.get(x).distance = 
+//                             vertex_data.get(w).distance + e_weight;
+//                    }
+//
+////                    if (vertex_data.get(x).distance == vertex_data.get(w).distance + 1) 
+//                    if (vertex_data.get(x).distance == 
+//                     vertex_data.get(w).distance + e_weight)
+//                    {
+//                        vertex_data.get(x).numSPs += vertex_data.get(w).numSPs;
+//                        vertex_data.get(x).predecessors.add(w);
+//                    }
+//                }
+//            }
+//            updateScores(v, stack);
+//        }
+//
+//        if(graph instanceof UndirectedGraph) 
+//            adjustUndirectedScores();
+//
+//        vertex_data.clear();
+//     }
+       
+       public Double getVertexScore(V v) 
+       {
+               return vertex_scores.get(v);
+       }
+
+       public Double getEdgeScore(E e) 
+       {
+               return edge_scores.get(e);
+       }
+
+    private class BetweennessData 
+    {
+        double distance;
+        double numSPs;
+//        List<V> predecessors;
+        List<E> incomingEdges;
+        double dependency;
+
+        BetweennessData() 
+        {
+            distance = -1;
+            numSPs = 0;
+//            predecessors = new ArrayList<V>();
+            incomingEdges = new ArrayList<E>();
+            dependency = 0;
+        }
+        
+        @Override
+        public String toString()
+        {
+               return "[d:" + distance + ", sp:" + numSPs + 
+                       ", p:" + incomingEdges + ", d:" + dependency + "]\n";
+//                     ", p:" + predecessors + ", d:" + dependency + "]\n";
+        }
+    }
+    
+    private class BetweennessComparator implements Comparator<V>
+    {
+               public int compare(V v1, V v2) 
+               {
+                       return vertex_data.get(v1).distance > vertex_data.get(v2).distance ? 1 : -1;
+               }
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/ClosenessCentrality.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/ClosenessCentrality.java
new file mode 100644 (file)
index 0000000..d64f01e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Created on Jul 12, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.shortestpath.Distance;
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * Assigns scores to each vertex based on the mean distance to each other vertex.
+ * 
+ * @author Joshua O'Madadhain
+ */
+public class ClosenessCentrality<V,E> extends DistanceCentralityScorer<V,E>
+{
+
+    /**
+     * Creates an instance using the specified vertex/vertex distance metric.
+     * @param graph the input
+     * @param distance the vertex/vertex distance metric.
+     */
+    public ClosenessCentrality(Hypergraph<V,E> graph, Distance<V> distance)
+    {
+        super(graph, distance, true);
+    }
+
+    /**
+     * Creates an instance which measures distance using the specified edge weights.
+     * @param graph the input graph
+     * @param edge_weights the edge weights to be used to determine vertex/vertex distances
+     */
+    public ClosenessCentrality(Hypergraph<V,E> graph, Transformer<E, ? extends Number> edge_weights)
+    {
+        super(graph, edge_weights, true);
+    }
+
+    /**
+     * Creates an instance which measures distance on the graph without edge weights.
+     * @param graph
+     */
+    public ClosenessCentrality(Hypergraph<V,E> graph)
+    {
+        super(graph, true);
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/DegreeScorer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/DegreeScorer.java
new file mode 100644 (file)
index 0000000..2ec3148
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Created on Jul 6, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * Assigns a score to each vertex equal to its degree.
+ *
+ * @param <V> the vertex type
+ */
+public class DegreeScorer<V> implements VertexScorer<V,Integer>
+{
+       /**
+        * The graph for which scores are to be generated.
+        */
+    protected Hypergraph<V,?> graph;
+    
+    /**
+     * Creates an instance for the specified graph.
+     * @param graph the input graph
+     */
+    public DegreeScorer(Hypergraph<V,?> graph)
+    {
+        this.graph = graph;
+    }
+    
+    /**
+     * Returns the degree of the vertex.
+     * @return the degree of the vertex
+     */
+    public Integer getVertexScore(V v) 
+    {
+        return graph.degree(v); 
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/DistanceCentralityScorer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/DistanceCentralityScorer.java
new file mode 100644 (file)
index 0000000..16dd862
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * Created on Jul 10, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.shortestpath.DijkstraDistance;
+import edu.uci.ics.jung.algorithms.shortestpath.Distance;
+import edu.uci.ics.jung.algorithms.shortestpath.UnweightedShortestPath;
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * Assigns scores to vertices based on their distances to each other vertex 
+ * in the graph.
+ * 
+ * This class optionally normalizes its results based on the value of its
+ * 'averaging' constructor parameter.  If it is <code>true</code>, 
+ * then the value returned for vertex v is 1 / (_average_ distance from v to all other vertices); 
+ * this is sometimes called <i>closeness centrality</i>.
+ * If it is <code>false</code>, then the value returned is 1 / (_total_ distance from
+ * v to all other vertices); this is sometimes referred to as <i>barycenter centrality</i>.
+ * (If the average/total distance is 0, the value returned is {@code Double.POSITIVE_INFINITY}.)
+ * 
+ * @see BarycenterScorer
+ * @see ClosenessCentrality
+ */
+public class DistanceCentralityScorer<V,E> implements VertexScorer<V, Double>
+{
+    /**
+     * The graph on which the vertex scores are to be calculated.
+     */
+    protected Hypergraph<V, E> graph;
+    
+    /**
+     * The metric to use for specifying the distance between pairs of vertices.
+     */
+    protected Distance<V> distance;
+    
+    /**
+     * The cache for the output results.  Null encodes "not yet calculated",
+     * < 0 encodes "no such distance exists".
+     */
+    protected Map<V, Double> output;
+    
+    /**
+     * Specifies whether the values returned are the sum of the v-distances
+     * or the mean v-distance.
+     */
+    protected boolean averaging;
+    
+    /**
+     * Specifies whether, for a vertex <code>v</code> with missing (null) distances, 
+     * <code>v</code>'s score should ignore the missing values or be set to 'null'.
+     * Defaults to 'true'.
+     */
+    protected boolean ignore_missing;
+
+    /**
+     * Specifies whether the values returned should ignore self-distances 
+     * (distances from <code>v</code> to itself).
+     * Defaults to 'true'.
+     */
+    protected boolean ignore_self_distances;
+    
+    /**
+     * Creates an instance with the specified graph, distance metric, and 
+     * averaging behavior.
+     * 
+     * @param graph     The graph on which the vertex scores are to be calculated.
+     * @param distance  The metric to use for specifying the distance between 
+     * pairs of vertices.
+     * @param averaging Specifies whether the values returned is the sum of all 
+     * v-distances or the mean v-distance.
+     * @param ignore_missing   Specifies whether scores for missing distances 
+     * are to ignore missing distances or be set to null.
+     * @param ignore_self_distances    Specifies whether distances from a vertex
+     * to itself should be included in its score.
+     */
+    public DistanceCentralityScorer(Hypergraph<V,E> graph, Distance<V> distance, 
+               boolean averaging, boolean ignore_missing, 
+               boolean ignore_self_distances)
+    {
+        this.graph = graph;
+        this.distance = distance;
+        this.averaging = averaging;
+        this.ignore_missing = ignore_missing;
+        this.ignore_self_distances = ignore_self_distances;
+        this.output = new HashMap<V, Double>();
+    }
+
+    /**
+     * Equivalent to <code>this(graph, distance, averaging, true, true)</code>.
+     * 
+     * @param graph     The graph on which the vertex scores are to be calculated.
+     * @param distance  The metric to use for specifying the distance between 
+     * pairs of vertices.
+     * @param averaging Specifies whether the values returned is the sum of all 
+     * v-distances or the mean v-distance.
+     */
+    public DistanceCentralityScorer(Hypergraph<V,E> graph, Distance<V> distance, 
+               boolean averaging)
+    {
+       this(graph, distance, averaging, true, true);
+    }
+    
+    /**
+     * Creates an instance with the specified graph and averaging behavior
+     * whose vertex distances are calculated based on the specified edge
+     * weights.  
+     * 
+     * @param graph         The graph on which the vertex scores are to be 
+     * calculated.
+     * @param edge_weights  The edge weights to use for specifying the distance 
+     * between pairs of vertices.
+     * @param averaging     Specifies whether the values returned is the sum of 
+     * all v-distances or the mean v-distance.
+     * @param ignore_missing   Specifies whether scores for missing distances 
+     * are to ignore missing distances or be set to null.
+     * @param ignore_self_distances    Specifies whether distances from a vertex
+     * to itself should be included in its score.
+     */
+    public DistanceCentralityScorer(Hypergraph<V,E> graph, 
+            Transformer<E, ? extends Number> edge_weights, boolean averaging,
+            boolean ignore_missing, boolean ignore_self_distances)
+    {
+        this(graph, new DijkstraDistance<V,E>(graph, edge_weights), averaging,
+               ignore_missing, ignore_self_distances);
+    }
+    
+    /**
+     * Equivalent to <code>this(graph, edge_weights, averaging, true, true)</code>.
+     * @param graph         The graph on which the vertex scores are to be 
+     * calculated.
+     * @param edge_weights  The edge weights to use for specifying the distance 
+     * between pairs of vertices.
+     * @param averaging     Specifies whether the values returned is the sum of 
+     * all v-distances or the mean v-distance.
+     */
+    public DistanceCentralityScorer(Hypergraph<V,E> graph, 
+            Transformer<E, ? extends Number> edge_weights, boolean averaging)
+    {
+        this(graph, new DijkstraDistance<V,E>(graph, edge_weights), averaging,
+               true, true);
+    }
+    
+    /**
+     * Creates an instance with the specified graph and averaging behavior
+     * whose vertex distances are calculated on the unweighted graph.  
+     * 
+     * @param graph         The graph on which the vertex scores are to be 
+     * calculated.
+     * @param averaging     Specifies whether the values returned is the sum of 
+     * all v-distances or the mean v-distance.
+     * @param ignore_missing   Specifies whether scores for missing distances 
+     * are to ignore missing distances or be set to null.
+     * @param ignore_self_distances    Specifies whether distances from a vertex
+     * to itself should be included in its score.
+     */
+    public DistanceCentralityScorer(Hypergraph<V,E> graph, boolean averaging,
+            boolean ignore_missing, boolean ignore_self_distances)
+    {
+        this(graph, new UnweightedShortestPath<V,E>(graph), averaging, 
+               ignore_missing, ignore_self_distances);
+    }
+
+    /**
+     * Equivalent to <code>this(graph, averaging, true, true)</code>.
+     * @param graph         The graph on which the vertex scores are to be 
+     * calculated.
+     * @param averaging     Specifies whether the values returned is the sum of 
+     * all v-distances or the mean v-distance.
+     */
+    public DistanceCentralityScorer(Hypergraph<V,E> graph, boolean averaging)
+    {
+        this(graph, new UnweightedShortestPath<V,E>(graph), averaging, true, true);
+    }
+
+       /**
+        * Calculates the score for the specified vertex.  Returns {@code null} if 
+        * there are missing distances and such are not ignored by this instance.
+        */
+       public Double getVertexScore(V v) 
+       {
+           Double value = output.get(v);
+           if (value != null)
+           {
+               if (value < 0)
+                   return null;
+               return value;
+           }
+           
+           Map<V, Number> v_distances = new HashMap<V, Number>(distance.getDistanceMap(v));
+           if (ignore_self_distances)
+               v_distances.remove(v);
+           
+               // if we don't ignore missing distances and there aren't enough
+               // distances, output null (shortcut)
+               if (!ignore_missing)
+               {
+                       int num_dests = graph.getVertexCount() - 
+                           (ignore_self_distances ? 1 : 0);
+                       if (v_distances.size() != num_dests) 
+                       {
+                               output.put(v, -1.0);
+                               return null;
+                       }
+               }               
+               
+               Double sum = 0.0;
+               for (V w : graph.getVertices())
+               {
+                       if (w.equals(v) && ignore_self_distances)
+                               continue;
+                       Number w_distance = v_distances.get(w);
+                       if (w_distance == null)
+                               if (ignore_missing)
+                                       continue;
+                               else
+                               {
+                                       output.put(v, -1.0);
+                                       return null;
+                               }
+                       else
+                               sum += w_distance.doubleValue();
+               }
+               value = sum;
+               if (averaging)
+                   value /= v_distances.size();
+               
+               double score = value == 0 ? 
+                       Double.POSITIVE_INFINITY : 
+                       1.0 / value;
+           output.put(v, score);
+                  
+               return score;
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/EdgeScorer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/EdgeScorer.java
new file mode 100644 (file)
index 0000000..7e64874
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Created on Jul 6, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+
+/**
+ * An interface for algorithms that assign scores to edges.
+ *
+ * @param <E> the edge type
+ * @param <S> the score type
+ */
+public interface EdgeScorer<E, S>
+{
+    /**
+     * Returns the algorithm's score for this edge.
+     * @return the algorithm's score for this edge
+     */
+    public S getEdgeScore(E e);
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/EigenvectorCentrality.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/EigenvectorCentrality.java
new file mode 100644 (file)
index 0000000..87d7f3a
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Created on Jul 12, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * Calculates eigenvector centrality for each vertex in the graph.
+ * The 'eigenvector centrality' for a vertex is defined as the fraction of
+ * time that a random walk(er) will spend at that vertex over an infinite
+ * time horizon.
+ * Assumes that the graph is strongly connected.
+ */
+public class EigenvectorCentrality<V,E> extends PageRank<V,E>
+{
+    /**
+     * Creates an instance with the specified graph and edge weights.
+     * The outgoing edge weights for each edge must sum to 1.
+     * (See <code>UniformDegreeWeight</code> for one way to handle this for
+     * undirected graphs.)
+     * @param graph the graph for which the centrality is to be calculated
+     * @param edge_weights the edge weights 
+     */
+    public EigenvectorCentrality(Hypergraph<V,E> graph, 
+               Transformer<E, ? extends Number> edge_weights)
+    {
+        super(graph, edge_weights, 0);
+        acceptDisconnectedGraph(false);
+    }
+
+    /**
+     * Creates an instance with the specified graph and default edge weights.
+     * (Default edge weights: <code>UniformDegreeWeight</code>.)
+     * @param graph the graph for which the centrality is to be calculated.
+     */
+    public EigenvectorCentrality(Hypergraph<V,E> graph)
+    {
+        super(graph, 0);
+        acceptDisconnectedGraph(false);
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/HITS.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/HITS.java
new file mode 100644 (file)
index 0000000..b1b4f42
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Created on Jul 15, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+import edu.uci.ics.jung.algorithms.scoring.util.ScoringUtils;
+import edu.uci.ics.jung.graph.Graph;
+
+import org.apache.commons.collections15.Transformer;
+
+/**
+ * Assigns hub and authority scores to each vertex depending on the topology of
+ * the network.  The essential idea is that a vertex is a hub to the extent 
+ * that it links to authoritative vertices, and is an authority to the extent
+ * that it links to 'hub' vertices.
+ * 
+ * <p>The classic HITS algorithm essentially proceeds as follows:
+ * <pre>
+ * assign equal initial hub and authority values to each vertex
+ * repeat
+ *   for each vertex w:
+ *     w.hub = sum over successors x of x.authority
+ *     w.authority = sum over predecessors v of v.hub
+ *   normalize hub and authority scores so that the sum of the squares of each = 1
+ * until scores converge
+ * </pre>
+ * 
+ * HITS is somewhat different from random walk/eigenvector-based algorithms 
+ * such as PageRank in that: 
+ * <ul>
+ * <li/>there are two mutually recursive scores being calculated, rather than 
+ * a single value
+ * <li/>the edge weights are effectively all 1, i.e., they can't be interpreted
+ * as transition probabilities.  This means that the more inlinks and outlinks
+ * that a vertex has, the better, since adding an inlink (or outlink) does
+ * not dilute the influence of the other inlinks (or outlinks) as in 
+ * random walk-based algorithms.
+ * <li/>the scores cannot be interpreted as posterior probabilities (due to the different
+ * normalization)
+ * </ul>
+ * 
+ * This implementation has the classic behavior by default.  However, it has
+ * been generalized somewhat so that it can act in a more "PageRank-like" fashion:
+ * <ul>
+ * <li/>this implementation has an optional 'random jump probability' parameter analogous
+ * to the 'alpha' parameter used by PageRank.  Varying this value between 0 and 1
+ * allows the user to vary between the classic HITS behavior and one in which the
+ * scores are smoothed to a uniform distribution.
+ * The default value for this parameter is 0 (no random jumps possible).
+ * <li/>the edge weights can be set to anything the user likes, and in 
+ * particular they can be set up (e.g. using <code>UniformDegreeWeight</code>)
+ * so that the weights of the relevant edges incident to a vertex sum to 1.
+ * <li/>The vertex score normalization has been factored into its own method
+ * so that it can be overridden by a subclass.  Thus, for example, 
+ * since the vertices' values are set to sum to 1 initially, if the weights of the
+ * relevant edges incident to a vertex sum to 1, then the vertices' values
+ * will continue to sum to 1 if the "sum-of-squares" normalization code
+ * is overridden to a no-op.  (Other normalization methods may also be employed.)
+ * </ul>
+ * 
+ * @param <V> the vertex type
+ * @param <E> the edge type
+ * 
+ * @see "'Authoritative sources in a hyperlinked environment' by Jon Kleinberg, 1997"
+ */
+public class HITS<V,E> extends HITSWithPriors<V,E>
+{
+
+    /**
+     * Creates an instance for the specified graph, edge weights, and alpha
+     * (random jump probability) parameter.
+     * @param g the input graph
+     * @param edge_weights the weights to use for each edge
+     * @param alpha the probability of a hub giving some authority to all vertices,
+     * and of an authority increasing the score of all hubs (not just those connected
+     * via links)
+     */
+    public HITS(Graph<V,E> g, Transformer<E, Double> edge_weights, double alpha)
+    {
+        super(g, edge_weights, ScoringUtils.getHITSUniformRootPrior(g.getVertices()), alpha);
+    }
+
+    /**
+     * Creates an instance for the specified graph and alpha (random jump probability)
+     * parameter.  The edge weights are all set to 1.
+     * @param g the input graph
+     * @param alpha the probability of a hub giving some authority to all vertices,
+     * and of an authority increasing the score of all hubs (not just those connected
+     * via links)
+     */
+    public HITS(Graph<V,E> g, double alpha)
+    {
+        super(g, ScoringUtils.getHITSUniformRootPrior(g.getVertices()), alpha);
+    }
+
+    /**
+     * Creates an instance for the specified graph.  The edge weights are all set to 1
+     * and alpha is set to 0.
+     * @param g the input graph
+     */
+    public HITS(Graph<V,E> g)
+    {
+        this(g, 0.0);
+    }
+    
+
+    /**
+     * Maintains hub and authority score information for a vertex.
+     */
+    public static class Scores
+    {
+       /**
+        * The hub score for a vertex.
+        */
+       public double hub;
+       
+       /**
+        * The authority score for a vertex.
+        */
+       public double authority;
+       
+       /**
+        * Creates an instance with the specified hub and authority score.
+        */
+       public Scores(double hub, double authority)
+       {
+               this.hub = hub;
+               this.authority = authority;
+       }
+       
+       @Override
+        public String toString()
+       {
+               return String.format("[h:%.4f,a:%.4f]", this.hub, this.authority);
+       }
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/HITSWithPriors.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/HITSWithPriors.java
new file mode 100644 (file)
index 0000000..51ba719
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Created on Jul 14, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+import org.apache.commons.collections15.Transformer;
+import org.apache.commons.collections15.functors.ConstantTransformer;
+
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * A generalization of HITS that permits non-uniformly-distributed random jumps.
+ * The 'vertex_priors' (that is, prior probabilities for each vertex) may be
+ * thought of as the fraction of the total 'potential' (hub or authority score)
+ * that is assigned to that vertex out of the portion that is assigned according
+ * to random jumps.
+ * 
+ * @see "Algorithms for Estimating Relative Importance in Graphs by Scott White and Padhraic Smyth, 2003"
+ */
+public class HITSWithPriors<V, E> 
+       extends AbstractIterativeScorerWithPriors<V,E,HITS.Scores>
+{
+    /**
+     * The sum of the potential, at each step, associated with vertices with no outedges (authority)
+     * or no inedges (hub).
+     */
+    protected HITS.Scores disappearing_potential;
+
+    /**
+     * Creates an instance for the specified graph, edge weights, vertex prior probabilities,
+     * and random jump probability (alpha).
+     * @param g the input graph
+     * @param edge_weights the edge weights 
+     * @param vertex_priors the prior probability for each vertex
+     * @param alpha the probability of a random jump at each step
+     */
+    public HITSWithPriors(Hypergraph<V,E> g,
+            Transformer<E, ? extends Number> edge_weights,
+            Transformer<V, HITS.Scores> vertex_priors, double alpha)
+    {
+        super(g, edge_weights, vertex_priors, alpha);
+        disappearing_potential = new HITS.Scores(0,0);
+    }
+
+    /**
+     * Creates an instance for the specified graph, vertex priors, and random
+     * jump probability (alpha).  The edge weights default to 1.0.
+     * @param g the input graph
+     * @param vertex_priors the prior probability for each vertex
+     * @param alpha the probability of a random jump at each step
+     */
+    @SuppressWarnings("unchecked")
+    public HITSWithPriors(Hypergraph<V,E> g, 
+          Transformer<V, HITS.Scores> vertex_priors, double alpha)
+    {
+       super(g, new ConstantTransformer(1.0), vertex_priors, alpha);
+        disappearing_potential = new HITS.Scores(0,0);
+    }
+
+    /**
+     * Updates the value for this vertex.
+     */
+    @Override
+    protected double update(V v)
+    {
+        collectDisappearingPotential(v);
+        
+        double v_auth = 0;
+        for (E e : graph.getInEdges(v))
+        {
+               int incident_count = getAdjustedIncidentCount(e);
+               for (V w : graph.getIncidentVertices(e)) 
+               {
+                       if (!w.equals(v) || hyperedges_are_self_loops) 
+                               v_auth += (getCurrentValue(w).hub * 
+                                               getEdgeWeight(w,e).doubleValue() / incident_count);
+               }
+//            V w = graph.getOpposite(v, e);
+//            auth += (getCurrentValue(w).hub * getEdgeWeight(w, e).doubleValue());
+        }
+        
+        double v_hub = 0;
+        for (E e : graph.getOutEdges(v))
+        {
+               int incident_count = getAdjustedIncidentCount(e);
+               for (V w : graph.getIncidentVertices(e)) 
+               {
+                       if (!w.equals(v) || hyperedges_are_self_loops) 
+                               v_hub += (getCurrentValue(w).authority * 
+                                               getEdgeWeight(w,e).doubleValue() / incident_count);
+               }
+//            V x = graph.getOpposite(v,e);
+//            hub += (getCurrentValue(x).authority * getEdgeWeight(x, e).doubleValue()); 
+        }
+        
+        // modify total_input according to alpha
+        if (alpha > 0) 
+        {
+               v_auth = v_auth * (1 - alpha) + getVertexPrior(v).authority * alpha;
+               v_hub = v_hub * (1 - alpha) + getVertexPrior(v).hub * alpha;
+        }
+        setOutputValue(v, new HITS.Scores(v_hub, v_auth));
+
+        return Math.max(Math.abs(getCurrentValue(v).hub - v_hub), 
+                        Math.abs(getCurrentValue(v).authority - v_auth));
+    }
+
+    /**
+     * Code which is executed after each step.  In this case, deals with the
+     * 'disappearing potential', normalizes the scores, and then calls
+     * <code>super.afterStep()</code>.
+     * @see #collectDisappearingPotential(Object)
+     */
+    @Override
+    protected void afterStep()
+    {
+        if (disappearing_potential.hub > 0 || disappearing_potential.authority > 0)
+        {
+            for (V v : graph.getVertices())
+            {
+                double new_hub = getOutputValue(v).hub + 
+                    (1 - alpha) * (disappearing_potential.hub * getVertexPrior(v).hub);
+                double new_auth = getOutputValue(v).authority + 
+                    (1 - alpha) * (disappearing_potential.authority * getVertexPrior(v).authority);
+                setOutputValue(v, new HITS.Scores(new_hub, new_auth));
+            }
+            disappearing_potential.hub = 0;
+            disappearing_potential.authority = 0;
+        }
+        
+       normalizeScores();
+       
+        super.afterStep();
+    }
+
+       /**
+        * Normalizes scores so that sum of their squares = 1.
+        * This method may be overridden so as to yield different 
+        * normalizations.
+        */
+       protected void normalizeScores() {
+       double hub_ssum = 0;
+       double auth_ssum = 0;
+       for (V v : graph.getVertices())
+       {
+               double hub_val = getOutputValue(v).hub;
+               double auth_val = getOutputValue(v).authority;
+               hub_ssum += (hub_val * hub_val);
+               auth_ssum += (auth_val * auth_val);
+       }
+
+       hub_ssum = Math.sqrt(hub_ssum);
+       auth_ssum = Math.sqrt(auth_ssum);
+       
+       for (V v : graph.getVertices())
+       {
+               HITS.Scores values = getOutputValue(v);
+               setOutputValue(v, new HITS.Scores(
+                               values.hub / hub_ssum,
+                               values.authority / auth_ssum));
+       }
+       }
+    
+       /**
+        * Collects the "disappearing potential" associated with vertices that have either 
+        * no incoming edges, no outgoing edges, or both.  Vertices that have no incoming edges
+        * do not directly contribute to the hub scores of other vertices; similarly, vertices
+        * that have no outgoing edges do not directly contribute to the authority scores of
+        * other vertices.  These values are collected at each step and then distributed across all vertices
+        * as a part of the normalization process.  (This process is not required for, and does
+        * not affect, the 'sum-of-squares'-style normalization.) 
+        */
+    @Override
+    protected void collectDisappearingPotential(V v)
+    {
+        if (graph.outDegree(v) == 0)
+        {
+            if (isDisconnectedGraphOK())
+                disappearing_potential.hub += getCurrentValue(v).authority;
+            else
+                throw new IllegalArgumentException("Outdegree of " + v + " must be > 0");
+        }
+        if (graph.inDegree(v) == 0)
+        {
+            if (isDisconnectedGraphOK())
+                disappearing_potential.authority += getCurrentValue(v).hub;
+            else
+                throw new IllegalArgumentException("Indegree of " + v + " must be > 0");
+        }
+    }
+
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/KStepMarkov.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/KStepMarkov.java
new file mode 100644 (file)
index 0000000..e640b1b
--- /dev/null
@@ -0,0 +1,156 @@
+/**
+ * Copyright (c) 2008, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ * Created on Aug 22, 2008
+ * 
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.scoring.util.ScoringUtils;
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * A special case of {@code PageRankWithPriors} in which the final scores
+ * represent a probability distribution over position assuming a random (Markovian)
+ * walk of exactly k steps, based on the initial distribution specified by the priors.
+ * 
+ * <p><b>NOTE</b>: The version of {@code KStepMarkov} in {@code algorithms.importance}
+ * (and in JUNG 1.x) is believed to be incorrect: rather than returning 
+ * a score which represents a probability distribution over position assuming
+ * a k-step random walk, it returns a score which represents the sum over all steps
+ * of the probability for each step.  If you want that behavior, set the 
+ * 'cumulative' flag as follows <i>before calling {@code evaluate()}</i>:
+ * <pre>
+ *     KStepMarkov ksm = new KStepMarkov(...);
+ *     ksm.setCumulative(true);
+ *     ksm.evaluate();
+ * </pre>
+ * 
+ * By default, the 'cumulative' flag is set to false.
+ * 
+ * NOTE: THIS CLASS IS NOT YET COMPLETE.  USE AT YOUR OWN RISK.  (The original behavior
+ * is captured by the version still available in {@code algorithms.importance}.)
+ * 
+ * @see "Algorithms for Estimating Relative Importance in Graphs by Scott White and Padhraic Smyth, 2003"
+ * @see PageRank
+ * @see PageRankWithPriors
+ */
+public class KStepMarkov<V,E> extends PageRankWithPriors<V,E> 
+{
+       private boolean cumulative;
+       
+       /**
+        * Creates an instance based on the specified graph, edge weights, vertex
+        * priors (initial scores), and number of steps to take.
+        * @param graph the input graph
+        * @param edge_weights the edge weights (transition probabilities)
+        * @param vertex_priors the initial probability distribution (score assignment)
+        * @param steps the number of times that {@code step()} will be called by {@code evaluate}
+        */
+       public KStepMarkov(Hypergraph<V,E> graph, Transformer<E, ? extends Number> edge_weights, 
+                                          Transformer<V, Double> vertex_priors, int steps)
+       {
+               super(graph, edge_weights, vertex_priors, 0);
+               initialize(steps);
+       }
+       
+       /**
+        * Creates an instance based on the specified graph, vertex
+        * priors (initial scores), and number of steps to take.  The edge
+        * weights (transition probabilities) are set to default values (a uniform
+        * distribution over all outgoing edges).
+        * @param graph the input graph
+        * @param vertex_priors the initial probability distribution (score assignment)
+        * @param steps the number of times that {@code step()} will be called by {@code evaluate}
+        */
+       public KStepMarkov(Hypergraph<V,E> graph, Transformer<V, Double> vertex_priors, int steps)
+       {
+               super(graph, vertex_priors, 0);
+               initialize(steps);
+       }
+       
+       /**
+        * Creates an instance based on the specified graph and number of steps to 
+        * take.  The edge weights (transition probabilities) and vertex initial scores
+        * (prior probabilities) are set to default values (a uniform
+        * distribution over all outgoing edges, and a uniform distribution over
+        * all vertices, respectively).
+        * @param graph the input graph
+        * @param steps the number of times that {@code step()} will be called by {@code evaluate}
+        */
+       public KStepMarkov(Hypergraph<V,E> graph, int steps)
+       {
+               super(graph, ScoringUtils.getUniformRootPrior(graph.getVertices()), 0);
+               initialize(steps);
+       }
+       
+       private void initialize(int steps)
+       {
+               this.acceptDisconnectedGraph(false);
+               
+               if (steps <= 0)
+                       throw new IllegalArgumentException("Number of steps must be > 0");
+               
+               this.max_iterations = steps;
+               this.tolerance = -1.0;
+               
+               this.cumulative = false;
+       }
+
+       /**
+        * Specifies whether this instance should assign a score to each vertex
+        * based on the 
+        * @param cumulative
+        */
+       public void setCumulative(boolean cumulative)
+       {
+               this.cumulative = cumulative;
+       }
+       
+    /**
+     * Updates the value for this vertex.  Called by <code>step()</code>.
+     */
+    @Override
+    public double update(V v)
+    {
+       if (!cumulative)
+               return super.update(v);
+       
+        collectDisappearingPotential(v);
+        
+        double v_input = 0;
+        for (E e : graph.getInEdges(v))
+        {
+               // For graphs, the code below is equivalent to 
+//          V w = graph.getOpposite(v, e);
+//          total_input += (getCurrentValue(w) * getEdgeWeight(w,e).doubleValue());
+               // For hypergraphs, this divides the potential coming from w 
+               // by the number of vertices in the connecting edge e.
+               int incident_count = getAdjustedIncidentCount(e);
+               for (V w : graph.getIncidentVertices(e)) 
+               {
+                       if (!w.equals(v) || hyperedges_are_self_loops) 
+                               v_input += (getCurrentValue(w) * 
+                                               getEdgeWeight(w,e).doubleValue() / incident_count);
+               }
+        }
+        
+        // modify total_input according to alpha
+        double new_value = alpha > 0 ? 
+                       v_input * (1 - alpha) + getVertexPrior(v) * alpha :
+                       v_input;
+        setOutputValue(v, new_value + getCurrentValue(v));
+
+        // FIXME: DO WE NEED TO CHANGE HOW DISAPPEARING IS COUNTED?  NORMALIZE?
+        
+        return Math.abs(getCurrentValue(v) - new_value);
+    }
+
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/PageRank.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/PageRank.java
new file mode 100644 (file)
index 0000000..ca7266d
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Created on Jul 12, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.scoring.util.ScoringUtils;
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * Assigns scores to each vertex according to the PageRank algorithm.  
+ * 
+ * <p>PageRank is an eigenvector-based algorithm.  The score for a given vertex may be thought of
+ * as the fraction of time spent 'visiting' that vertex (measured over all time) 
+ * in a random walk over the vertices (following outgoing edges from each vertex).  
+ * PageRank modifies this random walk by adding to the model a probability (specified as 'alpha' 
+ * in the constructor) of jumping to any vertex.  If alpha is 0, this is equivalent to the
+ * eigenvector centrality algorithm; if alpha is 1, all vertices will receive the same score
+ * (1/|V|).  Thus, alpha acts as a sort of score smoothing parameter.
+ * 
+ * <p>The original algorithm assumed that, for a given vertex, the probability of following any 
+ * outgoing edge was the same; this is the default if edge weights are not specified.  
+ * This implementation generalizes the original by permitting 
+ * the user to specify edge weights; in order to maintain the original semantics, however,
+ * the weights on the outgoing edges for a given vertex must represent transition probabilities; 
+ * that is, they must sum to 1.
+ * 
+ * <p>If a vertex has no outgoing edges, then the probability of taking a random jump from that
+ * vertex is (by default) effectively 1.  If the user wishes to instead throw an exception when this happens,
+ * call <code>acceptDisconnectedGraph(false)</code> on this instance.
+ * 
+ * <p>Typical values for alpha (according to the original paper) are in the range [0.1, 0.2]
+ * but may be any value between 0 and 1 inclusive.
+ * 
+ * @see "The Anatomy of a Large-Scale Hypertextual Web Search Engine by L. Page and S. Brin, 1999"
+ */
+public class PageRank<V,E> extends PageRankWithPriors<V,E>
+{
+
+    /**
+     * Creates an instance for the specified graph, edge weights, and random jump probability.
+     * @param graph the input graph
+     * @param edge_weight the edge weights (transition probabilities)
+     * @param alpha the probability of taking a random jump to an arbitrary vertex
+     */
+    public PageRank(Hypergraph<V,E> graph, Transformer<E, ? extends Number> edge_weight, double alpha)
+    {
+        super(graph, edge_weight, ScoringUtils.getUniformRootPrior(graph.getVertices()), alpha);
+    }
+
+    /**
+     * Creates an instance for the specified graph and random jump probability; the probability
+     * of following any outgoing edge from a given vertex is the same.
+     * @param graph the input graph
+     * @param alpha the probability of taking a random jump to an arbitrary vertex
+     */
+    public PageRank(Hypergraph<V,E> graph, double alpha)
+    {
+        super(graph, ScoringUtils.getUniformRootPrior(graph.getVertices()), alpha);
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/PageRankWithPriors.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/PageRankWithPriors.java
new file mode 100644 (file)
index 0000000..717d5ea
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Created on Jul 6, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.scoring.util.UniformDegreeWeight;
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * A generalization of PageRank that permits non-uniformly-distributed random jumps.
+ * The 'vertex_priors' (that is, prior probabilities for each vertex) may be
+ * thought of as the fraction of the total 'potential' that is assigned to that 
+ * vertex at each step out of the portion that is assigned according
+ * to random jumps (this portion is specified by 'alpha').
+ * 
+ * @see "Algorithms for Estimating Relative Importance in Graphs by Scott White and Padhraic Smyth, 2003"
+ * @see PageRank
+ */
+public class PageRankWithPriors<V, E> 
+       extends AbstractIterativeScorerWithPriors<V,E,Double>
+{
+    /**
+     * Maintains the amount of potential associated with vertices with no out-edges.
+     */
+    protected double disappearing_potential = 0.0;
+    
+    /**
+     * Creates an instance with the specified graph, edge weights, vertex priors, and 
+     * 'random jump' probability (alpha).
+     * @param graph the input graph
+     * @param edge_weights the edge weights, denoting transition probabilities from source to destination
+     * @param vertex_priors the prior probabilities for each vertex
+     * @param alpha the probability of executing a 'random jump' at each step
+     */
+    public PageRankWithPriors(Hypergraph<V,E> graph, 
+               Transformer<E, ? extends Number> edge_weights, 
+            Transformer<V, Double> vertex_priors, double alpha)
+    {
+        super(graph, edge_weights, vertex_priors, alpha);
+    }
+    
+    /**
+     * Creates an instance with the specified graph, vertex priors, and 
+     * 'random jump' probability (alpha).  The outgoing edge weights for each
+     * vertex will be equal and sum to 1.
+     * @param graph the input graph
+     * @param vertex_priors the prior probabilities for each vertex
+     * @param alpha the probability of executing a 'random jump' at each step
+     */
+    public PageRankWithPriors(Hypergraph<V,E> graph, 
+               Transformer<V, Double> vertex_priors, double alpha)
+    {
+        super(graph, vertex_priors, alpha);
+        this.edge_weights = new UniformDegreeWeight<V,E>(graph);
+    }
+    
+    /**
+     * Updates the value for this vertex.  Called by <code>step()</code>.
+     */
+    @Override
+    public double update(V v)
+    {
+        collectDisappearingPotential(v);
+        
+        double v_input = 0;
+        for (E e : graph.getInEdges(v))
+        {
+               // For graphs, the code below is equivalent to 
+//          V w = graph.getOpposite(v, e);
+//          total_input += (getCurrentValue(w) * getEdgeWeight(w,e).doubleValue());
+               // For hypergraphs, this divides the potential coming from w 
+               // by the number of vertices in the connecting edge e.
+               int incident_count = getAdjustedIncidentCount(e);
+               for (V w : graph.getIncidentVertices(e)) 
+               {
+                       if (!w.equals(v) || hyperedges_are_self_loops) 
+                               v_input += (getCurrentValue(w) * 
+                                               getEdgeWeight(w,e).doubleValue() / incident_count);
+               }
+        }
+        
+        // modify total_input according to alpha
+        double new_value = alpha > 0 ? 
+                       v_input * (1 - alpha) + getVertexPrior(v) * alpha :
+                       v_input;
+        setOutputValue(v, new_value);
+        
+        return Math.abs(getCurrentValue(v) - new_value);
+    }
+
+    /**
+     * Cleans up after each step.  In this case that involves allocating the disappearing
+     * potential (thus maintaining normalization of the scores) according to the vertex 
+     * probability priors, and then calling 
+     * <code>super.afterStep</code>.
+     */
+    @Override
+    protected void afterStep()
+    {
+        // distribute disappearing potential according to priors
+        if (disappearing_potential > 0)
+        {
+            for (V v : graph.getVertices())
+            {
+                setOutputValue(v, getOutputValue(v) + 
+                        (1 - alpha) * (disappearing_potential * getVertexPrior(v)));
+            }
+            disappearing_potential = 0;
+        }
+        
+        super.afterStep();
+    }
+    
+    /**
+     * Collects the "disappearing potential" associated with vertices that have 
+     * no outgoing edges.  Vertices that have no outgoing edges do not directly 
+     * contribute to the scores of other vertices.  These values are collected 
+     * at each step and then distributed across all vertices
+     * as a part of the normalization process.
+    */
+    @Override
+    protected void collectDisappearingPotential(V v)
+    {
+        if (graph.outDegree(v) == 0)
+        {
+            if (isDisconnectedGraphOK())
+                disappearing_potential += getCurrentValue(v);
+            else
+                throw new IllegalArgumentException("Outdegree of " + v + " must be > 0");
+        }
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/VertexScorer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/VertexScorer.java
new file mode 100644 (file)
index 0000000..610de6b
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Created on Jul 6, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+
+/**
+ * An interface for algorithms that assign scores to vertices.
+ *
+ * @param <V> the vertex type
+ * @param <S> the score type
+ */
+public interface VertexScorer<V, S>
+{
+    /**
+     * Returns the algorithm's score for this vertex.
+     * @return the algorithm's score for this vertex
+     */
+    public S getVertexScore(V v);
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/VoltageScorer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/VoltageScorer.java
new file mode 100644 (file)
index 0000000..f05b911
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Created on Jul 15, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.scoring.util.UniformDegreeWeight;
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * Assigns scores to vertices according to their 'voltage' in an approximate 
+ * solution to the Kirchoff equations.  This is accomplished by tying "source"
+ * vertices to specified positive voltages, "sink" vertices to 0 V, and 
+ * iteratively updating the voltage of each other vertex to the (weighted) 
+ * average of the voltages of its neighbors.
+ * 
+ * <p>The resultant voltages will all be in the range <code>[0, max]</code>
+ * where <code>max</code> is the largest voltage of any source vertex (in the
+ * absence of negative source voltages; see below).
+ * 
+ * <p>A few notes about this algorithm's interpretation of the graph data: 
+ * <ul>
+ * <li/>Higher edge weights are interpreted as indicative of greater 
+ * influence/effect than lower edge weights.  
+ * <li/>Negative edge weights (and negative "source" voltages) invalidate
+ * the interpretation of the resultant values as voltages.  However, this 
+ * algorithm will not reject graphs with negative edge weights or source voltages.
+ * <li/>Parallel edges are equivalent to a single edge whose weight is the 
+ * sum of the weights on the parallel edges.
+ * <li/>Current flows along undirected edges in both directions, 
+ * but only flows along directed edges in the direction of the edge.
+ * </ul>
+ * </p> 
+ */
+public class VoltageScorer<V, E> extends AbstractIterativeScorer<V, E, Double>
+        implements VertexScorer<V, Double>
+{
+    protected Map<V, ? extends Number> source_voltages;
+    protected Collection<V> sinks;
+    
+    /**
+     * Creates an instance with the specified graph, edge weights, source voltages,
+     * and sinks.
+     * @param g the input graph
+     * @param edge_weights the edge weights, representing conductivity
+     * @param source_voltages the (fixed) voltage for each source
+     * @param sinks the vertices whose voltages are tied to 0
+     */
+    public VoltageScorer(Hypergraph<V, E> g, Transformer<E, ? extends Number> edge_weights, 
+            Map<V, ? extends Number> source_voltages, Collection<V> sinks)
+    {
+        super(g, edge_weights);
+        this.source_voltages = source_voltages;
+        this.sinks = sinks;
+        initialize();
+    }
+
+    /**
+     * Creates an instance with the specified graph, edge weights, source vertices
+     * (each of whose 'voltages' are tied to 1), and sinks.
+     * @param g the input graph
+     * @param edge_weights the edge weights, representing conductivity
+     * @param sources the vertices whose voltages are tied to 1
+     * @param sinks the vertices whose voltages are tied to 0
+     */
+    public VoltageScorer(Hypergraph<V, E> g, Transformer<E, ? extends Number> edge_weights, 
+            Collection<V> sources, Collection<V> sinks)
+    {
+        super(g, edge_weights);
+        
+        Map<V, Double> unit_voltages = new HashMap<V, Double>();
+        for(V v : sources) 
+            unit_voltages.put(v, new Double(1.0));
+        this.source_voltages = unit_voltages;
+        this.sinks = sinks;
+        initialize();
+    }
+
+    /**
+     * Creates an instance with the specified graph, source vertices
+     * (each of whose 'voltages' are tied to 1), and sinks.
+     * The outgoing edges for each vertex are assigned 
+     * weights that sum to 1.
+     * @param g the input graph
+     * @param sources the vertices whose voltages are tied to 1
+     * @param sinks the vertices whose voltages are tied to 0
+     */
+    public VoltageScorer(Hypergraph<V, E> g, Collection<V> sources, Collection<V> sinks)
+    {
+        super(g);
+        
+        Map<V, Double> unit_voltages = new HashMap<V, Double>();
+        for(V v : sources) 
+            unit_voltages.put(v, new Double(1.0));
+        this.source_voltages = unit_voltages;
+        this.sinks = sinks;
+        initialize();
+    }
+    
+    /**
+     * Creates an instance with the specified graph, source voltages,
+     * and sinks.  The outgoing edges for each vertex are assigned 
+     * weights that sum to 1.
+     * @param g the input graph
+     * @param source_voltages the (fixed) voltage for each source
+     * @param sinks the vertices whose voltages are tied to 0
+     */
+    public VoltageScorer(Hypergraph<V, E> g, Map<V, ? extends Number> source_voltages, 
+               Collection<V> sinks)
+    {
+        super(g);
+        this.source_voltages = source_voltages;
+        this.sinks = sinks;
+        this.edge_weights = new UniformDegreeWeight<V,E>(g);
+        initialize();
+    }
+    
+    /**
+     * Creates an instance with the specified graph, edge weights, source, and
+     * sink.  The source vertex voltage is tied to 1.
+     * @param g the input graph
+     * @param edge_weights the edge weights, representing conductivity
+     * @param source the vertex whose voltage is tied to 1
+     * @param sink the vertex whose voltage is tied to 0
+     */
+    public VoltageScorer(Hypergraph<V,E> g, Transformer<E, ? extends Number> edge_weights, 
+               V source, V sink)
+    {
+        this(g, edge_weights, Collections.singletonMap(source, 1.0), Collections.singletonList(sink));
+        initialize();
+    }
+
+    /**
+     * Creates an instance with the specified graph, edge weights, source, and
+     * sink.  The source vertex voltage is tied to 1.
+     * The outgoing edges for each vertex are assigned 
+     * weights that sum to 1.
+     * @param g the input graph
+     * @param source the vertex whose voltage is tied to 1
+     * @param sink the vertex whose voltage is tied to 0
+     */
+    public VoltageScorer(Hypergraph<V,E> g, V source, V sink)
+    {
+        this(g, Collections.singletonMap(source, 1.0), Collections.singletonList(sink));
+        initialize();
+    }
+
+    
+    /**
+     * Initializes the state of this instance.
+     */
+    @Override
+    public void initialize()
+    {
+        super.initialize();
+        
+        // sanity check
+        if (source_voltages.isEmpty() || sinks.isEmpty())
+            throw new IllegalArgumentException("Both sources and sinks (grounds) must be defined");
+        
+        if (source_voltages.size() + sinks.size() > graph.getVertexCount())
+            throw new IllegalArgumentException("Source/sink sets overlap, or contain vertices not in graph");
+        
+        for (Map.Entry<V, ? extends Number> entry : source_voltages.entrySet())
+        {
+            V v = entry.getKey();
+            if (sinks.contains(v))
+                throw new IllegalArgumentException("Vertex " + v + " is incorrectly specified as both source and sink");
+            double value = entry.getValue().doubleValue();
+            if (value <= 0)
+                throw new IllegalArgumentException("Source vertex " + v + " has negative voltage");
+        }
+        
+        // set up initial voltages
+        for (V v : graph.getVertices())
+        {
+            if (source_voltages.containsKey(v))
+                setOutputValue(v, source_voltages.get(v).doubleValue());
+            else
+                setOutputValue(v, 0.0);
+        }
+    }
+    
+    /**
+     * @see edu.uci.ics.jung.algorithms.scoring.AbstractIterativeScorer#update(Object)
+     */
+    @Override
+    public double update(V v)
+    {
+        // if it's a voltage source or sink, we're done
+        Number source_volts = source_voltages.get(v);
+        if (source_volts != null) 
+        {
+            setOutputValue(v, source_volts.doubleValue());
+            return 0.0;
+        }
+        if (sinks.contains(v))
+        {
+            setOutputValue(v, 0.0);
+            return 0.0;
+        }
+        
+        Collection<E> edges = graph.getInEdges(v);
+        double voltage_sum = 0;
+        double weight_sum = 0;
+        for (E e: edges)
+        {
+               int incident_count = getAdjustedIncidentCount(e);
+               for (V w : graph.getIncidentVertices(e)) 
+               {
+                       if (!w.equals(v) || hyperedges_are_self_loops) 
+                       {
+                               double weight = getEdgeWeight(w,e).doubleValue() / incident_count;
+                               voltage_sum += getCurrentValue(w).doubleValue() * weight;
+                               weight_sum += weight;
+                       }
+               }
+//            V w = graph.getOpposite(v, e);
+//            double weight = getEdgeWeight(w,e).doubleValue();
+//            voltage_sum += getCurrentValue(w).doubleValue() * weight;
+//            weight_sum += weight;
+        }
+
+        // if either is 0, new value is 0
+        if (voltage_sum == 0 || weight_sum == 0)
+        {
+            setOutputValue(v, 0.0);
+            return getCurrentValue(v).doubleValue();
+        }
+        
+        setOutputValue(v, voltage_sum / weight_sum);
+        return Math.abs(getCurrentValue(v).doubleValue() - voltage_sum / weight_sum);
+    }
+
+}
+
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/package.html
new file mode 100644 (file)
index 0000000..a1f8196
--- /dev/null
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+-->
+</head>
+<body>
+
+Mechanisms for assigning values (denoting significance, influence, centrality, etc.)
+to graph elements based on topological properties.  These include:
+
+<ul>
+<li/><code>BarycenterScorer</code>: assigns a score to each vertex according to 
+the sum of the distances to all other vertices
+<li/><code>ClosenessCentrality</code>: assigns a score to each vertex based on 
+the mean distance to each other vertex
+<li/><code>DegreeScorer</code>: assigns a score to each vertex based on its degree
+<li/><code>EigenvectorCentrality</code>: assigns vertex scores based on 
+long-term probabilities of random walks passing through the vertex at time t
+<li/><code>PageRank</code>: like <code>EigenvectorCentrality</code>, but with 
+a constant probability of the
+random walk restarting at a uniform-randomly chosen vertex
+<li/><code>PageRankWithPriors</code>: like <code>PageRank</code>, but with a 
+constant probability of the random
+walk restarting at a vertex drawn from an arbitrary distribution
+<li/><code>HITS</code>: assigns hubs-and-authorities scores to vertices based on 
+complementary random walk processes
+<li/><code>HITSWithPriors</code>: analogous to <code>HITS</code> 
+(see <code>PageRankWithPriors</code>)
+<li/><code>VoltageScorer</code>: assigns scores to vertices based on simulated 
+current flow along edges
+</ul>
+
+</body>
+</html>
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/DelegateToEdgeTransformer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/DelegateToEdgeTransformer.java
new file mode 100644 (file)
index 0000000..f836a9b
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Created on Jul 11, 2008
+ *
+ * Copyright (c) 2008, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring.util;
+
+import org.apache.commons.collections15.Transformer;
+
+/**
+ * A <code>Transformer<VEPair,Number></code> that delegates its operation to a
+ * <code>Transformer<E,Number></code>.  Mainly useful for technical reasons inside 
+ * AbstractIterativeScorer; in essence it allows the edge weight instance 
+ * variable to be of type <code>VEPair,W</code> even if the edge weight 
+ * <code>Transformer</code> only operates on edges.
+ */
+public class DelegateToEdgeTransformer<V,E> implements
+        Transformer<VEPair<V,E>,Number>
+{
+       /**
+        * The transformer to which this instance delegates its function.
+        */
+    protected Transformer<E,? extends Number> delegate;
+    
+    /**
+     * Creates an instance with the specified delegate transformer.
+     * @param delegate the Transformer to which this instance will delegate
+     */
+    public DelegateToEdgeTransformer(Transformer<E,? extends Number> delegate)
+    {
+        this.delegate = delegate;
+    }
+    
+    /**
+     * @see Transformer#transform(Object)
+     */
+    public Number transform(VEPair<V,E> arg0)
+    {
+        return delegate.transform(arg0.getE());
+    }
+
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/ScoringUtils.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/ScoringUtils.java
new file mode 100644 (file)
index 0000000..793944b
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Created on Jul 12, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring.util;
+
+import java.util.Collection;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.scoring.HITS;
+
+/**
+ * Methods for assigning values (to be interpreted as prior probabilities) to vertices in the context
+ * of random-walk-based scoring algorithms.
+ */
+public class ScoringUtils
+{
+    /**
+     * Assigns a probability of 1/<code>roots.size()</code> to each of the elements of <code>roots</code>.
+     * @param <V> the vertex type
+     * @param roots the vertices to be assigned nonzero prior probabilities
+     * @return
+     */
+    public static <V> Transformer<V, Double> getUniformRootPrior(Collection<V> roots)
+    {
+        final Collection<V> inner_roots = roots;
+        Transformer<V, Double> distribution = new Transformer<V, Double>()
+        {
+            public Double transform(V input)
+            {
+                if (inner_roots.contains(input))
+                    return new Double(1.0 / inner_roots.size());
+                else
+                    return 0.0;
+            }
+        };
+        
+        return distribution;
+    }
+    
+    /**
+     * Returns a Transformer that hub and authority values of 1/<code>roots.size()</code> to each 
+     * element of <code>roots</code>.
+     * @param <V> the vertex type
+     * @param roots the vertices to be assigned nonzero scores
+     * @return a Transformer that assigns uniform prior hub/authority probabilities to each root
+     */
+    public static <V> Transformer<V, HITS.Scores> getHITSUniformRootPrior(Collection<V> roots)
+    {
+        final Collection<V> inner_roots = roots;
+        Transformer<V, HITS.Scores> distribution = 
+               new Transformer<V, HITS.Scores>()
+        {
+            public HITS.Scores transform(V input)
+            {
+                if (inner_roots.contains(input))
+                    return new HITS.Scores(1.0 / inner_roots.size(), 1.0 / inner_roots.size());
+                else
+                    return new HITS.Scores(0.0, 0.0);
+            }
+        };
+        return distribution;
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/UniformDegreeWeight.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/UniformDegreeWeight.java
new file mode 100644 (file)
index 0000000..f22bfcc
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2008, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ * Created on Jul 14, 2008
+ * 
+ */
+package edu.uci.ics.jung.algorithms.scoring.util;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.graph.Hypergraph;
+import edu.uci.ics.jung.graph.util.EdgeType;
+
+/**
+ * An edge weight function that assigns weights as uniform
+ * transition probabilities.
+ * For undirected edges, returns 1/degree(v) (where 'v' is the
+ * vertex in the VEPair.
+ * For directed edges, returns 1/outdegree(source(e)) (where 'e'
+ * is the edge in the VEPair).
+ * Throws an <code>IllegalArgumentException</code> if the input 
+ * edge is neither EdgeType.UNDIRECTED nor EdgeType.DIRECTED.
+ *
+ */
+public class UniformDegreeWeight<V, E> implements
+               Transformer<VEPair<V, E>, Double> 
+{
+    private Hypergraph<V, E> graph;
+    
+    /**
+     * Creates an instance for the specified graph.
+     */
+    public UniformDegreeWeight(Hypergraph<V, E> graph)
+    {
+        this.graph = graph;
+    }
+
+       /**
+        * @see org.apache.commons.collections15.Transformer#transform(java.lang.Object)
+        */
+       public Double transform(VEPair<V, E> ve_pair) 
+       {
+               E e = ve_pair.getE();
+               V v = ve_pair.getV();
+               EdgeType edge_type = graph.getEdgeType(e);
+               if (edge_type == EdgeType.UNDIRECTED)
+                       return 1.0 / graph.degree(v);
+               if (edge_type == EdgeType.DIRECTED)
+                       return 1.0 / graph.outDegree(graph.getSource(e));
+               throw new IllegalArgumentException("can't handle edge type: " + edge_type);
+       }
+
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/UniformInOut.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/UniformInOut.java
new file mode 100644 (file)
index 0000000..7853f00
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Created on Jul 11, 2008
+ *
+ * Copyright (c) 2008, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring.util;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.EdgeType;
+
+/**
+ * Assigns weights to directed edges (the edge of the vertex/edge pair) depending on 
+ * whether the vertex is the edge's source or its destination.
+ * If the vertex v is the edge's source, assigns 1/outdegree(v).
+ * Otherwise, assigns 1/indegree(w).
+ * Throws <code>IllegalArgumentException</code> if the edge is not directed.
+ */
+public class UniformInOut<V,E> implements Transformer<VEPair<V,E>, Double>
+{
+       /**
+        * The graph for which the edge weights are defined.
+        */
+    protected Graph<V,E> graph;
+    
+    /**
+     * Creates an instance for the specified graph.
+     * @param graph the graph for which the edge weights will be defined
+     */
+    public UniformInOut(Graph<V,E> graph)
+    {
+        this.graph = graph;
+    }
+    
+    /**
+     * @see org.apache.commons.collections15.Transformer#transform(Object)
+     * @throws IllegalArgumentException
+     */
+    public Double transform(VEPair<V,E> ve_pair)
+    {
+       V v = ve_pair.getV();
+       E e = ve_pair.getE();
+       if (graph.getEdgeType(e) != EdgeType.DIRECTED)
+               throw new IllegalArgumentException("This transformer only" +
+                               " operates on directed edges");
+       return 1.0 / (graph.isSource(v, e) ? 
+                       graph.outDegree(v) : 
+                       graph.inDegree(v));
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/VEPair.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/VEPair.java
new file mode 100644 (file)
index 0000000..ad90293
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Created on Jul 8, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring.util;
+
+/**
+ * Convenience class for associating a vertex and an edge.  Used, for example,
+ * in contexts in which it is necessary to know the origin for an edge traversal
+ * (that is, the direction in which an (undirected) edge is being traversed).
+ *
+ * @param <V> the vertex type
+ * @param <E> the edge type
+ */
+public class VEPair<V, E>
+{
+    private V v;
+    private E e;
+    
+    /**
+     * Creates an instance with the specified vertex and edge
+     * @param v the vertex to add
+     * @param e the edge to add
+     */
+    public VEPair(V v, E e)
+    {
+        if (v == null || e == null)
+            throw new IllegalArgumentException("elements must be non-null");
+        
+        this.v = v;
+        this.e = e;
+    }
+    
+    /**
+     * Returns the vertex of this pair.
+     */
+    public V getV()
+    {
+        return v;
+    }
+    
+    /**
+     * Returns the edge of this pair.
+     */
+    public E getE()
+    {
+        return e;
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/VertexScoreTransformer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/VertexScoreTransformer.java
new file mode 100644 (file)
index 0000000..851c08e
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Created on Jul 18, 2008
+ *
+ * Copyright (c) 2008, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.scoring.util;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.scoring.VertexScorer;
+
+/**
+ * A Transformer convenience wrapper around VertexScorer.
+ */
+public class VertexScoreTransformer<V, S> implements Transformer<V, S>
+{
+    /**
+     * The VertexScorer instance that provides the values returned by <code>transform</code>.
+     */
+    protected VertexScorer<V,S> vs;
+
+    /**
+     * Creates an instance based on the specified VertexScorer.
+     */
+    public VertexScoreTransformer(VertexScorer<V,S> vs)
+    {
+        this.vs = vs;
+    }
+
+    /**
+     * Returns the score for this vertex.
+     */
+    public S transform(V v)
+    {
+        return vs.getVertexScore(v);
+    }
+
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/scoring/util/package.html
new file mode 100644 (file)
index 0000000..3bf18f3
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+-->
+</head>
+<body>
+
+Utility functions for assigning scores to graph elements.  These include:
+<ul>
+<li/><code>EdgeWeight</code>: interface for classes that associate numeric values 
+with edges
+<li/><code>ScoringUtils</code>: methods for calculating transition probabilities
+for random-walk-based algorithms.
+<li/><code>UniformOut</code>: an edge weight function that assigns weights as uniform
+transition probabilities to all outgoing edges of a vertex.
+<li/><code>UniformIncident</code>: an edge weight function that assigns
+weights as uniform transition probabilities to all incident edges of a
+vertex (useful for undirected graphs). 
+<li/><code>VEPair</code>: analogous to <code>Pair</code> but specifically 
+containing an associated vertex and edge.
+<li/><code>VertexEdgeWeight</code>: a subtype of <code>EdgeWeight</code> that 
+assigns edge weights with respect to a specified 'source' vertex. 
+</ul>
+
+</body>
+</html>
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/BFSDistanceLabeler.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/BFSDistanceLabeler.java
new file mode 100644 (file)
index 0000000..38d3b00
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.shortestpath;
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * Labels each node in the graph according to the BFS distance from the start node(s). If nodes are unreachable, then
+ * they are assigned a distance of -1.
+ * All nodes traversed at step k are marked as predecessors of their successors traversed at step k+1.
+ * <p>
+ * Running time is: O(m)
+ * @author Scott White
+ */
+public class BFSDistanceLabeler<V, E> {
+
+    private Map<V, Number> distanceDecorator = new HashMap<V,Number>();
+    private List<V> mCurrentList;
+    private Set<V> mUnvisitedVertices;
+    private List<V> mVerticesInOrderVisited;
+    private Map<V,HashSet<V>> mPredecessorMap;
+
+       /**
+        * Creates a new BFS labeler for the specified graph and root set
+        * The distances are stored in the corresponding Vertex objects and are of type MutableInteger
+        */
+       public BFSDistanceLabeler() {
+               mPredecessorMap = new HashMap<V,HashSet<V>>();
+       }
+
+    /**
+     * Returns the list of vertices visited in order of traversal
+     * @return the list of vertices
+     */
+    public List<V> getVerticesInOrderVisited() {
+        return mVerticesInOrderVisited;
+    }
+
+    /**
+     * Returns the set of all vertices that were not visited
+     * @return the list of unvisited vertices
+     */
+    public Set<V> getUnvisitedVertices() {
+        return mUnvisitedVertices;
+    }
+
+    /**
+     * Given a vertex, returns the shortest distance from any node in the root set to v
+     * @param v the vertex whose distance is to be retrieved
+     * @return the shortest distance from any node in the root set to v
+     */
+    public int getDistance(Hypergraph<V,E> g, V v) {
+        if (!g.getVertices().contains(v)) {
+            throw new IllegalArgumentException("Vertex is not contained in the graph.");
+        }
+
+        return distanceDecorator.get(v).intValue();
+    }
+
+    /**
+     * Returns set of predecessors of the given vertex
+     * @param v the vertex whose predecessors are to be retrieved
+     * @return the set of predecessors
+     */
+    public Set<V> getPredecessors(V v) {
+        return mPredecessorMap.get(v);
+    }
+
+    protected void initialize(Hypergraph<V,E> g, Set<V> rootSet) {
+        mVerticesInOrderVisited = new ArrayList<V>();
+        mUnvisitedVertices = new HashSet<V>();
+        for(V currentVertex : g.getVertices()) {
+            mUnvisitedVertices.add(currentVertex);
+            mPredecessorMap.put(currentVertex,new HashSet<V>());
+        }
+
+        mCurrentList = new ArrayList<V>();
+        for(V v : rootSet) {
+            distanceDecorator.put(v, new Integer(0));
+            mCurrentList.add(v);
+            mUnvisitedVertices.remove(v);
+            mVerticesInOrderVisited.add(v);
+        }
+    }
+
+    private void addPredecessor(V predecessor,V sucessor) {
+        HashSet<V> predecessors = mPredecessorMap.get(sucessor);
+        predecessors.add(predecessor);
+    }
+
+    /**
+     * Computes the distances of all the node from the starting root nodes. If there is more than one root node
+     * the minimum distance from each root node is used as the designated distance to a given node. Also keeps track
+     * of the predecessors of each node traversed as well as the order of nodes traversed.
+     * @param graph the graph to label
+     * @param rootSet the set of starting vertices to traverse from
+     */
+    public void labelDistances(Hypergraph<V,E> graph, Set<V> rootSet) {
+
+        initialize(graph,rootSet);
+
+        int distance = 1;
+        while (true) {
+            List<V> newList = new ArrayList<V>();
+            for(V currentVertex : mCurrentList) {
+               if(graph.containsVertex(currentVertex)) {
+                       for(V next : graph.getSuccessors(currentVertex)) {
+                               visitNewVertex(currentVertex,next, distance, newList);
+                       }
+               }
+            }
+            if (newList.size() == 0) break;
+            mCurrentList = newList;
+            distance++;
+        }
+
+        for(V v : mUnvisitedVertices) {
+            distanceDecorator.put(v,new Integer(-1));
+        }
+    }
+
+    /**
+     * Computes the distances of all the node from the specified root node. Also keeps track
+     * of the predecessors of each node traversed as well as the order of nodes traversed.
+     *  @param graph the graph to label
+     * @param root the single starting vertex to traverse from
+     */
+    public void labelDistances(Hypergraph<V,E> graph, V root) {
+        labelDistances(graph, Collections.singleton(root));
+    }
+
+    private void visitNewVertex(V predecessor, V neighbor, int distance, List<V> newList) {
+        if (mUnvisitedVertices.contains(neighbor)) {
+            distanceDecorator.put(neighbor, new Integer(distance));
+            newList.add(neighbor);
+            mVerticesInOrderVisited.add(neighbor);
+            mUnvisitedVertices.remove(neighbor);
+        }
+        int predecessorDistance = distanceDecorator.get(predecessor).intValue();
+        int successorDistance = distanceDecorator.get(neighbor).intValue();
+        if (predecessorDistance < successorDistance) {
+            addPredecessor(predecessor,neighbor);
+        }
+    }
+
+    /**
+     * Returns a map from vertices to minimum distances from the original source(s).
+     * Must be called after {@code labelDistances} in order to contain valid data.
+     */
+    public Map<V, Number> getDistanceDecorator() {
+        return distanceDecorator;
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/DijkstraDistance.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/DijkstraDistance.java
new file mode 100644 (file)
index 0000000..3e99e16
--- /dev/null
@@ -0,0 +1,582 @@
+/*
+ * Created on Jul 9, 2005
+ *
+ * Copyright (c) 2005, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.shortestpath;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections15.Transformer;
+import org.apache.commons.collections15.functors.ConstantTransformer;
+
+import edu.uci.ics.jung.algorithms.util.BasicMapEntry;
+import edu.uci.ics.jung.algorithms.util.MapBinaryHeap;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * <p>Calculates distances in a specified graph, using  
+ * Dijkstra's single-source-shortest-path algorithm.  All edge weights
+ * in the graph must be nonnegative; if any edge with negative weight is 
+ * found in the course of calculating distances, an 
+ * <code>IllegalArgumentException</code> will be thrown.
+ * (Note: this exception will only be thrown when such an edge would be
+ * used to update a given tentative distance;
+ * the algorithm does not check for negative-weight edges "up front".)
+ * 
+ * <p>Distances and partial results are optionally cached (by this instance)
+ * for later reference.  Thus, if the 10 closest vertices to a specified source 
+ * vertex are known, calculating the 20 closest vertices does not require 
+ * starting Dijkstra's algorithm over from scratch.</p>
+ * 
+ * <p>Distances are stored as double-precision values.  
+ * If a vertex is not reachable from the specified source vertex, no 
+ * distance is stored.  <b>This is new behavior with version 1.4</b>;
+ * the previous behavior was to store a value of 
+ * <code>Double.POSITIVE_INFINITY</code>.  This change gives the algorithm
+ * an approximate complexity of O(kD log k), where k is either the number of
+ * requested targets or the number of reachable vertices (whichever is smaller),
+ * and D is the average degree of a vertex.</p>
+ * 
+ * <p> The elements in the maps returned by <code>getDistanceMap</code> 
+ * are ordered (that is, returned 
+ * by the iterator) by nondecreasing distance from <code>source</code>.</p>
+ * 
+ * <p>Users are cautioned that distances calculated should be assumed to
+ * be invalidated by changes to the graph, and should invoke <code>reset()</code>
+ * when appropriate so that the distances can be recalculated.</p>
+ * 
+ * @author Joshua O'Madadhain
+ * @author Tom Nelson converted to jung2
+ */
+public class DijkstraDistance<V,E> implements Distance<V>
+{
+    protected Hypergraph<V,E> g;
+    protected Transformer<E,? extends Number> nev;
+    protected Map<V,SourceData> sourceMap;   // a map of source vertices to an instance of SourceData
+    protected boolean cached;
+    protected double max_distance;
+    protected int max_targets;
+    
+    /**
+     * <p>Creates an instance of <code>DijkstraShortestPath</code> for 
+     * the specified graph and the specified method of extracting weights 
+     * from edges, which caches results locally if and only if 
+     * <code>cached</code> is <code>true</code>.
+     * 
+     * @param g     the graph on which distances will be calculated
+     * @param nev   the class responsible for returning weights for edges
+     * @param cached    specifies whether the results are to be cached
+     */
+    public DijkstraDistance(Hypergraph<V,E> g, Transformer<E,? extends Number> nev, boolean cached) {
+        this.g = g;
+        this.nev = nev;
+        this.sourceMap = new HashMap<V,SourceData>();
+        this.cached = cached;
+        this.max_distance = Double.POSITIVE_INFINITY;
+        this.max_targets = Integer.MAX_VALUE;
+    }
+    
+    /**
+     * <p>Creates an instance of <code>DijkstraShortestPath</code> for 
+     * the specified graph and the specified method of extracting weights 
+     * from edges, which caches results locally.
+     * 
+     * @param g     the graph on which distances will be calculated
+     * @param nev   the class responsible for returning weights for edges
+     */
+    public DijkstraDistance(Hypergraph<V,E> g, Transformer<E,? extends Number> nev) {
+        this(g, nev, true);
+    }
+    
+    /**
+     * <p>Creates an instance of <code>DijkstraShortestPath</code> for 
+     * the specified unweighted graph (that is, all weights 1) which
+     * caches results locally.
+     * 
+     * @param g     the graph on which distances will be calculated
+     */ 
+    @SuppressWarnings("unchecked")
+    public DijkstraDistance(Hypergraph<V,E> g) {
+        this(g, new ConstantTransformer(1), true);
+    }
+
+    /**
+     * <p>Creates an instance of <code>DijkstraShortestPath</code> for 
+     * the specified unweighted graph (that is, all weights 1) which
+     * caches results locally.
+     * 
+     * @param g     the graph on which distances will be calculated
+     * @param cached    specifies whether the results are to be cached
+     */ 
+    @SuppressWarnings("unchecked")
+    public DijkstraDistance(Hypergraph<V,E> g, boolean cached) {
+        this(g, new ConstantTransformer(1), cached);
+    }
+
+    /**
+     * Implements Dijkstra's single-source shortest-path algorithm for
+     * weighted graphs.  Uses a <code>MapBinaryHeap</code> as the priority queue, 
+     * which gives this algorithm a time complexity of O(m lg n) (m = # of edges, n = 
+     * # of vertices).
+     * This algorithm will terminate when any of the following have occurred (in order
+     * of priority):
+     * <ul>
+     * <li> the distance to the specified target (if any) has been found
+     * <li> no more vertices are reachable 
+     * <li> the specified # of distances have been found, or the maximum distance 
+     * desired has been exceeded
+     * <li> all distances have been found
+     * </ul>
+     * 
+     * @param source    the vertex from which distances are to be measured
+     * @param numDests  the number of distances to measure
+     * @param targets   the set of vertices to which distances are to be measured
+     * @param regular   boolean is true if we want regular SP dijkstra. False for MT.
+     */
+    private LinkedHashMap<V,Number> singleSourceShortestPath(V source, Collection<V> targets, int numDests, boolean regular)
+    {
+        SourceData sd = getSourceData(source);
+
+        Set<V> to_get = new HashSet<V>();
+        if (targets != null) {
+            to_get.addAll(targets);
+            Set<V> existing_dists = sd.distances.keySet();
+            for(V o : targets) {
+                if (existing_dists.contains(o))
+                    to_get.remove(o);
+            }
+        }
+        
+        // if we've exceeded the max distance or max # of distances we're willing to calculate, or
+        // if we already have all the distances we need, 
+        // terminate
+        if (sd.reached_max ||
+            (targets != null && to_get.isEmpty()) ||
+            (sd.distances.size() >= numDests))
+        {
+            return sd.distances;
+        }
+        
+        while (!sd.unknownVertices.isEmpty() && (sd.distances.size() < numDests || !to_get.isEmpty()))
+        {
+            Map.Entry<V,Number> p = sd.getNextVertex();
+            V v = p.getKey();
+            double v_dist = p.getValue().doubleValue();
+            to_get.remove(v);
+            if (v_dist > this.max_distance) 
+            {
+                // we're done; put this vertex back in so that we're not including
+                // a distance beyond what we specified
+                sd.restoreVertex(v, v_dist);
+                sd.reached_max = true;
+                break;
+            }
+            sd.dist_reached = v_dist;
+
+            if (sd.distances.size() >= this.max_targets)
+            {
+                sd.reached_max = true;
+                break;
+            }
+            
+            for (E e : getEdgesToCheck(v) )
+            {
+                for (V w : g.getIncidentVertices(e))
+                {
+                    if (!sd.distances.containsKey(w))
+                    {
+                        double edge_weight = nev.transform(e).doubleValue();
+                        if (edge_weight < 0)
+                            throw new IllegalArgumentException("Edges weights must be non-negative");
+                        double new_dist;
+                        if (regular == true) {
+                          new_dist = v_dist + edge_weight;
+                        } else {
+                          if (v_dist <= edge_weight) {
+                            new_dist = edge_weight;
+                          } else {
+                            new_dist = v_dist;
+                          }
+                        }
+                        if (!sd.estimatedDistances.containsKey(w))
+                        {
+                            sd.createRecord(w, e, new_dist);
+                        }
+                        else
+                        {
+                            double w_dist = ((Double)sd.estimatedDistances.get(w)).doubleValue();
+                            if (new_dist < w_dist) // update tentative distance & path for w
+                                sd.update(w, e, new_dist);
+                        }
+                    }
+                }
+            }
+        }
+        return sd.distances;
+    }
+    
+    /**
+     * Implements Dijkstra's single-source shortest-path algorithm for
+     * weighted graphs.  Uses a <code>MapBinaryHeap</code> as the priority queue, 
+     * which gives this algorithm a time complexity of O(m lg n) (m = # of edges, n = 
+     * # of vertices).
+     * This algorithm will terminate when any of the following have occurred (in order
+     * of priority):
+     * <ul>
+     * <li> the distance to the specified target (if any) has been found
+     * <li> no more vertices are reachable 
+     * <li> the specified # of distances have been found, or the maximum distance 
+     * desired has been exceeded
+     * <li> all distances have been found
+     * </ul>
+     * 
+     * @param source    the vertex from which distances are to be measured
+     * @param numDests  the number of distances to measure
+     * @param targets   the set of vertices to which distances are to be measured
+     */
+    protected LinkedHashMap<V,Number> singleSourceShortestPath(V source, Collection<V> targets, int numDests)
+    {
+        return singleSourceShortestPath(source, targets, numDests, true);
+    }
+
+    /**
+     * Implements Dijkstra's single-source shortest-path algorithm for
+     * weighted graphs.  Uses a <code>MapBinaryHeap</code> as the priority queue, 
+     * which gives this algorithm a time complexity of O(m lg n) (m = # of edges, n = 
+     * # of vertices).
+     * This algorithm will terminate when any of the following have occurred (in order
+     * of priority):
+     * <ul>
+     * <li> the distance to the specified target (if any) has been found
+     * <li> no more vertices are reachable 
+     * <li> the specified # of distances have been found, or the maximum distance 
+     * desired has been exceeded
+     * <li> all distances have been found
+     * </ul>
+     * 
+     * @param source    the vertex from which distances are to be measured
+     * @param numDests  the number of distances to measure
+     * @param targets   the set of vertices to which distances are to be measured
+     */
+    protected LinkedHashMap<V,Number> singleSourceMaxThroughputPath(V source, Collection<V> targets, int numDests)
+    {
+        return singleSourceShortestPath(source, targets, numDests, false);
+    }
+
+    protected SourceData getSourceData(V source)
+    {
+        SourceData sd = sourceMap.get(source);
+        if (sd == null)
+            sd = new SourceData(source);
+        return sd;
+    }
+    
+    /**
+     * Returns the set of edges incident to <code>v</code> that should be tested.
+     * By default, this is the set of outgoing edges for instances of <code>Graph</code>,
+     * the set of incident edges for instances of <code>Hypergraph</code>,
+     * and is otherwise undefined.
+     */
+    protected Collection<E> getEdgesToCheck(V v)
+    {
+        if (g instanceof Graph)
+            return ((Graph<V,E>)g).getOutEdges(v);
+        else
+            return g.getIncidentEdges(v);
+
+    }
+
+    
+    /**
+     * Returns the length of a shortest path from the source to the target vertex,
+     * or null if the target is not reachable from the source.
+     * If either vertex is not in the graph for which this instance
+     * was created, throws <code>IllegalArgumentException</code>.
+     * 
+     * @see #getDistanceMap(Object)
+     * @see #getDistanceMap(Object,int)
+     */
+    public Number getDistance(V source, V target)
+    {
+        if (g.containsVertex(target) == false)
+            throw new IllegalArgumentException("Specified target vertex " + 
+                    target + " is not part of graph " + g);
+        if (g.containsVertex(source) == false)
+            throw new IllegalArgumentException("Specified source vertex " + 
+                    source + " is not part of graph " + g);
+        
+        Set<V> targets = new HashSet<V>();
+        targets.add(target);
+        Map<V,Number> distanceMap = getDistanceMap(source, targets);
+        return distanceMap.get(target);
+    }
+    
+
+    /**
+     * Returns a {@code Map} from each element {@code t} of {@code targets} to the 
+     * shortest-path distance from {@code source} to {@code t}. 
+     */
+    public Map<V,Number> getDistanceMap(V source, Collection<V> targets)
+    {
+       if (g.containsVertex(source) == false)
+            throw new IllegalArgumentException("Specified source vertex " + 
+                    source + " is not part of graph " + g);
+       if (targets.size() > max_targets)
+            throw new IllegalArgumentException("size of target set exceeds maximum " +
+                    "number of targets allowed: " + this.max_targets);
+        
+        Map<V,Number> distanceMap = 
+               singleSourceShortestPath(source, targets, 
+                               Math.min(g.getVertexCount(), max_targets));
+        if (!cached)
+            reset(source);
+        
+        return distanceMap;
+    }
+    
+    /**
+     * <p>Returns a <code>LinkedHashMap</code> which maps each vertex 
+     * in the graph (including the <code>source</code> vertex) 
+     * to its distance from the <code>source</code> vertex.
+     * The map's iterator will return the elements in order of 
+     * increasing distance from <code>source</code>.</p>
+     * 
+     * <p>The size of the map returned will be the number of 
+     * vertices reachable from <code>source</code>.</p>
+     * 
+     * @see #getDistanceMap(Object,int)
+     * @see #getDistance(Object,Object)
+     * @param source    the vertex from which distances are measured
+     */
+    public Map<V,Number> getDistanceMap(V source)
+    {
+        return getDistanceMap(source, Math.min(g.getVertexCount(), max_targets));
+    }
+    
+
+
+    /**
+     * <p>Returns a <code>LinkedHashMap</code> which maps each of the closest 
+     * <code>numDist</code> vertices to the <code>source</code> vertex 
+     * in the graph (including the <code>source</code> vertex) 
+     * to its distance from the <code>source</code> vertex.  Throws 
+     * an <code>IllegalArgumentException</code> if <code>source</code>
+     * is not in this instance's graph, or if <code>numDests</code> is 
+     * either less than 1 or greater than the number of vertices in the 
+     * graph.</p>
+     * 
+     * <p>The size of the map returned will be the smaller of 
+     * <code>numDests</code> and the number of vertices reachable from
+     * <code>source</code>. 
+     * 
+     * @see #getDistanceMap(Object)
+     * @see #getDistance(Object,Object)
+     * @param source    the vertex from which distances are measured
+     * @param numDests  the number of vertices for which to measure distances
+     */
+    public LinkedHashMap<V,Number> getDistanceMap(V source, int numDests)
+    {
+
+       if(g.getVertices().contains(source) == false) {
+            throw new IllegalArgumentException("Specified source vertex " + 
+                    source + " is not part of graph " + g);
+               
+       }
+        if (numDests < 1 || numDests > g.getVertexCount())
+            throw new IllegalArgumentException("numDests must be >= 1 " + 
+                "and <= g.numVertices()");
+
+        if (numDests > max_targets)
+            throw new IllegalArgumentException("numDests must be <= the maximum " +
+                    "number of targets allowed: " + this.max_targets);
+            
+        LinkedHashMap<V,Number> distanceMap = 
+               singleSourceShortestPath(source, null, numDests);
+                
+        if (!cached)
+            reset(source);
+        
+        return distanceMap;        
+    }
+    
+    /**
+     * Allows the user to specify the maximum distance that this instance will calculate.
+     * Any vertices past this distance will effectively be unreachable from the source, in
+     * the sense that the algorithm will not calculate the distance to any vertices which
+     * are farther away than this distance.  A negative value for <code>max_dist</code> 
+     * will ensure that no further distances are calculated.
+     * 
+     * <p>This can be useful for limiting the amount of time and space used by this algorithm
+     * if the graph is very large.</p>
+     * 
+     * <p>Note: if this instance has already calculated distances greater than <code>max_dist</code>,
+     * and the results are cached, those results will still be valid and available; this limit
+     * applies only to subsequent distance calculations.</p>
+     * @see #setMaxTargets(int)
+     */
+    public void setMaxDistance(double max_dist)
+    {
+        this.max_distance = max_dist;
+        for (V v : sourceMap.keySet())
+        {
+            SourceData sd = sourceMap.get(v);
+            sd.reached_max = (this.max_distance <= sd.dist_reached) || (sd.distances.size() >= max_targets);
+        }
+    }
+       
+    /**
+     * Allows the user to specify the maximum number of target vertices per source vertex 
+     * for which this instance will calculate distances.  Once this threshold is reached, 
+     * any further vertices will effectively be unreachable from the source, in
+     * the sense that the algorithm will not calculate the distance to any more vertices.  
+     * A negative value for <code>max_targets</code> will ensure that no further distances are calculated.
+     * 
+     * <p>This can be useful for limiting the amount of time and space used by this algorithm
+     * if the graph is very large.</p>
+     * 
+     * <p>Note: if this instance has already calculated distances to a greater number of 
+     * targets than <code>max_targets</code>, and the results are cached, those results 
+     * will still be valid and available; this limit applies only to subsequent distance 
+     * calculations.</p>
+     * @see #setMaxDistance(double)
+     */
+    public void setMaxTargets(int max_targets)
+    {
+        this.max_targets = max_targets;
+        for (V v : sourceMap.keySet())
+        {
+            SourceData sd = sourceMap.get(v);
+            sd.reached_max = (this.max_distance <= sd.dist_reached) || (sd.distances.size() >= max_targets);
+        }
+    }
+    
+    /**
+     * Clears all stored distances for this instance.  
+     * Should be called whenever the graph is modified (edge weights 
+     * changed or edges added/removed).  If the user knows that
+     * some currently calculated distances are unaffected by a
+     * change, <code>reset(V)</code> may be appropriate instead.
+     * 
+     * @see #reset(Object)
+     */
+    public void reset()
+    {
+        sourceMap = new HashMap<V,SourceData>();
+    }
+        
+    /**
+     * Specifies whether or not this instance of <code>DijkstraShortestPath</code>
+     * should cache its results (final and partial) for future reference.
+     * 
+     * @param enable    <code>true</code> if the results are to be cached, and
+     *                  <code>false</code> otherwise
+     */
+    public void enableCaching(boolean enable)
+    {
+        this.cached = enable;
+    }
+    
+    /**
+     * Clears all stored distances for the specified source vertex 
+     * <code>source</code>.  Should be called whenever the stored distances
+     * from this vertex are invalidated by changes to the graph.
+     * 
+     * @see #reset()
+     */
+    public void reset(V source)
+    {
+        sourceMap.put(source, null);
+    }
+
+    /**
+     * Compares according to distances, so that the BinaryHeap knows how to 
+     * order the tree.  
+     */
+    protected static class VertexComparator<V> implements Comparator<V>
+    {
+        private Map<V,Number> distances;
+        
+        protected VertexComparator(Map<V,Number> distances)
+        {
+            this.distances = distances;
+        }
+
+        public int compare(V o1, V o2)
+        {
+            return ((Double) distances.get(o1)).compareTo((Double) distances.get(o2));
+        }
+    }
+    
+    /**
+     * For a given source vertex, holds the estimated and final distances, 
+     * tentative and final assignments of incoming edges on the shortest path from
+     * the source vertex, and a priority queue (ordered by estimated distance)
+     * of the vertices for which distances are unknown.
+     * 
+     * @author Joshua O'Madadhain
+     */
+    protected class SourceData
+    {
+        protected LinkedHashMap<V,Number> distances;
+        protected Map<V,Number> estimatedDistances;
+        protected MapBinaryHeap<V> unknownVertices;
+        protected boolean reached_max = false;
+        protected double dist_reached = 0;
+
+        protected SourceData(V source)
+        {
+            distances = new LinkedHashMap<V,Number>();
+            estimatedDistances = new HashMap<V,Number>();
+            unknownVertices = new MapBinaryHeap<V>(new VertexComparator<V>(estimatedDistances));
+            
+            sourceMap.put(source, this);
+            
+            // initialize priority queue
+            estimatedDistances.put(source, new Double(0)); // distance from source to itself is 0
+            unknownVertices.add(source);
+            reached_max = false;
+            dist_reached = 0;
+        }
+        
+        protected Map.Entry<V,Number> getNextVertex()
+        {
+            V v = unknownVertices.remove();
+            Double dist = (Double)estimatedDistances.remove(v);
+            distances.put(v, dist);
+            return new BasicMapEntry<V,Number>(v, dist);
+        }
+        
+        protected void update(V dest, E tentative_edge, double new_dist)
+        {
+            estimatedDistances.put(dest, new_dist);
+            unknownVertices.update(dest);
+        }
+        
+        protected void createRecord(V w, E e, double new_dist)
+        {
+            estimatedDistances.put(w, new_dist);
+            unknownVertices.add(w);
+        }
+        
+        protected void restoreVertex(V v, double dist) 
+        {
+            estimatedDistances.put(v, dist);
+            unknownVertices.add(v);
+            distances.remove(v);
+        }
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/DijkstraShortestPath.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/DijkstraShortestPath.java
new file mode 100644 (file)
index 0000000..05c008d
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.shortestpath;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * <p>Calculates distances and shortest paths using Dijkstra's   
+ * single-source-shortest-path algorithm.  This is a lightweight
+ * extension of <code>DijkstraDistance</code> that also stores
+ * path information, so that the shortest paths can be reconstructed.</p>
+ * 
+ * <p> The elements in the maps returned by 
+ * <code>getIncomingEdgeMap</code> are ordered (that is, returned 
+ * by the iterator) by nondecreasing distance from <code>source</code>.</p>
+ * 
+ * @author Joshua O'Madadhain
+ * @author Tom Nelson converted to jung2
+ * @see DijkstraDistance
+ */
+public class DijkstraShortestPath<V,E> extends DijkstraDistance<V,E> implements ShortestPath<V,E>
+{
+    /**
+     * <p>Creates an instance of <code>DijkstraShortestPath</code> for 
+     * the specified graph and the specified method of extracting weights 
+     * from edges, which caches results locally if and only if 
+     * <code>cached</code> is <code>true</code>.
+     * 
+     * @param g     the graph on which distances will be calculated
+     * @param nev   the class responsible for returning weights for edges
+     * @param cached    specifies whether the results are to be cached
+     */
+    public DijkstraShortestPath(Graph<V,E> g, Transformer<E, ? extends Number> nev, boolean cached)
+    {
+        super(g, nev, cached);
+    }
+    
+    /**
+     * <p>Creates an instance of <code>DijkstraShortestPath</code> for 
+     * the specified graph and the specified method of extracting weights 
+     * from edges, which caches results locally.
+     * 
+     * @param g     the graph on which distances will be calculated
+     * @param nev   the class responsible for returning weights for edges
+     */
+    public DijkstraShortestPath(Graph<V,E> g, Transformer<E, ? extends Number> nev)
+    {
+        super(g, nev);
+    }
+    
+    /**
+     * <p>Creates an instance of <code>DijkstraShortestPath</code> for 
+     * the specified unweighted graph (that is, all weights 1) which
+     * caches results locally.
+     * 
+     * @param g     the graph on which distances will be calculated
+     */ 
+    public DijkstraShortestPath(Graph<V,E> g)
+    {
+        super(g);
+    }
+
+    /**
+     * <p>Creates an instance of <code>DijkstraShortestPath</code> for 
+     * the specified unweighted graph (that is, all weights 1) which
+     * caches results locally.
+     * 
+     * @param g     the graph on which distances will be calculated
+     * @param cached    specifies whether the results are to be cached
+     */ 
+    public DijkstraShortestPath(Graph<V,E> g, boolean cached)
+    {
+        super(g, cached);
+    }
+    
+    @Override
+    protected SourceData getSourceData(V source)
+    {
+        SourceData sd = sourceMap.get(source);
+        if (sd == null)
+            sd = new SourcePathData(source);
+        return sd;
+    }
+    
+    /**
+     * <p>Returns the last edge on a shortest path from <code>source</code>
+     * to <code>target</code>, or null if <code>target</code> is not 
+     * reachable from <code>source</code>.</p>
+     * 
+     * <p>If either vertex is not in the graph for which this instance
+     * was created, throws <code>IllegalArgumentException</code>.</p>
+     */
+       public E getIncomingEdge(V source, V target)
+       {
+        if (!g.containsVertex(source))
+            throw new IllegalArgumentException("Specified source vertex " + 
+                    source + " is not part of graph " + g);
+        
+        if (!g.containsVertex(target))
+            throw new IllegalArgumentException("Specified target vertex " + 
+                    target + " is not part of graph " + g);
+
+        Set<V> targets = new HashSet<V>();
+        targets.add(target);
+        singleSourceShortestPath(source, targets, g.getVertexCount());
+        Map<V,E> incomingEdgeMap = 
+            ((SourcePathData)sourceMap.get(source)).incomingEdges;
+        E incomingEdge = incomingEdgeMap.get(target);
+        
+        if (!cached)
+            reset(source);
+        
+        return incomingEdge;
+       }
+
+    /**
+     * <p>Returns a <code>LinkedHashMap</code> which maps each vertex 
+     * in the graph (including the <code>source</code> vertex) 
+     * to the last edge on the shortest path from the 
+     * <code>source</code> vertex.
+     * The map's iterator will return the elements in order of 
+     * increasing distance from <code>source</code>.</p>
+     * 
+     * @see DijkstraDistance#getDistanceMap(Object,int)
+     * @see DijkstraDistance#getDistance(Object,Object)
+     * @param source    the vertex from which distances are measured
+     */
+    public Map<V,E> getIncomingEdgeMap(V source)
+       {
+               return getIncomingEdgeMap(source, g.getVertexCount());
+       }
+
+    /**
+     * Returns a <code>List</code> of the edges on the shortest path from 
+     * <code>source</code> to <code>target</code>, in order of their
+     * occurrence on this path.  
+     * If either vertex is not in the graph for which this instance
+     * was created, throws <code>IllegalArgumentException</code>.
+     */
+       private List<E> getPath(V source, V target, boolean spath)
+       {
+               if(!g.containsVertex(source)) 
+            throw new IllegalArgumentException("Specified source vertex " + 
+                    source + " is not part of graph " + g);
+        
+               if(!g.containsVertex(target)) 
+            throw new IllegalArgumentException("Specified target vertex " + 
+                    target + " is not part of graph " + g);
+        
+        LinkedList<E> path = new LinkedList<E>();
+
+        // collect path data; must use internal method rather than
+        // calling getIncomingEdge() because getIncomingEdge() may
+        // wipe out results if results are not cached
+        Set<V> targets = new HashSet<V>();
+        targets.add(target);
+        if (spath == true) {
+          singleSourceShortestPath(source, targets, g.getVertexCount());
+        } else {
+          singleSourceMaxThroughputPath(source, targets, g.getVertexCount());
+        }
+        Map<V,E> incomingEdges = 
+            ((SourcePathData)sourceMap.get(source)).incomingEdges;
+        
+        if (incomingEdges.isEmpty() || incomingEdges.get(target) == null)
+            return path;
+        V current = target;
+        while (!current.equals(source))
+        {
+            E incoming = incomingEdges.get(current);
+            path.addFirst(incoming);
+            current = ((Graph<V,E>)g).getOpposite(current, incoming);
+        }
+               return path;
+       }
+
+    /**
+     * Returns a <code>List</code> of the edges on the shortest path from 
+     * <code>source</code> to <code>target</code>, in order of their
+     * occurrence on this path.  
+     * If either vertex is not in the graph for which this instance
+     * was created, throws <code>IllegalArgumentException</code>.
+     */
+       public List<E> getPath(V source, V target)
+       {
+
+               return getPath(source,target, true);
+       }
+
+    /**
+     * Returns a <code>List</code> of the edges on the Max Througput Shortest
+     * path from  <code>source</code> to <code>target</code>, in order of their
+     * their occurrence on this path.
+     * Important - Transformer fn should return the appropriate edge weight
+     * for this API to return the Path Correctly.
+     * If either vertex is not in the graph for which this instance
+     * was created, throws <code>IllegalArgumentException</code>.
+     */
+       public List<E> getMaxThroughputPath(V source, V target)
+       {
+
+               return getPath(source,target, false);
+       }
+
+    
+    /**
+     * <p>Returns a <code>LinkedHashMap</code> which maps each of the closest 
+     * <code>numDist</code> vertices to the <code>source</code> vertex 
+     * in the graph (including the <code>source</code> vertex) 
+     * to the incoming edge along the path from that vertex.  Throws 
+     * an <code>IllegalArgumentException</code> if <code>source</code>
+     * is not in this instance's graph, or if <code>numDests</code> is 
+     * either less than 1 or greater than the number of vertices in the 
+     * graph.
+     * 
+     * @see #getIncomingEdgeMap(Object)
+     * @see #getPath(Object,Object)
+     * @param source    the vertex from which distances are measured
+     * @param numDests  the number of vertices for which to measure distances
+     */
+       public LinkedHashMap<V,E> getIncomingEdgeMap(V source, int numDests)
+       {
+        if (g.getVertices().contains(source) == false)
+            throw new IllegalArgumentException("Specified source vertex " + 
+                    source + " is not part of graph " + g);
+
+        if (numDests < 1 || numDests > g.getVertexCount())
+            throw new IllegalArgumentException("numDests must be >= 1 " + 
+            "and <= g.numVertices()");
+
+        singleSourceShortestPath(source, null, numDests);
+        
+        LinkedHashMap<V,E> incomingEdgeMap = 
+            ((SourcePathData)sourceMap.get(source)).incomingEdges;
+        
+        if (!cached)
+            reset(source);
+        
+        return incomingEdgeMap;        
+       }
+     
+    
+    /**
+     * For a given source vertex, holds the estimated and final distances, 
+     * tentative and final assignments of incoming edges on the shortest path from
+     * the source vertex, and a priority queue (ordered by estimaed distance)
+     * of the vertices for which distances are unknown.
+     * 
+     * @author Joshua O'Madadhain
+     */
+    protected class SourcePathData extends SourceData
+    {
+        protected Map<V,E> tentativeIncomingEdges;
+               protected LinkedHashMap<V,E> incomingEdges;
+
+               protected SourcePathData(V source)
+               {
+            super(source);
+            incomingEdges = new LinkedHashMap<V,E>();
+            tentativeIncomingEdges = new HashMap<V,E>();
+               }
+        
+        @Override
+        public void update(V dest, E tentative_edge, double new_dist)
+        {
+            super.update(dest, tentative_edge, new_dist);
+            tentativeIncomingEdges.put(dest, tentative_edge);
+        }
+        
+        @Override
+        public Map.Entry<V,Number> getNextVertex()
+        {
+            Map.Entry<V,Number> p = super.getNextVertex();
+            V v = p.getKey();
+            E incoming = tentativeIncomingEdges.remove(v);
+            incomingEdges.put(v, incoming);
+            return p;
+        }
+        
+        @Override
+        public void restoreVertex(V v, double dist)
+        {
+            super.restoreVertex(v, dist);
+            E incoming = incomingEdges.get(v);
+            tentativeIncomingEdges.put(v, incoming);
+        }
+        
+        @Override
+        public void createRecord(V w, E e, double new_dist)
+        {
+            super.createRecord(w, e, new_dist);
+            tentativeIncomingEdges.put(w, e);
+        }
+       
+    }
+
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/Distance.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/Distance.java
new file mode 100644 (file)
index 0000000..85820d1
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Created on Apr 2, 2004
+ *
+ * Copyright (c) 2004, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.shortestpath;
+
+import java.util.Map;
+
+
+/**
+ * An interface for classes which calculate the distance between
+ * one vertex and another.
+ * 
+ * @author Joshua O'Madadhain
+ */
+public interface Distance<V>
+{
+    /**
+     * Returns the distance from the <code>source</code> vertex 
+     * to the <code>target</code> vertex.  If <code>target</code> 
+     * is not reachable from <code>source</code>, returns null.
+     */ 
+     Number getDistance(V source, V target);
+
+    /**
+     * <p>Returns a <code>Map</code> which maps each vertex 
+     * in the graph (including the <code>source</code> vertex) 
+     * to its distance (represented as a Number) 
+     * from <code>source</code>.  If any vertex 
+     * is not reachable from <code>source</code>, no 
+     * distance is stored for that vertex.
+     */
+     Map<V,Number> getDistanceMap(V source);
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/DistanceStatistics.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/DistanceStatistics.java
new file mode 100644 (file)
index 0000000..f0f20a3
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.shortestpath;
+import java.util.Collection;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.scoring.ClosenessCentrality;
+import edu.uci.ics.jung.algorithms.scoring.util.VertexScoreTransformer;
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * Statistics relating to vertex-vertex distances in a graph.
+ * 
+ * <p>Formerly known as <code>GraphStatistics</code> in JUNG 1.x.</p>
+ * 
+ * @author Scott White
+ * @author Joshua O'Madadhain
+ */
+public class DistanceStatistics 
+{
+    /**
+     * For each vertex <code>v</code> in <code>graph</code>, 
+     * calculates the average shortest path length from <code>v</code> 
+     * to all other vertices in <code>graph</code> using the metric 
+     * specified by <code>d</code>, and returns the results in a
+     * <code>Map</code> from vertices to <code>Double</code> values.
+     * If there exists an ordered pair <code>&lt;u,v&gt;</code>
+     * for which <code>d.getDistance(u,v)</code> returns <code>null</code>,
+     * then the average distance value for <code>u</code> will be stored
+     * as <code>Double.POSITIVE_INFINITY</code>).
+     * 
+     * <p>Does not include self-distances (path lengths from <code>v</code>
+     * to <code>v</code>).
+     * 
+     * <p>To calculate the average distances, ignoring edge weights if any:
+     * <pre>
+     * Map distances = DistanceStatistics.averageDistances(g, new UnweightedShortestPath(g));
+     * </pre>
+     * To calculate the average distances respecting edge weights:
+     * <pre>
+     * DijkstraShortestPath dsp = new DijkstraShortestPath(g, nev);
+     * Map distances = DistanceStatistics.averageDistances(g, dsp);
+     * </pre>
+     * where <code>nev</code> is an instance of <code>Transformer</code> that
+     * is used to fetch the weight for each edge.
+     * 
+     * @see edu.uci.ics.jung.algorithms.shortestpath.UnweightedShortestPath
+     * @see edu.uci.ics.jung.algorithms.shortestpath.DijkstraDistance
+     */
+    public static <V,E> Transformer<V,Double> averageDistances(Hypergraph<V,E> graph, Distance<V> d)
+    {
+       final ClosenessCentrality<V,E> cc = new ClosenessCentrality<V,E>(graph, d);
+       return new VertexScoreTransformer<V, Double>(cc);
+    }
+    
+    /**
+     * For each vertex <code>v</code> in <code>g</code>, 
+     * calculates the average shortest path length from <code>v</code> 
+     * to all other vertices in <code>g</code>, ignoring edge weights.
+     * @see #diameter(Hypergraph)
+     * @see edu.uci.ics.jung.algorithms.scoring.ClosenessCentrality
+     */
+    public static <V,E> Transformer<V, Double> averageDistances(Hypergraph<V,E> g)
+    {
+       final ClosenessCentrality<V,E> cc = new ClosenessCentrality<V,E>(g, 
+                       new UnweightedShortestPath<V,E>(g));
+        return new VertexScoreTransformer<V, Double>(cc);
+    }
+    
+    /**
+     * Returns the diameter of <code>g</code> using the metric 
+     * specified by <code>d</code>.  The diameter is defined to be
+     * the maximum, over all pairs of vertices <code>u,v</code>,
+     * of the length of the shortest path from <code>u</code> to 
+     * <code>v</code>.  If the graph is disconnected (that is, not 
+     * all pairs of vertices are reachable from one another), the
+     * value returned will depend on <code>use_max</code>:  
+     * if <code>use_max == true</code>, the value returned
+     * will be the the maximum shortest path length over all pairs of <b>connected</b> 
+     * vertices; otherwise it will be <code>Double.POSITIVE_INFINITY</code>.
+     */
+    public static <V, E> double diameter(Hypergraph<V,E> g, Distance<V> d, boolean use_max)
+    {
+        double diameter = 0;
+        Collection<V> vertices = g.getVertices();
+        for(V v : vertices) {
+            for(V w : vertices) {
+
+                if (v.equals(w) == false) // don't include self-distances
+                {
+                    Number dist = d.getDistance(v, w);
+                    if (dist == null)
+                    {
+                        if (!use_max)
+                            return Double.POSITIVE_INFINITY;
+                    }
+                    else
+                        diameter = Math.max(diameter, dist.doubleValue());
+                }
+            }
+        }
+        return diameter;
+    }
+    
+    /**
+     * Returns the diameter of <code>g</code> using the metric 
+     * specified by <code>d</code>.  The diameter is defined to be
+     * the maximum, over all pairs of vertices <code>u,v</code>,
+     * of the length of the shortest path from <code>u</code> to 
+     * <code>v</code>, or <code>Double.POSITIVE_INFINITY</code>
+     * if any of these distances do not exist.
+     * @see #diameter(Hypergraph, Distance, boolean)
+     */
+    public static <V, E> double diameter(Hypergraph<V,E> g, Distance<V> d)
+    {
+        return diameter(g, d, false);
+    }
+    
+    /**
+     * Returns the diameter of <code>g</code>, ignoring edge weights.
+     * @see #diameter(Hypergraph, Distance, boolean)
+     */
+    public static <V, E> double diameter(Hypergraph<V,E> g)
+    {
+        return diameter(g, new UnweightedShortestPath<V,E>(g));
+    }
+    
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/MinimumSpanningForest.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/MinimumSpanningForest.java
new file mode 100644 (file)
index 0000000..18cb0fe
--- /dev/null
@@ -0,0 +1,165 @@
+package edu.uci.ics.jung.algorithms.shortestpath;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections15.Factory;
+import org.apache.commons.collections15.functors.ConstantTransformer;
+import org.apache.commons.collections15.map.LazyMap;
+
+import edu.uci.ics.jung.graph.Forest;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.EdgeType;
+import edu.uci.ics.jung.graph.util.Pair;
+
+/**
+ * For the input Graph, creates a MinimumSpanningTree
+ * using a variation of Prim's algorithm.
+ * 
+ * @author Tom Nelson - tomnelson@dev.java.net
+ *
+ * @param <V>
+ * @param <E>
+ */
+public class MinimumSpanningForest<V,E> {
+       
+       protected Graph<V,E> graph;
+       protected Forest<V,E> forest;
+       protected Map<E,Double> weights;
+       
+       /**
+        * Creates a Forest from the supplied Graph and supplied Factory, which
+        * is used to create a new, empty Forest. If non-null, the supplied root
+        * will be used as the root of the tree/forest. If the supplied root is
+        * null, or not present in the Graph, then an arbitrary Graph vertex
+        * will be selected as the root.
+        * If the Minimum Spanning Tree does not include all vertices of the
+        * Graph, then a leftover vertex is selected as a root, and another
+        * tree is created.
+        * @param graph the input graph
+        * @param factory the factory to use to create the new forest
+        * @param root the vertex of the graph to be used as the root of the forest 
+        * @param weights edge weights
+        */
+       public MinimumSpanningForest(Graph<V, E> graph, Factory<Forest<V,E>> factory, 
+                       V root, Map<E, Double> weights) {
+               this(graph, factory.create(), root, weights);
+       }
+       
+       /**
+        * Creates a minimum spanning forest from the supplied graph, populating the
+        * supplied Forest, which must be empty. 
+        * If the supplied root is null, or not present in the Graph,
+        * then an arbitrary Graph vertex will be selected as the root.
+        * If the Minimum Spanning Tree does not include all vertices of the
+        * Graph, then a leftover vertex is selected as a root, and another
+        * tree is created
+        * @param graph the Graph to find MST in
+        * @param forest the Forest to populate. Must be empty
+        * @param root first Tree root, may be null
+        * @param weights edge weights, may be null
+        */
+       public MinimumSpanningForest(Graph<V, E> graph, Forest<V,E> forest, 
+                       V root, Map<E, Double> weights) {
+               
+               if(forest.getVertexCount() != 0) {
+                       throw new IllegalArgumentException("Supplied Forest must be empty");
+               }
+               this.graph = graph;
+               this.forest = forest;
+               if(weights != null) {
+                       this.weights = weights;
+               }
+               Set<E> unfinishedEdges = new HashSet<E>(graph.getEdges());
+               if(graph.getVertices().contains(root)) {
+                       this.forest.addVertex(root);
+               }
+               updateForest(forest.getVertices(), unfinishedEdges);
+       }
+       
+    /**
+     * Creates a minimum spanning forest from the supplied graph, populating the
+     * supplied Forest, which must be empty. 
+     * If the supplied root is null, or not present in the Graph,
+     * then an arbitrary Graph vertex will be selected as the root.
+     * If the Minimum Spanning Tree does not include all vertices of the
+     * Graph, then a leftover vertex is selected as a root, and another
+     * tree is created
+     * @param graph the Graph to find MST in
+     * @param forest the Forest to populate. Must be empty
+     * @param root first Tree root, may be null
+     */
+    @SuppressWarnings("unchecked")
+    public MinimumSpanningForest(Graph<V, E> graph, Forest<V,E> forest, 
+            V root) {
+        
+        if(forest.getVertexCount() != 0) {
+            throw new IllegalArgumentException("Supplied Forest must be empty");
+        }
+        this.graph = graph;
+        this.forest = forest;
+        this.weights = LazyMap.decorate(new HashMap<E,Double>(),
+                new ConstantTransformer(1.0));
+        Set<E> unfinishedEdges = new HashSet<E>(graph.getEdges());
+        if(graph.getVertices().contains(root)) {
+            this.forest.addVertex(root);
+        }
+        updateForest(forest.getVertices(), unfinishedEdges);
+    }
+       
+       /**
+        * Returns the generated forest.
+        */
+       public Forest<V,E> getForest() {
+               return forest;
+       }
+       
+       protected void updateForest(Collection<V> tv, Collection<E> unfinishedEdges) {
+               double minCost = Double.MAX_VALUE;
+               E nextEdge = null;
+               V nextVertex = null;
+               V currentVertex = null;
+               for(E e : unfinishedEdges) {
+                       
+                       if(forest.getEdges().contains(e)) continue;
+                       // find the lowest cost edge, get its opposite endpoint,
+                       // and then update forest from its Successors
+                       Pair<V> endpoints = graph.getEndpoints(e);
+                       V first = endpoints.getFirst();
+                       V second = endpoints.getSecond();
+                       if(tv.contains(first) == true && tv.contains(second) == false) {
+                               if(weights.get(e) < minCost) {
+                                       minCost = weights.get(e);
+                                       nextEdge = e;
+                                       currentVertex = first;
+                                       nextVertex = second;
+                               }
+                       }
+                       if(graph.getEdgeType(e) == EdgeType.UNDIRECTED &&
+                                       tv.contains(second) == true && tv.contains(first) == false) {
+                               if(weights.get(e) < minCost) {
+                                       minCost = weights.get(e);
+                                       nextEdge = e;
+                                       currentVertex = second;
+                                       nextVertex = first;
+                               }
+                       }
+               }
+               
+               if(nextVertex != null && nextEdge != null) {
+                       unfinishedEdges.remove(nextEdge);
+                       forest.addEdge(nextEdge, currentVertex, nextVertex);
+                       updateForest(forest.getVertices(), unfinishedEdges);
+               }
+               Collection<V> leftovers = new HashSet<V>(graph.getVertices());
+               leftovers.removeAll(forest.getVertices());
+               if(leftovers.size() > 0) {
+                       V anotherRoot = leftovers.iterator().next();
+                       forest.addVertex(anotherRoot);
+                       updateForest(forest.getVertices(), unfinishedEdges);
+               }
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/MinimumSpanningForest2.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/MinimumSpanningForest2.java
new file mode 100644 (file)
index 0000000..13e800c
--- /dev/null
@@ -0,0 +1,104 @@
+package edu.uci.ics.jung.algorithms.shortestpath;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.apache.commons.collections15.Factory;
+import org.apache.commons.collections15.Transformer;
+import org.apache.commons.collections15.functors.ConstantTransformer;
+
+import edu.uci.ics.jung.algorithms.cluster.WeakComponentClusterer;
+import edu.uci.ics.jung.algorithms.filters.FilterUtils;
+import edu.uci.ics.jung.graph.Forest;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.Tree;
+import edu.uci.ics.jung.graph.util.TreeUtils;
+
+/**
+ * For the input Graph, creates a MinimumSpanningTree
+ * using a variation of Prim's algorithm.
+ * 
+ * @author Tom Nelson - tomnelson@dev.java.net
+ *
+ * @param <V>
+ * @param <E>
+ */
+@SuppressWarnings("unchecked")
+public class MinimumSpanningForest2<V,E> {
+       
+       protected Graph<V,E> graph;
+       protected Forest<V,E> forest;
+       protected Transformer<E,Double> weights = 
+               (Transformer<E,Double>)new ConstantTransformer<Double>(1.0);
+       
+       /**
+        * create a Forest from the supplied Graph and supplied Factory, which
+        * is used to create a new, empty Forest. If non-null, the supplied root
+        * will be used as the root of the tree/forest. If the supplied root is
+        * null, or not present in the Graph, then an arbitary Graph vertex
+        * will be selected as the root.
+        * If the Minimum Spanning Tree does not include all vertices of the
+        * Graph, then a leftover vertex is selected as a root, and another
+        * tree is created
+        * @param graph
+        * @param factory
+        * @param weights
+        */
+       public MinimumSpanningForest2(Graph<V, E> graph, 
+                       Factory<Forest<V,E>> factory, 
+                       Factory<? extends Graph<V,E>> treeFactory,
+                       Transformer<E, Double> weights) {
+               this(graph, factory.create(), 
+                               treeFactory, 
+                               weights);
+       }
+       
+       /**
+        * create a forest from the supplied graph, populating the
+        * supplied Forest, which must be empty. 
+        * If the supplied root is null, or not present in the Graph,
+        * then an arbitary Graph vertex will be selected as the root.
+        * If the Minimum Spanning Tree does not include all vertices of the
+        * Graph, then a leftover vertex is selected as a root, and another
+        * tree is created
+        * @param graph the Graph to find MST in
+        * @param forest the Forest to populate. Must be empty
+        * @param weights edge weights, may be null
+        */
+       public MinimumSpanningForest2(Graph<V, E> graph, 
+                       Forest<V,E> forest, 
+                       Factory<? extends Graph<V,E>> treeFactory,
+                       Transformer<E, Double> weights) {
+               
+               if(forest.getVertexCount() != 0) {
+                       throw new IllegalArgumentException("Supplied Forest must be empty");
+               }
+               this.graph = graph;
+               this.forest = forest;
+               if(weights != null) {
+                       this.weights = weights;
+               }
+               
+               WeakComponentClusterer<V,E> wcc =
+                       new WeakComponentClusterer<V,E>();
+               Set<Set<V>> component_vertices = wcc.transform(graph);
+               Collection<Graph<V,E>> components = 
+                       FilterUtils.createAllInducedSubgraphs(component_vertices, graph);
+               
+               for(Graph<V,E> component : components) {
+                       PrimMinimumSpanningTree<V,E> mst = 
+                               new PrimMinimumSpanningTree<V,E>(treeFactory, this.weights);
+                       Graph<V,E> subTree = mst.transform(component);
+                       if(subTree instanceof Tree) {
+                               TreeUtils.addSubTree(forest, (Tree<V,E>)subTree, null, null);
+                       }
+               }
+       }
+       
+       /**
+        * Returns the generated forest.
+        */
+       public Forest<V,E> getForest() {
+               return forest;
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/PrimMinimumSpanningTree.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/PrimMinimumSpanningTree.java
new file mode 100644 (file)
index 0000000..b029dda
--- /dev/null
@@ -0,0 +1,116 @@
+package edu.uci.ics.jung.algorithms.shortestpath;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.collections15.Factory;
+import org.apache.commons.collections15.Transformer;
+import org.apache.commons.collections15.functors.ConstantTransformer;
+
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.Pair;
+
+/**
+ * For the input Graph, creates a MinimumSpanningTree
+ * using a variation of Prim's algorithm.
+ * 
+ * @author Tom Nelson - tomnelson@dev.java.net
+ *
+ * @param <V> the vertex type
+ * @param <E> the edge type
+ */
+@SuppressWarnings("unchecked")
+public class PrimMinimumSpanningTree<V,E> implements Transformer<Graph<V,E>,Graph<V,E>> {
+       
+       protected Factory<? extends Graph<V,E>> treeFactory;
+       protected Transformer<E,Double> weights; 
+       
+       /**
+        * Creates an instance which generates a minimum spanning tree assuming constant edge weights.
+        */
+       public PrimMinimumSpanningTree(Factory<? extends Graph<V,E>> factory) {
+               this(factory, new ConstantTransformer(1.0));
+       }
+
+    /**
+     * Creates an instance which generates a minimum spanning tree using the input edge weights.
+     */
+       public PrimMinimumSpanningTree(Factory<? extends Graph<V,E>> factory, 
+                       Transformer<E, Double> weights) {
+               this.treeFactory = factory;
+               if(weights != null) {
+                       this.weights = weights;
+               }
+       }
+       
+       /**
+        * @param graph the Graph to find MST in
+        */
+    public Graph<V,E> transform(Graph<V,E> graph) {
+               Set<E> unfinishedEdges = new HashSet<E>(graph.getEdges());
+               Graph<V,E> tree = treeFactory.create();
+               V root = findRoot(graph);
+               if(graph.getVertices().contains(root)) {
+                       tree.addVertex(root);
+               } else if(graph.getVertexCount() > 0) {
+                       // pick an arbitrary vertex to make root
+                       tree.addVertex(graph.getVertices().iterator().next());
+               }
+               updateTree(tree, graph, unfinishedEdges);
+               
+               return tree;
+       }
+    
+    protected V findRoot(Graph<V,E> graph) {
+       for(V v : graph.getVertices()) {
+               if(graph.getInEdges(v).size() == 0) {
+                       return v;
+               }
+       }
+       // if there is no obvious root, pick any vertex
+       if(graph.getVertexCount() > 0) {
+               return graph.getVertices().iterator().next();
+       }
+       // this graph has no vertices
+       return null;
+    }
+       
+       protected void updateTree(Graph<V,E> tree, Graph<V,E> graph, Collection<E> unfinishedEdges) {
+               Collection<V> tv = tree.getVertices();
+               double minCost = Double.MAX_VALUE;
+               E nextEdge = null;
+               V nextVertex = null;
+               V currentVertex = null;
+               for(E e : unfinishedEdges) {
+                       
+                       if(tree.getEdges().contains(e)) continue;
+                       // find the lowest cost edge, get its opposite endpoint,
+                       // and then update forest from its Successors
+                       Pair<V> endpoints = graph.getEndpoints(e);
+                       V first = endpoints.getFirst();
+                       V second = endpoints.getSecond();
+                       if((tv.contains(first) == true && tv.contains(second) == false)) {
+                               if(weights.transform(e) < minCost) {
+                                       minCost = weights.transform(e);
+                                       nextEdge = e;
+                                       currentVertex = first;
+                                       nextVertex = second;
+                               }
+                       } else if((tv.contains(second) == true && tv.contains(first) == false)) {
+                               if(weights.transform(e) < minCost) {
+                                       minCost = weights.transform(e);
+                                       nextEdge = e;
+                                       currentVertex = second;
+                                       nextVertex = first;
+                               }
+                       }
+               }
+               
+               if(nextVertex != null && nextEdge != null) {
+                       unfinishedEdges.remove(nextEdge);
+                       tree.addEdge(nextEdge, currentVertex, nextVertex);
+                       updateTree(tree, graph, unfinishedEdges);
+               }
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/ShortestPath.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/ShortestPath.java
new file mode 100644 (file)
index 0000000..a922cdd
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+* 
+* Created on Feb 12, 2004
+*/
+package edu.uci.ics.jung.algorithms.shortestpath;
+
+import java.util.Map;
+
+
+/**
+ * An interface for algorithms that calculate shortest paths.
+ */
+public interface ShortestPath<V, E>
+{
+    /**
+     * <p>Returns a <code>Map</code> which maps each vertex 
+     * in the graph (including the <code>source</code> vertex) 
+     * to the last edge on the shortest path from the 
+     * <code>source</code> vertex.
+     */ 
+     Map<V,E> getIncomingEdgeMap(V source);
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/ShortestPathUtils.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/ShortestPathUtils.java
new file mode 100644 (file)
index 0000000..d3e59eb
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Created on Jul 10, 2005
+ *
+ * Copyright (c) 2005, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.shortestpath;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.Pair;
+
+/**
+ * Utilities relating to the shortest paths in a graph.
+ */
+public class ShortestPathUtils
+{
+    /**
+     * Returns a <code>List</code> of the edges on the shortest path from 
+     * <code>source</code> to <code>target</code>, in order of their
+     * occurrence on this path.  
+     */
+    public static <V, E> List<E> getPath(Graph<V,E> graph, ShortestPath<V,E> sp, V source, V target)
+    {
+        LinkedList<E> path = new LinkedList<E>();
+        
+        Map<V,E> incomingEdges = sp.getIncomingEdgeMap(source);
+        
+        if (incomingEdges.isEmpty() || incomingEdges.get(target) == null)
+            return path;
+        V current = target;
+        while (!current.equals(source))
+        {
+            E incoming = incomingEdges.get(current);
+            path.addFirst(incoming);
+            Pair<V> endpoints = graph.getEndpoints(incoming);
+            if(endpoints.getFirst().equals(current)) { 
+               current = endpoints.getSecond();
+            } else {
+               current = endpoints.getFirst();
+            }
+                       //incoming.getOpposite(current);
+        }
+        return path;
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/UnweightedShortestPath.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/UnweightedShortestPath.java
new file mode 100644 (file)
index 0000000..1d3390c
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.shortestpath;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import edu.uci.ics.jung.graph.Hypergraph;
+
+/**
+ * Computes the shortest path distances for graphs whose edges are not weighted (using BFS).
+ * 
+ * @author Scott White
+ */
+public class UnweightedShortestPath<V, E> 
+    implements ShortestPath<V,E>, Distance<V>
+{
+       private Map<V,Map<V,Number>> mDistanceMap;
+       private Map<V,Map<V,E>> mIncomingEdgeMap;
+       private Hypergraph<V,E> mGraph;
+    private Map<V, Number> distances = new HashMap<V,Number>();
+
+       /**
+        * Constructs and initializes algorithm
+        * @param g the graph
+        */
+       public UnweightedShortestPath(Hypergraph<V,E> g)
+       {
+               mDistanceMap = new HashMap<V,Map<V,Number>>();
+               mIncomingEdgeMap = new HashMap<V,Map<V,E>>();
+               mGraph = g;
+       }
+
+    /**
+     * @see edu.uci.ics.jung.algorithms.shortestpath.Distance#getDistance(Object, Object)
+     */
+       public Number getDistance(V source, V target)
+       {
+               Map<V, Number> sourceSPMap = getDistanceMap(source);
+               return sourceSPMap.get(target);
+       }
+
+    /**
+     * @see edu.uci.ics.jung.algorithms.shortestpath.Distance#getDistanceMap(Object)
+     */
+       public Map<V,Number> getDistanceMap(V source)
+       {
+               Map<V,Number> sourceSPMap = mDistanceMap.get(source);
+               if (sourceSPMap == null)
+               {
+                       computeShortestPathsFromSource(source);
+                       sourceSPMap = mDistanceMap.get(source);
+               }
+               return sourceSPMap;
+       }
+
+       /**
+        * @see edu.uci.ics.jung.algorithms.shortestpath.ShortestPath#getIncomingEdgeMap(Object)
+        */
+       public Map<V,E> getIncomingEdgeMap(V source)
+       {
+               Map<V,E> sourceIEMap = mIncomingEdgeMap.get(source);
+               if (sourceIEMap == null)
+               {
+                       computeShortestPathsFromSource(source);
+                       sourceIEMap = mIncomingEdgeMap.get(source);
+               }
+               return sourceIEMap;
+       }
+
+
+       /**
+        * Computes the shortest path distances from a given node to all other nodes.
+        * @param source the source node
+        */
+       private void computeShortestPathsFromSource(V source)
+       {
+               BFSDistanceLabeler<V,E> labeler = new BFSDistanceLabeler<V,E>();
+               labeler.labelDistances(mGraph, source);
+        distances = labeler.getDistanceDecorator();
+               Map<V,Number> currentSourceSPMap = new HashMap<V,Number>();
+               Map<V,E> currentSourceEdgeMap = new HashMap<V,E>();
+
+        for(V vertex : mGraph.getVertices()) {
+            
+                       Number distanceVal = distances.get(vertex);
+            // BFSDistanceLabeler uses -1 to indicate unreachable vertices;
+            // don't bother to store unreachable vertices
+            if (distanceVal != null && distanceVal.intValue() >= 0) 
+            {
+                currentSourceSPMap.put(vertex, distanceVal);
+                int minDistance = distanceVal.intValue();
+                for(E incomingEdge : mGraph.getInEdges(vertex)) 
+                {
+                       for (V neighbor : mGraph.getIncidentVertices(incomingEdge))
+                       {
+                               if (neighbor.equals(vertex))
+                                       continue;
+//                         V neighbor = mGraph.getOpposite(vertex, incomingEdge);
+       
+                           Number predDistanceVal = distances.get(neighbor);
+       
+                           int pred_distance = predDistanceVal.intValue();
+                           if (pred_distance < minDistance && pred_distance >= 0)
+                           {
+                               minDistance = predDistanceVal.intValue();
+                               currentSourceEdgeMap.put(vertex, incomingEdge);
+                           }
+                       }
+                }
+            }
+               }
+               mDistanceMap.put(source, currentSourceSPMap);
+               mIncomingEdgeMap.put(source, currentSourceEdgeMap);
+       }
+    
+    /**
+     * Clears all stored distances for this instance.  
+     * Should be called whenever the graph is modified (edge weights 
+     * changed or edges added/removed).  If the user knows that
+     * some currently calculated distances are unaffected by a
+     * change, <code>reset(V)</code> may be appropriate instead.
+     * 
+     * @see #reset(Object)
+     */
+    public void reset()
+    {
+        mDistanceMap.clear();
+        mIncomingEdgeMap.clear();
+    }
+    
+    /**
+     * Clears all stored distances for the specified source vertex 
+     * <code>source</code>.  Should be called whenever the stored distances
+     * from this vertex are invalidated by changes to the graph.
+     * 
+     * @see #reset()
+     */
+    public void reset(V v)
+    {
+        mDistanceMap.remove(v);
+        mIncomingEdgeMap.remove(v);
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/shortestpath/package.html
new file mode 100644 (file)
index 0000000..01f27b5
--- /dev/null
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+-->
+</head>
+<body>
+
+Provides interfaces and classes for calculating (geodesic) distances and shortest paths.  Currently includes:
+<ul>
+<li/><code>DijkstraDistance</code>: finds the distances from a specified source vertex to other vertices in a 
+weighted graph with no negative cycles
+<li/><code>DijkstraShortestPath</code>: extends <code>DijkstraDistance</code>, also finds shortest paths
+<li/><code>Distance</code>: an interface for defining vertex-vertex distances
+<li/><code>PrimMinimumSpanningTree</code>: identifies the spanning tree for a graph of least total edge weight
+<li/><code>ShortestPath</code>: an interface for shortest-path algorithms
+<li/><code>ShortestPathUtils</code>: utility functions for manipulating shortest paths
+<li/><code>UnweightedShortestPath</code>: finds the distances from a specified source vertex to other vertices in an
+unweighted graph
+</ul>
+
+</body>
+</html>
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/transformation/DirectionTransformer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/transformation/DirectionTransformer.java
new file mode 100644 (file)
index 0000000..8fa33b8
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+/*
+ * Created on Apr 21, 2004
+ */
+package edu.uci.ics.jung.algorithms.transformation;
+
+import org.apache.commons.collections15.Factory;
+
+import edu.uci.ics.jung.graph.DirectedGraph;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.UndirectedGraph;
+import edu.uci.ics.jung.graph.util.EdgeType;
+import edu.uci.ics.jung.graph.util.Pair;
+
+/**
+ * <p>Functions for transforming graphs into directed or undirected graphs.</p>
+ * 
+ * 
+ * @author Danyel Fisher
+ * @author Joshua O'Madadhain
+ */
+public class DirectionTransformer 
+{
+
+    /**
+     * Transforms <code>graph</code> (which may be of any directionality)
+     * into an undirected graph. (This may be useful for
+     * visualization tasks).
+     * Specifically:
+     * <ul>
+     * <li/>Vertices are copied from <code>graph</code>.
+     * <li/>Directed edges are 'converted' into a single new undirected edge in the new graph.
+     * <li/>Each undirected edge (if any) in <code>graph</code> is 'recreated' with a new undirected edge in the new
+     * graph if <code>create_new</code> is true, or copied from <code>graph</code> otherwise.
+     * </ul>
+     * 
+     * @param graph     the graph to be transformed
+     * @param create_new specifies whether existing undirected edges are to be copied or recreated
+     * @param graph_factory used to create the new graph object
+     * @param edge_factory used to create new edges
+     * @return          the transformed <code>Graph</code>
+     */
+    public static <V,E> UndirectedGraph<V,E> toUndirected(Graph<V,E> graph, 
+               Factory<UndirectedGraph<V,E>> graph_factory,
+            Factory<E> edge_factory, boolean create_new)
+    {
+        UndirectedGraph<V,E> out = graph_factory.create();
+        
+        for (V v : graph.getVertices())
+            out.addVertex(v);
+        
+        for (E e : graph.getEdges())
+        {
+            Pair<V> endpoints = graph.getEndpoints(e);
+            V v1 = endpoints.getFirst();
+            V v2 = endpoints.getSecond();
+            E to_add;
+            if (graph.getEdgeType(e) == EdgeType.DIRECTED || create_new)
+                to_add = edge_factory.create();
+            else
+                to_add = e;
+            out.addEdge(to_add, v1, v2, EdgeType.UNDIRECTED);
+        }
+        return out;
+    }
+    
+    /**
+     * Transforms <code>graph</code> (which may be of any directionality)
+     * into a directed graph.  
+     * Specifically:
+     * <ul>
+     * <li/>Vertices are copied from <code>graph</code>.
+     * <li/>Undirected edges are 'converted' into two new antiparallel directed edges in the new graph.
+     * <li/>Each directed edge (if any) in <code>graph</code> is 'recreated' with a new edge in the new
+     * graph if <code>create_new</code> is true, or copied from <code>graph</code> otherwise.
+     * </ul>
+     * 
+     * @param graph     the graph to be transformed
+     * @param create_new specifies whether existing directed edges are to be copied or recreated
+     * @param graph_factory used to create the new graph object
+     * @param edge_factory used to create new edges
+     * @return          the transformed <code>Graph</code>
+     */
+    public static <V,E> Graph<V,E> toDirected(Graph<V,E> graph, Factory<DirectedGraph<V,E>> graph_factory,
+            Factory<E> edge_factory, boolean create_new)
+    {
+        DirectedGraph<V,E> out = graph_factory.create();
+        
+        for (V v : graph.getVertices())
+            out.addVertex(v);
+        
+        for (E e : graph.getEdges())
+        {
+            Pair<V> endpoints = graph.getEndpoints(e);
+            if (graph.getEdgeType(e) == EdgeType.UNDIRECTED)
+            {
+                V v1 = endpoints.getFirst();
+                V v2 = endpoints.getSecond();
+                out.addEdge(edge_factory.create(), v1, v2, EdgeType.DIRECTED);
+                out.addEdge(edge_factory.create(), v2, v1, EdgeType.DIRECTED);
+            }
+            else // if the edge is directed, just add it 
+            {
+                V source = graph.getSource(e);
+                V dest = graph.getDest(e);
+                E to_add = create_new ? edge_factory.create() : e;
+                out.addEdge(to_add, source, dest, EdgeType.DIRECTED);
+            }
+                
+        }
+        return out;
+    }
+}
\ No newline at end of file
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/transformation/FoldingTransformer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/transformation/FoldingTransformer.java
new file mode 100644 (file)
index 0000000..2193319
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+/*
+ * Created on Apr 21, 2004
+ */
+package edu.uci.ics.jung.algorithms.transformation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.commons.collections15.Factory;
+import org.apache.commons.collections15.Predicate;
+
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.Hypergraph;
+import edu.uci.ics.jung.graph.KPartiteGraph;
+
+/**
+ * Methods for creating a "folded" graph based on a k-partite graph or a
+ * hypergraph.  
+ * 
+ * <p>A "folded" graph is derived from a k-partite graph by identifying
+ * a partition of vertices which will become the vertices of the new graph, copying
+ * these vertices into the new graph, and then connecting those vertices whose
+ * original analogues were connected indirectly through elements
+ * of other partitions.</p>
+ * 
+ * <p>A "folded" graph is derived from a hypergraph by creating vertices based on
+ * either the vertices or the hyperedges of the original graph, and connecting 
+ * vertices in the new graph if their corresponding vertices/hyperedges share a 
+ * connection with a common hyperedge/vertex.</p>   
+ * 
+ * @author Danyel Fisher
+ * @author Joshua O'Madadhain
+ */
+public class FoldingTransformer<V,E>
+{
+    
+    /**
+     * Converts <code>g</code> into a unipartite graph whose vertex set is the
+     * vertices of <code>g</code>'s partition <code>p</code>.  For vertices
+     * <code>a</code> and <code>b</code> in this partition, the resultant
+     * graph will include the edge <code>(a,b)</code> if the original graph
+     * contains edges <code>(a,c)</code> and <code>(c,b)</code> for at least
+     * one vertex <code>c</code>.
+     * 
+     * <p>The vertices of the new graph are the same as the vertices of the
+     * appropriate partition in the old graph; the edges in the new graph are
+     * created by the input edge <code>Factory</code>.</p>
+     * 
+     * <p>If there is more than 1 such vertex <code>c</code> for a given pair
+     * <code>(a,b)</code>, the type of the output graph will determine whether
+     * it will contain parallel edges or not.</p>
+     * 
+     * <p>This function will not create self-loops.</p>
+     * 
+     * @param <V> vertex type
+     * @param <E> input edge type
+     * @param g input k-partite graph
+     * @param p predicate specifying vertex partition
+     * @param graph_factory factory used to create the output graph 
+     * @param edge_factory factory used to create the edges in the new graph
+     * @return a copy of the input graph folded with respect to the input partition
+     */
+    public static <V,E> Graph<V,E> foldKPartiteGraph(KPartiteGraph<V,E> g, Predicate<V> p, 
+            Factory<Graph<V,E>> graph_factory, Factory<E> edge_factory)
+    {
+        Graph<V,E> newGraph = graph_factory.create();
+
+        // get vertices for the specified partition
+        Collection<V> vertices = g.getVertices(p);
+        for (V v : vertices)
+        {
+            newGraph.addVertex(v);
+            for (V s : g.getSuccessors(v))
+            {
+                for (V t : g.getSuccessors(s))
+                {
+                    if (!vertices.contains(t) || t.equals(v)) 
+                        continue;
+                    newGraph.addVertex(t);
+                    newGraph.addEdge(edge_factory.create(), v, t);
+                }
+            }
+        }
+        return newGraph;
+    }
+
+    /**
+     * Converts <code>g</code> into a unipartite graph whose vertices are the
+     * vertices of <code>g</code>'s partition <code>p</code>, and whose edges
+     * consist of collections of the intermediate vertices from other partitions.  
+     * For vertices
+     * <code>a</code> and <code>b</code> in this partition, the resultant
+     * graph will include the edge <code>(a,b)</code> if the original graph
+     * contains edges <code>(a,c)</code> and <code>(c,b)</code> for at least
+     * one vertex <code>c</code>.
+     * 
+     * <p>The vertices of the new graph are the same as the vertices of the
+     * appropriate partition in the old graph; the edges in the new graph are
+     * collections of the intermediate vertices <code>c</code>.</p>
+     * 
+     * <p>This function will not create self-loops.</p>
+     * 
+     * @param <V> vertex type
+     * @param <E> input edge type
+     * @param g input k-partite graph
+     * @param p predicate specifying vertex partition
+     * @param graph_factory factory used to create the output graph 
+     * @return the result of folding g into unipartite graph whose vertices
+     * are those of the <code>p</code> partition of g
+     */
+    public static <V,E> Graph<V, Collection<V>> foldKPartiteGraph(KPartiteGraph<V,E> g, Predicate<V> p, 
+            Factory<Graph<V, Collection<V>>> graph_factory)
+    {
+        Graph<V, Collection<V>> newGraph = graph_factory.create();
+
+        // get vertices for the specified partition, copy into new graph
+        Collection<V> vertices = g.getVertices(p);
+
+        for (V v : vertices)
+        {
+            newGraph.addVertex(v);
+            for (V s : g.getSuccessors(v))
+            {
+                for (V t : g.getSuccessors(s))
+                {
+                    if (!vertices.contains(t) || t.equals(v)) 
+                        continue;
+                    newGraph.addVertex(t);
+                    Collection<V> v_coll = newGraph.findEdge(v, t);
+                    if (v_coll == null)
+                    {
+                        v_coll = new ArrayList<V>();
+                        newGraph.addEdge(v_coll, v, t);
+                    }
+                    v_coll.add(s);
+                }
+            }
+        }
+        return newGraph;
+    }
+    
+    /**
+     * Creates a <code>Graph</code> which is an edge-folded version of <code>h</code>, where
+     * hyperedges are replaced by k-cliques in the output graph.
+     * 
+     * <p>The vertices of the new graph are the same objects as the vertices of 
+     * <code>h</code>, and <code>a</code> 
+     * is connected to <code>b</code> in the new graph if the corresponding vertices
+     * in <code>h</code> are connected by a hyperedge.  Thus, each hyperedge with 
+     * <i>k</i> vertices in <code>h</code> induces a <i>k</i>-clique in the new graph.</p>
+     * 
+     * <p>The edges of the new graph consist of collections of each hyperedge that connected
+     * the corresponding vertex pair in the original graph.</p>
+     * 
+     * @param <V> vertex type
+     * @param <E> input edge type
+     * @param h hypergraph to be folded
+     * @param graph_factory factory used to generate the output graph
+     * @return a copy of the input graph where hyperedges are replaced by cliques
+     */
+    public static <V,E> Graph<V, Collection<E>> foldHypergraphEdges(Hypergraph<V,E> h, 
+            Factory<Graph<V, Collection<E>>> graph_factory)
+    {
+        Graph<V, Collection<E>> target = graph_factory.create();
+
+        for (V v : h.getVertices())
+            target.addVertex(v);
+        
+        for (E e : h.getEdges())
+        {
+            ArrayList<V> incident = new ArrayList<V>(h.getIncidentVertices(e));
+            populateTarget(target, e, incident);
+        }
+        return target;
+    }
+
+
+    /**
+     * Creates a <code>Graph</code> which is an edge-folded version of <code>h</code>, where
+     * hyperedges are replaced by k-cliques in the output graph.
+     * 
+     * <p>The vertices of the new graph are the same objects as the vertices of 
+     * <code>h</code>, and <code>a</code> 
+     * is connected to <code>b</code> in the new graph if the corresponding vertices
+     * in <code>h</code> are connected by a hyperedge.  Thus, each hyperedge with 
+     * <i>k</i> vertices in <code>h</code> induces a <i>k</i>-clique in the new graph.</p>
+     * 
+     * <p>The edges of the new graph are generated by the specified edge factory.</p>
+     * 
+     * @param <V> vertex type
+     * @param <E> input edge type
+     * @param h hypergraph to be folded
+     * @param graph_factory factory used to generate the output graph
+     * @param edge_factory factory used to create the new edges 
+     * @return a copy of the input graph where hyperedges are replaced by cliques
+     */
+    public static <V,E> Graph<V,E> foldHypergraphEdges(Hypergraph<V,E> h, 
+            Factory<Graph<V,E>> graph_factory, Factory<E> edge_factory)
+    {
+        Graph<V,E> target = graph_factory.create();
+
+        for (V v : h.getVertices())
+            target.addVertex(v);
+        
+        for (E e : h.getEdges())
+        {
+            ArrayList<V> incident = new ArrayList<V>(h.getIncidentVertices(e));
+            for (int i = 0; i < incident.size(); i++)
+                for (int j = i+1; j < incident.size(); j++)
+                    target.addEdge(edge_factory.create(), incident.get(i), incident.get(j));
+        }
+        return target;
+    }
+
+    /**
+     * Creates a <code>Graph</code> which is a vertex-folded version of <code>h</code>, whose
+     * vertices are the input's hyperedges and whose edges are induced by adjacent hyperedges
+     * in the input.
+     * 
+     * <p>The vertices of the new graph are the same objects as the hyperedges of 
+     * <code>h</code>, and <code>a</code> 
+     * is connected to <code>b</code> in the new graph if the corresponding edges
+     * in <code>h</code> have a vertex in common.  Thus, each vertex incident to  
+     * <i>k</i> edges in <code>h</code> induces a <i>k</i>-clique in the new graph.</p>
+     * 
+     * <p>The edges of the new graph are created by the specified factory.</p>
+     * 
+     * @param <V> vertex type
+     * @param <E> input edge type
+     * @param <F> output edge type
+     * @param h hypergraph to be folded
+     * @param graph_factory factory used to generate the output graph
+     * @param edge_factory factory used to generate the output edges
+     * @return a transformation of the input graph whose vertices correspond to the input's hyperedges 
+     * and edges are induced by hyperedges sharing vertices in the input
+     */
+    public static <V,E,F> Graph<E,F> foldHypergraphVertices(Hypergraph<V,E> h, 
+            Factory<Graph<E,F>> graph_factory, Factory<F> edge_factory)
+    {
+        Graph<E,F> target = graph_factory.create();
+        
+        for (E e : h.getEdges())
+            target.addVertex(e);
+        
+        for (V v : h.getVertices())
+        {
+            ArrayList<E> incident = new ArrayList<E>(h.getIncidentEdges(v));
+            for (int i = 0; i < incident.size(); i++)
+                for (int j = i+1; j < incident.size(); j++)
+                    target.addEdge(edge_factory.create(), incident.get(i), incident.get(j));
+        }
+        
+        return target;
+    }
+
+    /**
+     * Creates a <code>Graph</code> which is a vertex-folded version of <code>h</code>, whose
+     * vertices are the input's hyperedges and whose edges are induced by adjacent hyperedges
+     * in the input.
+     * 
+     * <p>The vertices of the new graph are the same objects as the hyperedges of 
+     * <code>h</code>, and <code>a</code> 
+     * is connected to <code>b</code> in the new graph if the corresponding edges
+     * in <code>h</code> have a vertex in common.  Thus, each vertex incident to  
+     * <i>k</i> edges in <code>h</code> induces a <i>k</i>-clique in the new graph.</p>
+     * 
+     * <p>The edges of the new graph consist of collections of each vertex incident to 
+     * the corresponding hyperedge pair in the original graph.</p>
+     * 
+     * @param h hypergraph to be folded
+     * @param graph_factory factory used to generate the output graph
+     * @return a transformation of the input graph whose vertices correspond to the input's hyperedges 
+     * and edges are induced by hyperedges sharing vertices in the input
+     */
+    public Graph<E,Collection<V>> foldHypergraphVertices(Hypergraph<V,E> h, 
+            Factory<Graph<E,Collection<V>>> graph_factory)
+    {
+        Graph<E,Collection<V>> target = graph_factory.create();
+
+        for (E e : h.getEdges())
+            target.addVertex(e);
+        
+        for (V v : h.getVertices())
+        {
+            ArrayList<E> incident = new ArrayList<E>(h.getIncidentEdges(v));
+            populateTarget(target, v, incident);
+        }
+        return target;
+    }
+    
+    /**
+     * @param target
+     * @param e
+     * @param incident
+     */
+    private static <S,T> void populateTarget(Graph<S, Collection<T>> target, T e,
+            ArrayList<S> incident)
+    {
+        for (int i = 0; i < incident.size(); i++)
+        {
+            S v1 = incident.get(i);
+            for (int j = i+1; j < incident.size(); j++)
+            {
+                S v2 = incident.get(j);
+                Collection<T> e_coll = target.findEdge(v1, v2);
+                if (e_coll == null)
+                {
+                    e_coll = new ArrayList<T>();
+                    target.addEdge(e_coll, v1, v2);
+                }
+                e_coll.add(e);
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/transformation/VertexPartitionCollapser.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/transformation/VertexPartitionCollapser.java
new file mode 100644 (file)
index 0000000..e44d05d
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.transformation;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections15.Factory;
+import org.apache.commons.collections15.Transformer;
+import org.apache.commons.collections15.functors.MapTransformer;
+
+import edu.uci.ics.jung.algorithms.blockmodel.VertexPartition;
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * This class transforms a graph with a known vertex partitioning into a graph whose 
+ * vertices correspond to the input graph's partitions.  Two vertices in the output graph
+ * are connected if and only if there exists at least one edge between vertices in the 
+ * corresponding partitions of the input graph.  If the output graph permits parallel edges,
+ * there will be an edge connecting two vertices in the new graph for each such 
+ * edge connecting constituent vertices in the input graph.
+ * 
+ * <p>Concept based on Danyel Fisher's <code>GraphCollapser</code> in JUNG 1.x.
+ * 
+ */
+public class VertexPartitionCollapser<V,E,CV,CE> 
+{
+    protected Factory<Graph<CV,CE>> graph_factory;
+    protected Factory<CV> vertex_factory;
+    protected Factory<CE> edge_factory;
+    protected Map<Set<V>, CV> set_collapsedv;
+    
+    /**
+     * Creates an instance with the specified graph and element factories.
+     * @param vertex_factory used to construct the vertices of the new graph
+     * @param edge_factory used to construct the edges of the new graph
+     * @param graph_factory used to construct the new graph
+     */
+    public VertexPartitionCollapser(Factory<Graph<CV,CE>> graph_factory, 
+            Factory<CV> vertex_factory, Factory<CE> edge_factory)
+    {
+        this.graph_factory = graph_factory;
+        this.vertex_factory = vertex_factory;
+        this.edge_factory = edge_factory;
+        this.set_collapsedv = new HashMap<Set<V>, CV>();
+    }
+
+    /**
+     * Creates a new graph whose vertices correspond to the partitions of the supplied graph.
+     * @param partitioning
+     * @return a new graph whose vertices correspond to the partitions of the supplied graph
+     */
+    public Graph<CV,CE> collapseVertexPartitions(VertexPartition<V,E> partitioning)
+    {
+        Graph<V,E> original = partitioning.getGraph();
+        Graph<CV, CE> collapsed = graph_factory.create();
+        
+        // create vertices in new graph corresponding to equivalence sets in the original graph
+        for (Set<V> set : partitioning.getVertexPartitions())
+        {
+            CV cv = vertex_factory.create();
+            collapsed.addVertex(vertex_factory.create());
+            set_collapsedv.put(set, cv);
+        }
+
+        // create edges in new graph corresponding to edges in original graph
+        for (E e : original.getEdges())
+        {
+            Collection<V> incident = original.getIncidentVertices(e);
+            Collection<CV> collapsed_vertices = new HashSet<CV>();
+            Map<V, Set<V>> vertex_partitions = partitioning.getVertexToPartitionMap();
+            // collect the collapsed vertices corresponding to the original incident vertices
+            for (V v : incident)
+                collapsed_vertices.add(set_collapsedv.get(vertex_partitions.get(v))); 
+            // if there's only one collapsed vertex, continue (no edges to create)
+            if (collapsed_vertices.size() > 1)
+            {
+                CE ce = edge_factory.create();
+                collapsed.addEdge(ce, collapsed_vertices);
+            }
+        }
+        return collapsed;
+    }
+    
+    /**
+     * Returns a transformer from vertex sets in the original graph to collapsed vertices
+     * in the transformed graph.
+     */
+    public Transformer<Set<V>, CV> getSetToCollapsedVertexTransformer()
+    {
+        return MapTransformer.getInstance(set_collapsedv);
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/transformation/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/transformation/package.html
new file mode 100644 (file)
index 0000000..6680095
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+-->
+</head>
+<body>
+
+Mechanisms for graph transformation.  These currently include:
+<ul>
+<li/><code>DirectionTransformer</code>: generates graphs where input undirected 
+edges have been converted to directed edges, or vice versa
+<li/><code>FoldingTransformer</code>: transforms k-partite graphs or hypergraphs 
+into unipartite graphs
+<li/><code>VertexPartitionCollapser</code>: transforms a graph, given a 
+partition of its vertices into disjoint sets, into a graph in which each 
+of these disjoint sets has been 'collapsed' into a single new vertex.
+</ul>
+
+</body>
+</html>
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/BasicMapEntry.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/BasicMapEntry.java
new file mode 100644 (file)
index 0000000..a82aea6
--- /dev/null
@@ -0,0 +1,80 @@
+package edu.uci.ics.jung.algorithms.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * An simple minimal implementation of <code>Map.Entry</code>.
+ *
+ * @param <K> the key type
+ * @param <V> the value type
+ */
+public class BasicMapEntry<K,V> implements Map.Entry<K,V> {
+    final K key;
+    V value;
+    
+    /**
+     * Create new entry.
+     */
+    public BasicMapEntry(K k, V v) {
+        value = v;
+        key = k;
+    }
+
+    public K getKey() {
+        return key;
+    }
+
+    public V getValue() {
+        return value;
+    }
+
+    public V setValue(V newValue) {
+    V oldValue = value;
+        value = newValue;
+        return oldValue;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Map.Entry))
+            return false;
+        Map.Entry e = (Map.Entry)o;
+        Object k1 = getKey();
+        Object k2 = e.getKey();
+        if (k1 == k2 || (k1 != null && k1.equals(k2))) {
+            Object v1 = getValue();
+            Object v2 = e.getValue();
+            if (v1 == v2 || (v1 != null && v1.equals(v2))) 
+                return true;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return (key==null ? 0 : key.hashCode()) ^
+               (value==null   ? 0 : value.hashCode());
+    }
+
+    @Override
+    public String toString() {
+        return getKey() + "=" + getValue();
+    }
+
+    /**
+     * This method is invoked whenever the value in an entry is
+     * overwritten by an invocation of put(k,v) for a key k that's already
+     * in the HashMap.
+     */
+    void recordAccess(HashMap<K,V> m) {
+    }
+
+    /**
+     * This method is invoked whenever the entry is
+     * removed from the table.
+     */
+    void recordRemoval(HashMap<K,V> m) {
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/ConstantMap.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/ConstantMap.java
new file mode 100644 (file)
index 0000000..53054d7
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+
+package edu.uci.ics.jung.algorithms.util;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * An implementation of <code>Map</code> that returns the constructor-supplied
+ * value for any input.
+ *
+ * @param <K> the key type
+ * @param <V> the value type
+ */
+public class ConstantMap<K,V> implements Map<K,V> {
+
+       private Map<K,V> delegate;
+       
+       /**
+        * Creates an instance whose {@code get} method always returns {@code value}.
+        */
+       public ConstantMap(V value) {
+               delegate = Collections.<K,V>unmodifiableMap(Collections.<K,V>singletonMap(null, value));
+       }
+
+       public V get(Object key) {
+               return delegate.get(null);
+       }
+       
+       public void clear() {
+               delegate.clear();
+       }
+       
+       public boolean containsKey(Object key) {
+               return true;
+       }
+       
+       public boolean containsValue(Object value) {
+               return delegate.containsValue(value);
+       }
+       
+       public Set<Entry<K, V>> entrySet() {
+               return delegate.entrySet();
+       }
+       
+       @Override
+       public boolean equals(Object o) {
+               return delegate.equals(o);
+       }
+       
+       @Override
+       public int hashCode() {
+               return delegate.hashCode();
+       }
+       
+       public boolean isEmpty() {
+               return delegate.isEmpty();
+       }
+       
+       public Set<K> keySet() {
+               return delegate.keySet();
+       }
+       
+       public V put(K key, V value) {
+               return delegate.put(key, value);
+       }
+       
+       public void putAll(Map<? extends K, ? extends V> t) {
+               delegate.putAll(t);
+       }
+       
+       public V remove(Object key) {
+               return delegate.remove(key);
+       }
+       
+       public int size() {
+               return delegate.size();
+       }
+       
+       public Collection<V> values() {
+               return delegate.values();
+       }
+}
\ No newline at end of file
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/DiscreteDistribution.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/DiscreteDistribution.java
new file mode 100644 (file)
index 0000000..84eadc0
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ * 
+ * Created on Feb 18, 2004
+ */
+package edu.uci.ics.jung.algorithms.util;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * A utility class for calculating properties of discrete distributions.
+ * Generally, these distributions are represented as arrays of 
+ * <code>double</code> values, which are assumed to be normalized
+ * such that the entries in a single array sum to 1.  
+ * 
+ * @author Joshua O'Madadhain
+ */
+public class DiscreteDistribution
+{
+
+    /**
+     * Returns the Kullback-Leibler divergence between the 
+     * two specified distributions, which must have the same
+     * number of elements.  This is defined as 
+     * the sum over all <code>i</code> of 
+     * <code>dist[i] * Math.log(dist[i] / reference[i])</code>.
+     * Note that this value is not symmetric; see 
+     * <code>symmetricKL</code> for a symmetric variant. 
+     * @see #symmetricKL(double[], double[])
+     */
+    public static double KullbackLeibler(double[] dist, double[] reference)
+    {
+        double distance = 0;
+
+        checkLengths(dist, reference);
+
+        for (int i = 0; i < dist.length; i++)
+        {
+            if (dist[i] > 0 && reference[i] > 0)
+                distance += dist[i] * Math.log(dist[i] / reference[i]);
+        }
+        return distance;
+    }
+
+    /**
+     * Returns <code>KullbackLeibler(dist, reference) + KullbackLeibler(reference, dist)</code>.
+     * @see #KullbackLeibler(double[], double[])
+     */
+    public static double symmetricKL(double[] dist, double[] reference)
+    {
+        return KullbackLeibler(dist, reference)
+                + KullbackLeibler(reference, dist);
+    }
+
+    /**
+     * Returns the squared difference between the 
+     * two specified distributions, which must have the same
+     * number of elements.  This is defined as 
+     * the sum over all <code>i</code> of the square of 
+     * <code>(dist[i] - reference[i])</code>.
+     */
+    public static double squaredError(double[] dist, double[] reference)
+    {
+        double error = 0;
+
+        checkLengths(dist, reference);
+
+        for (int i = 0; i < dist.length; i++)
+        {
+            double difference = dist[i] - reference[i];
+            error += difference * difference;
+        }
+        return error;
+    }
+
+    /**
+     * Returns the cosine distance between the two 
+     * specified distributions, which must have the same number
+     * of elements.  The distributions are treated as vectors
+     * in <code>dist.length</code>-dimensional space.
+     * Given the following definitions
+     * <ul>
+     * <li/><code>v</code> = the sum over all <code>i</code> of <code>dist[i] * dist[i]</code>
+     * <li/><code>w</code> = the sum over all <code>i</code> of <code>reference[i] * reference[i]</code>
+     * <li/><code>vw</code> = the sum over all <code>i</code> of <code>dist[i] * reference[i]</code>
+     * </ul>
+     * the value returned is defined as <code>vw / (Math.sqrt(v) * Math.sqrt(w))</code>.
+     */
+    public static double cosine(double[] dist, double[] reference)
+    {
+        double v_prod = 0; // dot product x*x
+        double w_prod = 0; // dot product y*y
+        double vw_prod = 0; // dot product x*y
+
+        checkLengths(dist, reference);
+
+        for (int i = 0; i < dist.length; i++)
+        {
+            vw_prod += dist[i] * reference[i];
+            v_prod += dist[i] * dist[i];
+            w_prod += reference[i] * reference[i];
+        }
+        // cosine distance between v and w
+        return vw_prod / (Math.sqrt(v_prod) * Math.sqrt(w_prod));
+    }
+
+    /**
+     * Returns the entropy of this distribution.
+     * High entropy indicates that the distribution is 
+     * close to uniform; low entropy indicates that the
+     * distribution is close to a Dirac delta (i.e., if
+     * the probability mass is concentrated at a single
+     * point, this method returns 0).  Entropy is defined as 
+     * the sum over all <code>i</code> of 
+     * <code>-(dist[i] * Math.log(dist[i]))</code>
+     */
+    public static double entropy(double[] dist)
+    {
+        double total = 0;
+
+        for (int i = 0; i < dist.length; i++)
+        {
+            if (dist[i] > 0)
+                total += dist[i] * Math.log(dist[i]);
+        }
+        return -total;
+    }
+
+    /**
+     * Throws an <code>IllegalArgumentException</code> if the two arrays are not of the same length.
+     */
+    protected static void checkLengths(double[] dist, double[] reference)
+    {
+        if (dist.length != reference.length)
+            throw new IllegalArgumentException("Arrays must be of the same length");
+    }
+
+    /**
+     * Normalizes, with Lagrangian smoothing, the specified <code>double</code>
+     * array, so that the values sum to 1 (i.e., can be treated as probabilities).
+     * The effect of the Lagrangian smoothing is to ensure that all entries 
+     * are nonzero; effectively, a value of <code>alpha</code> is added to each
+     * entry in the original array prior to normalization.
+     * @param counts
+     * @param alpha
+     */
+    public static void normalize(double[] counts, double alpha)
+    {
+        double total_count = 0;
+
+        for (int i = 0; i < counts.length; i++)
+            total_count += counts[i];
+
+        for (int i = 0; i < counts.length; i++)
+            counts[i] = (counts[i] + alpha)
+                    / (total_count + counts.length * alpha);
+    }
+
+    /**
+     * Returns the mean of the specified <code>Collection</code> of
+     * distributions, which are assumed to be normalized arrays of 
+     * <code>double</code> values.
+     * @see #mean(double[][])
+     */
+    public static double[] mean(Collection<double[]> distributions)
+    {
+        if (distributions.isEmpty())
+            throw new IllegalArgumentException("Distribution collection must be non-empty");
+        Iterator<double[]> iter = distributions.iterator();
+        double[] first = iter.next();
+        double[][] d_array = new double[distributions.size()][first.length];
+        d_array[0] = first;
+        for (int i = 1; i < d_array.length; i++)
+            d_array[i] = iter.next();
+        
+        return mean(d_array);
+    }
+    
+    /**
+     * Returns the mean of the specified array of distributions,
+     * represented as normalized arrays of <code>double</code> values.
+     * Will throw an "index out of bounds" exception if the 
+     * distribution arrays are not all of the same length.
+     */
+    public static double[] mean(double[][] distributions)
+    {
+        double[] d_mean = new double[distributions[0].length];
+        for (int j = 0; j < d_mean.length; j++)
+            d_mean[j] = 0;
+            
+        for (int i = 0; i < distributions.length; i++)
+            for (int j = 0; j < d_mean.length; j++)
+                d_mean[j] += distributions[i][j] / distributions.length;
+        
+        return d_mean;
+    }
+    
+}
\ No newline at end of file
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/Indexer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/Indexer.java
new file mode 100644 (file)
index 0000000..b8a215e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.util;
+
+import java.util.Collection;
+
+import org.apache.commons.collections15.BidiMap;
+import org.apache.commons.collections15.bidimap.DualHashBidiMap;
+
+/**
+ * A class providing static methods useful for improving the
+ * performance of graph algorithms.
+ * 
+ * @author Tom Nelson
+ *
+ */
+public class Indexer {
+       
+       /**
+        * Returns a <code>BidiMap</code> mapping each element of the collection to its
+        * index as encountered while iterating over the collection. The purpose
+        * of the index operation is to supply an O(1) replacement operation for the
+        * O(n) <code>indexOf(element)</code> method of a <code>List</code>
+        * @param <T>
+        * @param collection
+        * @return a bidirectional map from collection elements to 0-based indices
+        */
+       public static <T> BidiMap<T,Integer> create(Collection<T> collection) {
+           return create(collection, 0);
+       }
+       /**
+        * Returns a <code>BidiMap</code> mapping each element of the collection to its
+        * index as encountered while iterating over the collection. The purpose
+        * of the index operation is to supply an O(1) replacement operation for the
+        * O(n) <code>indexOf(element)</code> method of a <code>List</code>
+        * @param <T>
+        * @param collection
+        * @param start start index
+        * @return a bidirectional map from collection elements to start-based indices
+        */
+       public static <T> BidiMap<T,Integer> create(Collection<T> collection, int start) {
+               BidiMap<T,Integer> map = new DualHashBidiMap<T,Integer>();
+               int i=start;
+               for(T t : collection) {
+                       map.put(t,i++);
+               }
+               return map;
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/IterativeContext.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/IterativeContext.java
new file mode 100644 (file)
index 0000000..92bd45d
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.util;
+
+
+/**
+ * An interface for algorithms that proceed iteratively.
+ *
+ */
+public interface IterativeContext 
+{
+       /**
+        * Advances one step.
+        */
+       void step();
+
+       /**
+        * Returns true if this iterative process is finished, and false otherwise.
+        */
+       boolean done();
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/IterativeProcess.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/IterativeProcess.java
new file mode 100644 (file)
index 0000000..fbe07f4
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University 
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.util;
+
+
+
+/**
+ * Provides basic infrastructure for iterative algorithms. Services provided include:
+ * <ul>
+ * <li> storage of current and max iteration count </li>
+ * <li> framework for initialization, iterative evaluation, and finalization </li>
+ * <li> test for convergence </li>
+ * <li> etc. </li>
+ * </ul>
+ * <p>
+ * Algorithms that subclass this class are typically used in the following way: <br>
+ * <pre>
+ * FooAlgorithm foo = new FooAlgorithm(...)
+ * foo.setMaximumIterations(100); //set up conditions
+ * ...
+ * foo.evaluate(); //key method which initiates iterative process
+ * foo.getSomeResult();
+ * </pre>
+ * 
+ * @author Scott White (originally written by Didier Besset)
+ */
+public abstract class IterativeProcess implements IterativeContext {
+    /**
+     * Number of iterations performed.
+     */
+    private int iterations;
+    /**
+     * Maximum allowed number of iterations.
+     */
+    private int maximumIterations = 50;
+    /**
+     * Desired precision.
+     */
+    private double desiredPrecision = Double.MIN_VALUE;
+    /**
+     * Achieved precision.
+     */
+    private double precision;
+
+
+    /**
+     * Generic constructor.
+     */
+    public IterativeProcess() {
+    }
+
+    /**
+     * Performs the iterative process.
+     * Note: this method does not return anything because Java does not
+     * allow mixing double, int, or objects
+     */
+    public void evaluate() {
+        iterations = 0;
+        initializeIterations();
+        while (iterations++ < maximumIterations) {
+               step();
+            precision = getPrecision();
+            if (hasConverged())
+                break;
+        }
+        finalizeIterations();
+    }
+
+    /**
+     * Evaluate the result of the current iteration.
+     */
+    abstract public void step();
+
+    /**
+     * Perform eventual clean-up operations
+     * (must be implement by subclass when needed).
+     */
+    protected void finalizeIterations() {
+    }
+
+    /**
+     * Returns the desired precision.
+     */
+    public double getDesiredPrecision() {
+        return desiredPrecision;
+    }
+
+    /**
+     * Returns the number of iterations performed.
+     */
+    public int getIterations() {
+        return iterations;
+    }
+
+    /**
+     * Returns the maximum allowed number of iterations.
+     */
+    public int getMaximumIterations() {
+        return maximumIterations;
+    }
+
+    /**
+     * Returns the attained precision.
+     */
+    public double getPrecision() {
+        return precision;
+    }
+
+    /**
+        * @param precision the precision to set
+        */
+       public void setPrecision(double precision) {
+               this.precision = precision;
+       }
+
+       /**
+     *
+     * Check to see if the result has been attained.
+     * @return boolean
+     */
+    public boolean hasConverged() {
+        return precision < desiredPrecision;
+    }
+    
+    public boolean done() {
+       return hasConverged();
+    }
+
+    /**
+     * Initializes internal parameters to start the iterative process.
+     */
+    protected void initializeIterations() {
+    }
+
+    /**
+     * 
+     */
+    public void reset() {
+    }
+
+    /**
+     * @return double
+     * @param epsilon double
+     * @param x double
+     */
+    public double relativePrecision(double epsilon, double x) {
+        return x > desiredPrecision ? epsilon / x: epsilon;
+    }
+
+    /**
+     * Defines the desired precision.
+     */
+    public void setDesiredPrecision(double prec) throws IllegalArgumentException {
+        if (prec <= 0)
+            throw new IllegalArgumentException("Non-positive precision: " + prec);
+        desiredPrecision = prec;
+    }
+
+    /**
+     * Defines the maximum allowed number of iterations.
+     */
+    public void setMaximumIterations(int maxIter) throws IllegalArgumentException {
+        if (maxIter < 1)
+            throw new IllegalArgumentException("Non-positive maximum iteration: " + maxIter);
+        maximumIterations = maxIter;
+    }
+}
\ No newline at end of file
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/KMeansClusterer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/KMeansClusterer.java
new file mode 100644 (file)
index 0000000..dce550f
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+/*
+ * Created on Aug 9, 2004
+ *
+ */
+package edu.uci.ics.jung.algorithms.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+
+
+
+/**
+ * Groups items into a specified number of clusters, based on their proximity in
+ * d-dimensional space, using the k-means algorithm. Calls to
+ * <code>cluster</code> will terminate when either of the two following
+ * conditions is true:
+ * <ul>
+ * <li/>the number of iterations is &gt; <code>max_iterations</code> 
+ * <li/>none of the centroids has moved as much as <code>convergence_threshold</code>
+ * since the previous iteration
+ * </ul>
+ * 
+ * @author Joshua O'Madadhain
+ */
+public class KMeansClusterer<T>
+{
+    protected int max_iterations;
+    protected double convergence_threshold;
+    protected Random rand;
+
+    /**
+     * Creates an instance whose termination conditions are set according
+     * to the parameters.  
+     */
+    public KMeansClusterer(int max_iterations, double convergence_threshold)
+    {
+        this.max_iterations = max_iterations;
+        this.convergence_threshold = convergence_threshold;
+        this.rand = new Random();
+    }
+
+    /**
+     * Creates an instance with max iterations of 100 and convergence threshold
+     * of 0.001.
+     */
+    public KMeansClusterer()
+    {
+        this(100, 0.001);
+    }
+
+    /**
+     * Returns the maximum number of iterations.
+     */
+    public int getMaxIterations()
+    {
+        return max_iterations;
+    }
+
+    /**
+     * Sets the maximum number of iterations.
+     */
+    public void setMaxIterations(int max_iterations)
+    {
+        if (max_iterations < 0)
+            throw new IllegalArgumentException("max iterations must be >= 0");
+
+        this.max_iterations = max_iterations;
+    }
+
+    /**
+     * Returns the convergence threshold.
+     */
+    public double getConvergenceThreshold()
+    {
+        return convergence_threshold;
+    }
+
+    /**
+     * Sets the convergence threshold.
+     * @param convergence_threshold
+     */
+    public void setConvergenceThreshold(double convergence_threshold)
+    {
+        if (convergence_threshold <= 0)
+            throw new IllegalArgumentException("convergence threshold " +
+                "must be > 0");
+
+        this.convergence_threshold = convergence_threshold;
+    }
+
+    /**
+     * Returns a <code>Collection</code> of clusters, where each cluster is
+     * represented as a <code>Map</code> of <code>Objects</code> to locations
+     * in d-dimensional space.
+     * @param object_locations  a map of the Objects to cluster, to
+     * <code>double</code> arrays that specify their locations in d-dimensional space.
+     * @param num_clusters  the number of clusters to create
+     * @throws NotEnoughClustersException
+     */
+    @SuppressWarnings("unchecked")
+    public Collection<Map<T, double[]>> cluster(Map<T, double[]> object_locations, int num_clusters)
+    {
+        if (object_locations == null || object_locations.isEmpty())
+            throw new IllegalArgumentException("'objects' must be non-empty");
+
+        if (num_clusters < 2 || num_clusters > object_locations.size())
+            throw new IllegalArgumentException("number of clusters " +
+                "must be >= 2 and <= number of objects (" +
+                object_locations.size() + ")");
+
+
+        Set<double[]> centroids = new HashSet<double[]>();
+
+        Object[] obj_array = object_locations.keySet().toArray();
+        Set<T> tried = new HashSet<T>();
+
+        // create the specified number of clusters
+        while (centroids.size() < num_clusters && tried.size() < object_locations.size())
+        {
+            T o = (T)obj_array[(int)(rand.nextDouble() * obj_array.length)];
+            tried.add(o);
+            double[] mean_value = object_locations.get(o);
+            boolean duplicate = false;
+            for (double[] cur : centroids)
+            {
+                if (Arrays.equals(mean_value, cur))
+                    duplicate = true;
+            }
+            if (!duplicate)
+                centroids.add(mean_value);
+        }
+
+        if (tried.size() >= object_locations.size())
+            throw new NotEnoughClustersException();
+
+        // put items in their initial clusters
+        Map<double[], Map<T, double[]>> clusterMap = assignToClusters(object_locations, centroids);
+
+        // keep reconstituting clusters until either
+        // (a) membership is stable, or
+        // (b) number of iterations passes max_iterations, or
+        // (c) max movement of any centroid is <= convergence_threshold
+        int iterations = 0;
+        double max_movement = Double.POSITIVE_INFINITY;
+        while (iterations++ < max_iterations && max_movement > convergence_threshold)
+        {
+            max_movement = 0;
+            Set<double[]> new_centroids = new HashSet<double[]>();
+            // calculate new mean for each cluster
+            for (Map.Entry<double[], Map<T, double[]>> entry : clusterMap.entrySet())
+            {
+                double[] centroid = entry.getKey();
+                Map<T, double[]> elements = entry.getValue();
+                ArrayList<double[]> locations = new ArrayList<double[]>(elements.values());
+
+                double[] mean = DiscreteDistribution.mean(locations);
+                max_movement = Math.max(max_movement,
+                    Math.sqrt(DiscreteDistribution.squaredError(centroid, mean)));
+                new_centroids.add(mean);
+            }
+
+            // TODO: check membership of clusters: have they changed?
+
+            // regenerate cluster membership based on means
+            clusterMap = assignToClusters(object_locations, new_centroids);
+        }
+        return clusterMap.values();
+    }
+
+    /**
+     * Assigns each object to the cluster whose centroid is closest to the
+     * object.
+     * @param object_locations  a map of objects to locations
+     * @param centroids         the centroids of the clusters to be formed
+     * @return a map of objects to assigned clusters
+     */
+    protected Map<double[], Map<T, double[]>> assignToClusters(Map<T, double[]> object_locations, Set<double[]> centroids)
+    {
+        Map<double[], Map<T, double[]>> clusterMap = new HashMap<double[], Map<T, double[]>>();
+        for (double[] centroid : centroids)
+            clusterMap.put(centroid, new HashMap<T, double[]>());
+
+        for (Map.Entry<T, double[]> object_location : object_locations.entrySet())
+        {
+            T object = object_location.getKey();
+            double[] location = object_location.getValue();
+
+            // find the cluster with the closest centroid
+            Iterator<double[]> c_iter = centroids.iterator();
+            double[] closest = c_iter.next();
+            double distance = DiscreteDistribution.squaredError(location, closest);
+
+            while (c_iter.hasNext())
+            {
+                double[] centroid = c_iter.next();
+                double dist_cur = DiscreteDistribution.squaredError(location, centroid);
+                if (dist_cur < distance)
+                {
+                    distance = dist_cur;
+                    closest = centroid;
+                }
+            }
+            clusterMap.get(closest).put(object, location);
+        }
+
+        return clusterMap;
+    }
+
+    /**
+     * Sets the seed used by the internal random number generator.
+     * Enables consistent outputs.
+     */
+    public void setSeed(int random_seed)
+    {
+        this.rand = new Random(random_seed);
+    }
+
+    /**
+     * An exception that indicates that the specified data points cannot be
+     * clustered into the number of clusters requested by the user.
+     * This will happen if and only if there are fewer distinct points than
+     * requested clusters.  (If there are fewer total data points than
+     * requested clusters, <code>IllegalArgumentException</code> will be thrown.)
+     *
+     * @author Joshua O'Madadhain
+     */
+    @SuppressWarnings("serial")
+    public static class NotEnoughClustersException extends RuntimeException
+    {
+        @Override
+        public String getMessage()
+        {
+            return "Not enough distinct points in the input data set to form " +
+                    "the requested number of clusters";
+        }
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/MapBinaryHeap.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/MapBinaryHeap.java
new file mode 100644 (file)
index 0000000..bd00a82
--- /dev/null
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+/*
+ * 
+ * Created on Oct 29, 2003
+ */
+package edu.uci.ics.jung.algorithms.util;
+
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.Vector;
+
+import org.apache.commons.collections15.IteratorUtils;
+
+/**
+ * An array-based binary heap implementation of a priority queue, 
+ * which also provides
+ * efficient <code>update()</code> and <code>contains</code> operations.
+ * It contains extra infrastructure (a hash table) to keep track of the 
+ * position of each element in the array; thus, if the key value of an element
+ * changes, it may be "resubmitted" to the heap via <code>update</code>
+ * so that the heap can reposition it efficiently, as necessary.  
+ * 
+ * @author Joshua O'Madadhain
+ */
+public class MapBinaryHeap<T>
+    extends AbstractCollection<T> 
+    implements Queue<T>
+{
+       private Vector<T> heap = new Vector<T>();            // holds the heap as an implicit binary tree
+    private Map<T,Integer> object_indices = new HashMap<T,Integer>(); // maps each object in the heap to its index in the heap
+    private Comparator<T> comp;
+    private final static int TOP = 0;   // the index of the top of the heap
+
+    /**
+     * Creates a <code>MapBinaryHeap</code> whose heap ordering
+     * is based on the ordering of the elements specified by <code>c</code>.
+     */
+    public MapBinaryHeap(Comparator<T> comp)
+    {
+        initialize(comp);
+    }
+    
+    /**
+     * Creates a <code>MapBinaryHeap</code> whose heap ordering
+     * will be based on the <i>natural ordering</i> of the elements,
+     * which must be <code>Comparable</code>.
+     */
+    public MapBinaryHeap()
+    {
+        initialize(new ComparableComparator());
+    }
+
+    /**
+     * Creates a <code>MapBinaryHeap</code> based on the specified
+     * collection whose heap ordering
+     * will be based on the <i>natural ordering</i> of the elements,
+     * which must be <code>Comparable</code>.
+     */
+    public MapBinaryHeap(Collection<T> c)
+    {
+       this();
+        addAll(c);
+    }
+    
+    /**
+     * Creates a <code>MapBinaryHeap</code> based on the specified collection 
+     * whose heap ordering
+     * is based on the ordering of the elements specified by <code>c</code>.
+     */
+    public MapBinaryHeap(Collection<T> c, Comparator<T> comp)
+    {
+        this(comp);
+        addAll(c);
+    }
+    
+    private void initialize(Comparator<T> comp)
+    {
+        this.comp = comp;
+        clear();
+    }
+    
+       /**
+        * @see Collection#clear()
+        */
+       @Override
+       public void clear()
+       {
+        object_indices.clear();
+        heap.clear();
+       }
+
+       /**
+        * Inserts <code>o</code> into this collection.
+        */
+       @Override
+       public boolean add(T o)
+       {
+        int i = heap.size();  // index 1 past the end of the heap
+        heap.setSize(i+1);
+        percolateUp(i, o);
+        return true;
+       }
+
+       /**
+        * Returns <code>true</code> if this collection contains no elements, and
+     * <code>false</code> otherwise.
+        */
+       @Override
+       public boolean isEmpty()
+       {
+        return heap.isEmpty();
+       }
+
+       /**
+        * Returns the element at the top of the heap; does not
+     * alter the heap.
+        */
+       public T peek()
+       {
+               if (heap.size() > 0)
+                       return heap.elementAt(TOP);
+               else
+                       return null;
+       }
+
+       /**
+        * Removes the element at the top of this heap, and returns it.
+        * @deprecated Use {@link MapBinaryHeap#poll()} 
+        * or {@link MapBinaryHeap#remove()} instead.
+        */
+       @Deprecated
+    public T pop() throws NoSuchElementException
+       {
+               return this.remove();
+       }
+
+    /**
+     * Returns the size of this heap.
+     */
+    @Override
+    public int size() 
+    {
+        return heap.size();
+    }
+       
+    /**
+     * Informs the heap that this object's internal key value has been
+     * updated, and that its place in the heap may need to be shifted
+     * (up or down).
+     * @param o
+     */
+    public void update(T o)
+    {
+        // Since we don't know whether the key value increased or 
+        // decreased, we just percolate up followed by percolating down;
+        // one of the two will have no effect.
+        
+        int cur = object_indices.get(o).intValue(); // current index
+        int new_idx = percolateUp(cur, o);
+        percolateDown(new_idx);
+    }
+
+    /**
+     * @see Collection#contains(java.lang.Object)
+     */
+    @Override
+    public boolean contains(Object o)
+    {
+        return object_indices.containsKey(o);
+    }
+    
+    /**
+     * Moves the element at position <code>cur</code> closer to 
+     * the bottom of the heap, or returns if no further motion is
+     * necessary.  Calls itself recursively if further motion is 
+     * possible.
+     */
+    private void percolateDown(int cur)
+    {
+        int left = lChild(cur);
+        int right = rChild(cur);
+        int smallest;
+
+        if ((left < heap.size()) && 
+                       (comp.compare(heap.elementAt(left), heap.elementAt(cur)) < 0)) {
+                       smallest = left;
+               } else {
+                       smallest = cur;
+               }
+
+        if ((right < heap.size()) && 
+                       (comp.compare(heap.elementAt(right), heap.elementAt(smallest)) < 0)) {
+                       smallest = right;
+               }
+
+        if (cur != smallest)
+        {
+            swap(cur, smallest);
+            percolateDown(smallest);
+        }
+    }
+
+    /**
+     * Moves the element <code>o</code> at position <code>cur</code> 
+     * as high as it can go in the heap.  Returns the new position of the 
+     * element in the heap.
+     */
+    private int percolateUp(int cur, T o)
+    {
+        int i = cur;
+        
+        while ((i > TOP) && (comp.compare(heap.elementAt(parent(i)), o) > 0))
+        {
+            T parentElt = heap.elementAt(parent(i));
+            heap.setElementAt(parentElt, i);
+            object_indices.put(parentElt, new Integer(i));  // reset index to i (new location)
+            i = parent(i);
+        }
+        
+        // place object in heap at appropriate place
+        object_indices.put(o, new Integer(i));
+        heap.setElementAt(o, i);
+
+        return i;
+    }
+    
+    /**
+     * Returns the index of the left child of the element at 
+     * index <code>i</code> of the heap.
+     * @param i
+     * @return the index of the left child of the element at 
+     * index <code>i</code> of the heap
+     */
+    private int lChild(int i)
+    {
+       return (i<<1) + 1;
+    }
+    
+    /**
+     * Returns the index of the right child of the element at 
+     * index <code>i</code> of the heap.
+     * @param i
+     * @return the index of the right child of the element at 
+     * index <code>i</code> of the heap
+     */
+    private int rChild(int i)
+    {
+       return (i<<1) + 2;
+    }
+    
+    /**
+     * Returns the index of the parent of the element at 
+     * index <code>i</code> of the heap.
+     * @param i
+     * @return the index of the parent of the element at index i of the heap
+     */
+    private int parent(int i)
+    {
+       return (i-1)>>1;
+    }
+    
+    /**
+     * Swaps the positions of the elements at indices <code>i</code>
+     * and <code>j</code> of the heap.
+     * @param i
+     * @param j
+     */
+    private void swap(int i, int j)
+    {
+        T iElt = heap.elementAt(i);
+        T jElt = heap.elementAt(j);
+
+        heap.setElementAt(jElt, i);
+        object_indices.put(jElt, new Integer(i));
+
+        heap.setElementAt(iElt, j);
+        object_indices.put(iElt, new Integer(j));
+    }
+    
+    /**
+     * Comparator used if none is specified in the constructor.
+     * @author Joshua O'Madadhain
+     */
+    private class ComparableComparator implements Comparator<T>
+    {
+        /**
+         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+         */
+        @SuppressWarnings("unchecked")
+        public int compare(T arg0, T arg1)
+        {
+            if (!(arg0 instanceof Comparable) || !(arg1 instanceof Comparable))
+                throw new IllegalArgumentException("Arguments must be Comparable");
+            
+            return ((Comparable<T>)arg0).compareTo(arg1);
+        }
+    }
+
+    /**
+     * Returns an <code>Iterator</code> that does not support modification
+     * of the heap.
+     */
+    @Override
+    public Iterator<T> iterator()
+    {
+        return IteratorUtils.<T>unmodifiableIterator(heap.iterator());
+    }
+
+    /**
+     * This data structure does not support the removal of arbitrary elements.
+     */
+    @Override
+    public boolean remove(Object o)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * This data structure does not support the removal of arbitrary elements.
+     */
+    @Override
+    public boolean removeAll(Collection<?> c)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * This data structure does not support the removal of arbitrary elements.
+     */
+    @Override
+    public boolean retainAll(Collection<?> c)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+       public T element() throws NoSuchElementException 
+       {
+               T top = this.peek();
+               if (top == null) 
+                       throw new NoSuchElementException();
+               return top;
+       }
+
+       public boolean offer(T o) 
+       {
+               return add(o);
+       }
+
+       public T poll() 
+       {
+        T top = this.peek();
+        if (top != null)
+        {
+               T bottom_elt = heap.lastElement();
+               heap.setElementAt(bottom_elt, TOP);
+               object_indices.put(bottom_elt, new Integer(TOP));
+               
+               heap.setSize(heap.size() - 1);  // remove the last element
+               if (heap.size() > 1)
+                       percolateDown(TOP);
+       
+               object_indices.remove(top);
+        }
+        return top;
+       }
+
+       public T remove() 
+       {
+               T top = this.poll();
+               if (top == null)
+                       throw new NoSuchElementException();
+               return top;
+       }
+
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/MapSettableTransformer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/MapSettableTransformer.java
new file mode 100644 (file)
index 0000000..1aa7d50
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Created on Aug 5, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.util;
+
+import java.util.Map;
+
+
+/**
+ * A <code>SettableTransformer</code> that operates on an underlying <code>Map</code> instance.
+ * Similar to <code>MapTransformer</code>.
+ * 
+ * @author Joshua O'Madadhain
+ */
+public class MapSettableTransformer<I, O> implements SettableTransformer<I, O>
+{
+    protected Map<I,O> map;
+    
+    /**
+     * Creates an instance based on <code>m</code>.
+     */
+    public MapSettableTransformer(Map<I,O> m)
+    {
+        this.map = m;
+    }
+
+    public O transform(I input)
+    {
+        return map.get(input);
+    }
+
+    public void set(I input, O output)
+    {
+        map.put(input, output);
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/SelfLoopEdgePredicate.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/SelfLoopEdgePredicate.java
new file mode 100644 (file)
index 0000000..a92c3b8
--- /dev/null
@@ -0,0 +1,23 @@
+package edu.uci.ics.jung.algorithms.util;
+
+import org.apache.commons.collections15.Predicate;
+
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.util.Context;
+import edu.uci.ics.jung.graph.util.Pair;
+
+/**
+ * A <code>Predicate</code> that returns <code>true</code> if the input edge's 
+ * endpoints in the input graph are identical.  (Thus, an edge which connects
+ * its sole incident vertex to itself).
+ *
+ * @param <V>
+ * @param <E>
+ */
+public class SelfLoopEdgePredicate<V,E> implements Predicate<Context<Graph<V,E>,E>> {
+
+    public boolean evaluate(Context<Graph<V,E>,E> context) {
+        Pair<V> endpoints = context.graph.getEndpoints(context.element);
+        return endpoints.getFirst().equals(endpoints.getSecond());
+    }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/SettableTransformer.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/SettableTransformer.java
new file mode 100644 (file)
index 0000000..5e5168a
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Created on Aug 5, 2007
+ *
+ * Copyright (c) 2007, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.util;
+
+import org.apache.commons.collections15.Transformer;
+
+/**
+ * An interface for classes that can set the value to be returned (from <code>transform()</code>)
+ * when invoked on a given input.
+ * 
+ * @author Joshua O'Madadhain
+ */
+public interface SettableTransformer<I, O> extends Transformer<I, O>
+{
+    /**
+     * Sets the value (<code>output</code>) to be returned by a call to 
+     * <code>transform(input)</code>).
+     * @param input
+     * @param output
+     */
+    public void set(I input, O output);
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/WeightedChoice.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/WeightedChoice.java
new file mode 100644 (file)
index 0000000..d9590b2
--- /dev/null
@@ -0,0 +1,193 @@
+/**
+ * Copyright (c) 2009, the JUNG Project and the Regents of the University 
+ * of California
+ * All rights reserved.
+ *
+ * This software is open-source under the BSD license; see either
+ * "license.txt" or
+ * http://jung.sourceforge.net/license.txt for a description.
+ * Created on Jan 8, 2009
+ * 
+ */
+package edu.uci.ics.jung.algorithms.util;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Random;
+
+/**
+ * Selects items according to their probability in an arbitrary probability 
+ * distribution.  The distribution is specified by a {@code Map} from
+ * items (of type {@code T}) to weights of type {@code Number}, supplied
+ * to the constructor; these weights are normalized internally to act as 
+ * probabilities.
+ * 
+ * <p>This implementation selects items in O(1) time, and requires O(n) space.
+ * 
+ * @author Joshua O'Madadhain
+ */
+public class WeightedChoice<T> 
+{
+       private List<ItemPair> item_pairs;
+       private Random random;
+       
+       /**
+        * The default minimum value that is treated as a valid probability 
+        * (as opposed to rounding error from floating-point operations). 
+        */
+       public static final double DEFAULT_THRESHOLD = 0.00000000001;
+
+       /**
+        * Equivalent to {@code this(item_weights, new Random(), DEFAULT_THRESHOLD)}.
+        * @param item_weights
+        */
+       public WeightedChoice(Map<T, ? extends Number> item_weights)
+       {
+               this(item_weights, new Random(), DEFAULT_THRESHOLD);
+       }
+
+       /**
+        * Equivalent to {@code this(item_weights, new Random(), threshold)}.
+        */
+       public WeightedChoice(Map<T, ? extends Number> item_weights, double threshold)
+       {
+               this(item_weights, new Random(), threshold);
+       }
+       
+       /**
+        * Equivalent to {@code this(item_weights, random, DEFAULT_THRESHOLD)}.
+        */
+       public WeightedChoice(Map<T, ? extends Number> item_weights, Random random)
+       {
+               this(item_weights, random, DEFAULT_THRESHOLD);
+       }
+       
+       /**
+        * Creates an instance with the specified mapping from items to weights,
+        * random number generator, and threshold value.
+        * 
+        * <p>The mapping defines the weight for each item to be selected; this 
+        * will be proportional to the probability of its selection.
+        * <p>The random number generator specifies the mechanism which will be
+        * used to provide uniform integer and double values.
+        * <p>The threshold indicates default minimum value that is treated as a valid 
+        * probability (as opposed to rounding error from floating-point operations). 
+        */
+       public WeightedChoice(Map<T, ? extends Number> item_weights, Random random,
+                       double threshold) 
+       {
+               if (item_weights.isEmpty())
+                       throw new IllegalArgumentException("Item weights must be non-empty");
+               
+               int item_count = item_weights.size();
+               item_pairs = new ArrayList<ItemPair>(item_count);
+               
+               double sum = 0;
+               for (Map.Entry<T, ? extends Number> entry : item_weights.entrySet())
+               {
+                       double value = entry.getValue().doubleValue();
+                       if (value <= 0)
+                               throw new IllegalArgumentException("Weights must be > 0");
+                       sum += value;
+               }
+        double bucket_weight = 1.0 / item_weights.size();
+               
+               Queue<ItemPair> light_weights = new LinkedList<ItemPair>();
+               Queue<ItemPair> heavy_weights = new LinkedList<ItemPair>();
+               for (Map.Entry<T, ? extends Number> entry : item_weights.entrySet())
+               {
+                       double value = entry.getValue().doubleValue() / sum;
+                       enqueueItem(entry.getKey(), value, bucket_weight, light_weights, heavy_weights);
+               }
+               
+               // repeat until both queues empty
+               while (!heavy_weights.isEmpty() || !light_weights.isEmpty())
+               {
+                       ItemPair heavy_item = heavy_weights.poll();
+                       ItemPair light_item = light_weights.poll();
+                       double light_weight = 0;
+                       T light = null;
+                       T heavy = null;
+                       if (light_item != null)
+                       {
+                               light_weight = light_item.weight;
+                               light = light_item.light;
+                       }
+                       if (heavy_item != null)
+                       {
+                               heavy = heavy_item.heavy;
+                               // put the 'left over' weight from the heavy item--what wasn't
+                               // needed to make up the difference between the light weight and
+                               // 1/n--back in the appropriate queue
+                               double new_weight = heavy_item.weight - (bucket_weight - light_weight);
+                               if (new_weight > threshold)
+                                       enqueueItem(heavy, new_weight, bucket_weight, light_weights, heavy_weights);
+                       }
+                       light_weight *= item_count;
+                       
+                       item_pairs.add(new ItemPair(light, heavy, light_weight));
+               }
+               
+               this.random = random;
+       }
+
+       /**
+        * Adds key/value to the appropriate queue.  Keys with values less than
+        * the threshold get added to {@code light_weights}, all others get added
+        * to {@code heavy_weights}.
+        */
+       private void enqueueItem(T key, double value, double threshold, 
+                       Queue<ItemPair> light_weights, Queue<ItemPair> heavy_weights)
+       {
+               if (value < threshold) 
+                       light_weights.offer(new ItemPair(key, null, value));
+               else
+                       heavy_weights.offer(new ItemPair(null, key, value));
+       }
+       
+       /**
+        * Sets the seed used by the internal random number generator.
+        */
+       public void setRandomSeed(long seed)
+       {
+               this.random.setSeed(seed);
+       }
+       
+       /**
+        * Retrieves an item with probability proportional to its weight in the
+        * {@code Map} provided in the input.
+        */
+       public T nextItem()
+       {
+               ItemPair item_pair = item_pairs.get(random.nextInt(item_pairs.size()));
+               if (random.nextDouble() < item_pair.weight)
+                       return item_pair.light;
+               return item_pair.heavy;
+       }
+       
+       /**
+        * Manages light object/heavy object/light conditional probability tuples.
+        */
+       private class ItemPair 
+       {
+               T light;
+               T heavy;
+               double weight;
+               
+               private ItemPair(T light, T heavy, double weight)
+               {
+                       this.light = light;
+                       this.heavy = heavy;
+                       this.weight = weight;
+               }
+               
+               @Override
+        public String toString()
+               {
+                       return String.format("[L:%s, H:%s, %.3f]", light, heavy, weight);
+               }
+       }
+}
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/package.html b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/util/package.html
new file mode 100644 (file)
index 0000000..58c5f59
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html
+
+ Copyright © 2003 The Regents of the University of California. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies. This software program and documentation are copyrighted by The Regents of the University of California ("The University of California").
+
+THE SOFTWARE PROGRAM AND DOCUMENTATION ARE SUPPLIED "AS IS," WITHOUT ANY ACCOMPANYING SERVICES FROM THE UNIVERSITY OF CALFORNIA. FURTHERMORE, THE UNIVERSITY OF CALIFORNIA DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE. THE END-USER UNDERSTANDS THAT THE PROGRAM WAS DEVELOPED FOR RESEARCH PURPOSES AND IS ADVISED NOT TO RELY EXCLUSIVELY ON THE PROGRAM FOR ANY REASON.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+-->
+</head>
+<body>
+
+Provides general algorithmic utilities.  These include:
+<ul>
+<li/><code>DiscreteDistribution</code>: calculates statistical measures on 
+discrete probability distributions represented as <code>double</code> arrays
+<li/><code>KMeansClusterer</code>: uses the k-means algorithm to cluster 
+points in d-dimensional space into k clusters 
+<li/><code>MapBinaryHeap</code>: a binary heap implementation that permits
+efficient element access and update operations
+<li/><code>RandomLocationTransformer</code>: a class that randomly assigns
+2D coordinates to items (default initializer for iterative Layouts)
+<li/><code>SettableTransformer</code>: an extension of <code>Transformer</code>
+that allows mutation of the transformation
+</ul>
+
+</body>
+</html>
diff --git a/third-party/openflowj/LICENSE b/third-party/openflowj/LICENSE
new file mode 100644 (file)
index 0000000..ee6da46
--- /dev/null
@@ -0,0 +1,29 @@
+Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
+University
+
+We are making the OpenFlow specification and associated documentation
+(Software) available for public use and benefit with the expectation that
+others will use, modify and enhance the Software and contribute those
+enhancements back to the community. However, since we would like to make the
+Software available for broadest use, with as few restrictions as possible
+permission is hereby granted, free of charge, to any person obtaining a copy of
+this Software to deal in the Software under the copyrights without restriction,
+including without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to permit
+persons to whom the Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+The name and trademarks of copyright holder(s) may NOT be used in advertising
+or publicity pertaining to the Software or any derivatives without specific,
+written prior permission.
diff --git a/third-party/openflowj/Makefile b/third-party/openflowj/Makefile
new file mode 100644 (file)
index 0000000..b803071
--- /dev/null
@@ -0,0 +1,19 @@
+# Because I am old and crotchety and my fingers can't stop from running 
+#      `make` commands
+all:
+       ant
+
+run:
+       ant run
+
+doc: 
+       ant javadoc
+
+tests:
+       ant tests
+
+count: 
+       @find . -name \*.java | xargs wc -l | sort -n
+
+clean:
+       ant clean
diff --git a/third-party/openflowj/README b/third-party/openflowj/README
new file mode 100644 (file)
index 0000000..6fffebe
--- /dev/null
@@ -0,0 +1,16 @@
+OpenFlow Java - v1.0.0 
+
+A Java implementation of low-level OpenFlow packet marshalling/unmarshalling
+and IO operations. Implements v1.0 of the OpenFlow specification at
+http://www.openflow.org.
+
+    - David Erickson (daviderickson@cs.stanford.edu)
+    - Rob Sherwood (rob.sherwood@stanford.edu)
+
+Building requires Maven 2.x+ (http://maven.apache.org/).
+
+To build:
+    mvn package
+
+To build javadocs:
+    mvn javadoc:javadoc
diff --git a/third-party/openflowj/eclipse_codestyle.xml b/third-party/openflowj/eclipse_codestyle.xml
new file mode 100644 (file)
index 0000000..6b661c6
--- /dev/null
@@ -0,0 +1,269 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<profiles version="11">
+<profile kind="CodeFormatterProfile" name="OpenFlowJ" version="11">
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
+<setting id="org.eclipse.jdt.core.compiler.source" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
+<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
+</profile>
+</profiles>
diff --git a/third-party/openflowj/lib/commons-cli-1.2.jar b/third-party/openflowj/lib/commons-cli-1.2.jar
new file mode 100644 (file)
index 0000000..ce4b9ff
Binary files /dev/null and b/third-party/openflowj/lib/commons-cli-1.2.jar differ
diff --git a/third-party/openflowj/lib/junit-4.8.1.jar b/third-party/openflowj/lib/junit-4.8.1.jar
new file mode 100644 (file)
index 0000000..524cd65
Binary files /dev/null and b/third-party/openflowj/lib/junit-4.8.1.jar differ
diff --git a/third-party/openflowj/pom.xml b/third-party/openflowj/pom.xml
new file mode 100644 (file)
index 0000000..4daddf1
--- /dev/null
@@ -0,0 +1,137 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.opendaylight.controller.thirdparty</groupId>
+  <artifactId>org.openflow.openflowj</artifactId>
+  <version>1.0.2-SNAPSHOT</version>
+  <name>OpenFlow Java</name>
+  <description>A Java implemention of the OpenFlow v1.0 protocol</description>
+
+  <!-- Get some common settings for the project we are using it in -->
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.thirdparty</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <relativePath>../commons/thirdparty</relativePath>
+  </parent>
+  
+  <developers>
+    <developer>
+      <name>David Erickson</name>
+      <email>daviderickson@cs.stanford.edu</email>
+    </developer>
+    <developer>
+      <name>Rob Sherwood</name>
+      <email>rob.sherwood@stanford.edu</email>
+    </developer>
+  </developers>
+  <packaging>bundle</packaging>
+  <url>http://www.openflow.org</url>
+  <licenses>
+    <license>
+      <name>The OpenFlow License</name>
+      <url>http://www.openflowswitch.org/wp/legal/</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+  <scm>
+    <connection>scm:git://gitosis.stanford.edu:openflowj.git</connection>
+    <url>https://openflow.stanford.edu/fisheye/browse/OpenFlowJ</url>
+  </scm>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+  <!-- For GPG release signing, use mvn release:perform -->
+  <profiles>
+    <profile>
+      <id>release-sign-artifacts</id>
+      <activation>
+        <property>
+          <name>performRelease</name>
+          <value>true</value>
+        </property>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-gpg-plugin</artifactId>
+            <version>1.1</version>
+            <executions>
+              <execution>
+                <id>sign-artifacts</id>
+                <phase>verify</phase>
+                <goals>
+                  <goal>sign</goal>
+                </goals>
+              </execution>
+            </executions>
+            <configuration>
+              <mavenExecutorId>forked-path</mavenExecutorId>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+  <build>
+    <plugins>
+      <plugin>
+       <groupId>org.apache.felix</groupId>
+       <artifactId>maven-bundle-plugin</artifactId>
+       <version>2.3.6</version>
+       <extensions>true</extensions>
+       <configuration>
+         <instructions>
+           <Export-Package>
+             org.openflow.example;version="1.0.1";
+             uses:="org.openflow.example.cli,
+             org.openflow.protocol,
+             org.openflow.io,
+             org.openflow.protocol.factory",
+             org.openflow.io;version="1.0.1";
+             uses:="org.openflow.protocol,
+             org.openflow.protocol.factory",
+             org.openflow.protocol;version="1.0.1";
+             uses:="org.openflow.protocol.statistics,
+             org.openflow.protocol,
+             org.openflow.protocol.factory",
+             org.openflow.protocol.action;version="1.0.1";
+             uses:="org.openflow.protocol",
+             org.openflow.protocol.factory;version="1.0.1";
+             uses:="org.openflow.protocol.statistics,
+             org.openflow.protocol,
+             org.openflow.protocol.action,
+             org.openflow.protocol.queue",
+             org.openflow.protocol.queue;version="1.0.2";
+             uses:="org.openflow.protocol,
+             org.openflow.protocol.factory",
+             org.openflow.protocol.statistics;version="1.0.1";
+             uses:="org.openflow.protocol,
+             org.openflow.protocol.factory",
+             org.openflow.util;version="1.0.1"
+           </Export-Package>
+         </instructions>
+       </configuration>
+      </plugin>
+      <plugin>
+       <groupId>org.apache.maven.plugins</groupId>
+       <artifactId>maven-compiler-plugin</artifactId>
+       <version>2.3.2</version>
+       <configuration>
+         <source>1.6</source>
+         <target>1.6</target>
+       </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/third-party/openflowj/src/main/java/org/openflow/example/SelectListener.java b/third-party/openflowj/src/main/java/org/openflow/example/SelectListener.java
new file mode 100644 (file)
index 0000000..16fa109
--- /dev/null
@@ -0,0 +1,21 @@
+/**
+ *
+ */
+package org.openflow.example;
+
+import java.io.IOException;
+import java.nio.channels.SelectionKey;
+
+/**
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ *
+ */
+public interface SelectListener {
+    /**
+     * Tell the select listener that an event took place on the passed object
+     * @param key the key used on the select
+     * @param arg some parameter passed by the caller when registering
+     * @throws IOException
+     */
+    void handleEvent(SelectionKey key, Object arg) throws IOException;
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/example/SelectLoop.java b/third-party/openflowj/src/main/java/org/openflow/example/SelectLoop.java
new file mode 100644 (file)
index 0000000..b7927d8
--- /dev/null
@@ -0,0 +1,156 @@
+package org.openflow.example;
+
+import java.io.IOException;
+import java.nio.channels.CancelledKeyException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.Iterator;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/***
+ * Dirt simple SelectLoop for simple java controller
+ */
+
+
+public class SelectLoop {
+    protected SelectListener callback;
+    protected boolean dontStop;
+    protected Object registrationLock;
+    protected int registrationRequests = 0;
+    protected Queue<Object[]> registrationQueue;
+    protected Selector selector;
+    protected long timeout;
+
+    public SelectLoop(SelectListener cb) throws IOException {
+        callback = cb;
+        dontStop = true;
+        selector = SelectorProvider.provider().openSelector();
+        registrationLock = new Object();
+        registrationQueue = new ConcurrentLinkedQueue<Object[]>();
+        timeout = 0;
+    }
+
+    /**
+     * Initializes this SelectLoop
+     * @param cb the callback to call when select returns
+     * @param timeout the timeout value in milliseconds that select will be
+     *        called with
+     * @throws IOException
+     */
+    public SelectLoop(SelectListener cb, long timeout) throws IOException {
+        callback = cb;
+        dontStop = true;
+        selector = SelectorProvider.provider().openSelector();
+        registrationLock = new Object();
+        registrationQueue = new ConcurrentLinkedQueue<Object[]>();
+        this.timeout = timeout;
+    }
+
+    public void register(SelectableChannel ch, int ops, Object arg)
+            throws ClosedChannelException {
+        registrationQueue.add(new Object[] {ch, ops, arg});
+    }
+
+    /**
+     * Registers the supplied SelectableChannel with this SelectLoop. Note this
+     * method blocks until registration proceeds.  It is advised that
+     * SelectLoop is intialized with a timeout value when using this method.
+     * @param ch the channel
+     * @param ops interest ops
+     * @param arg argument that will be returned with the SelectListener
+     * @return
+     * @throws ClosedChannelException
+     */
+    public synchronized SelectionKey registerBlocking(SelectableChannel ch, int ops, Object arg)
+            throws ClosedChannelException {
+        synchronized (registrationLock) {
+            registrationRequests++;
+        }
+        selector.wakeup();
+        SelectionKey key = ch.register(selector, ops, arg);
+        synchronized (registrationLock) {
+            registrationRequests--;
+            registrationLock.notifyAll();
+        }
+        return key;
+    }
+
+    /****
+     * Main top-level IO loop this dispatches all IO events and timer events
+     * together I believe this is fairly efficient
+     */
+    public void doLoop() throws IOException {
+        int nEvents;
+        processRegistrationQueue();
+
+        while (dontStop) {
+            nEvents = selector.select(timeout);
+            if (nEvents > 0) {
+                for (Iterator<SelectionKey> i = selector.selectedKeys()
+                        .iterator(); i.hasNext();) {
+                    SelectionKey sk = i.next();
+                    i.remove();
+
+                    if (!sk.isValid())
+                        continue;
+
+                    Object arg = sk.attachment();
+                    callback.handleEvent(sk, arg);
+                }
+            }
+
+            if (this.registrationQueue.size() > 0)
+                processRegistrationQueue();
+
+            if (registrationRequests > 0) {
+                synchronized (registrationLock) {
+                    while (registrationRequests > 0) {
+                        try {
+                            registrationLock.wait();
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    protected void processRegistrationQueue() {
+        // add any elements in queue
+        for (Iterator<Object[]> it = registrationQueue.iterator(); it.hasNext();) {
+            Object[] args = it.next();
+            SelectableChannel ch = (SelectableChannel) args[0];
+            try {
+                ch.register(selector, (Integer) args[1], args[2]);
+            } catch (CancelledKeyException cke) {
+               continue;
+            } catch (ClosedChannelException e) {
+            }
+            it.remove();
+        }
+    }
+
+    /**
+     * Force this select loop to return immediately and re-enter select, useful
+     * for example if a new item has been added to the select loop while it
+     * was already blocked.
+     */
+    public void wakeup() {
+       if (selector != null) {
+           selector.wakeup();
+       }
+    }
+
+    /**
+     * Shuts down this select loop, may return before it has fully shutdown
+     */
+    public void shutdown() {
+        this.dontStop = false;
+        wakeup();
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/example/SimpleController.java b/third-party/openflowj/src/main/java/org/openflow/example/SimpleController.java
new file mode 100644 (file)
index 0000000..e18e2f5
--- /dev/null
@@ -0,0 +1,321 @@
+/**
+ *
+ */
+package org.openflow.example;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.openflow.example.cli.Options;
+import org.openflow.example.cli.ParseException;
+import org.openflow.example.cli.SimpleCLI;
+import org.openflow.io.OFMessageAsyncStream;
+import org.openflow.protocol.OFEchoReply;
+import org.openflow.protocol.OFFlowMod;
+import org.openflow.protocol.OFMatch;
+import org.openflow.protocol.OFMessage;
+import org.openflow.protocol.OFPacketIn;
+import org.openflow.protocol.OFPacketOut;
+import org.openflow.protocol.OFPort;
+import org.openflow.protocol.OFType;
+import org.openflow.protocol.action.OFAction;
+import org.openflow.protocol.action.OFActionOutput;
+import org.openflow.protocol.factory.BasicFactory;
+import org.openflow.util.LRULinkedHashMap;
+import org.openflow.util.U16;
+
+/**
+ * @author Rob Sherwood (rob.sherwood@stanford.edu), David Erickson (daviderickson@cs.stanford.edu)
+ *
+ */
+public class SimpleController implements SelectListener {
+    protected ExecutorService es;
+    protected BasicFactory factory;
+    protected SelectLoop listenSelectLoop;
+    protected ServerSocketChannel listenSock;
+    protected List<SelectLoop> switchSelectLoops;
+    protected Map<SocketChannel,OFSwitch> switchSockets;
+    protected Integer threadCount;
+    protected int port;
+
+    protected class OFSwitch {
+        protected SocketChannel sock;
+        protected OFMessageAsyncStream stream;
+        protected Map<Integer, Short> macTable =
+            new LRULinkedHashMap<Integer, Short>(64001, 64000);
+
+        public OFSwitch(SocketChannel sock, OFMessageAsyncStream stream) {
+            this.sock = sock;
+            this.stream = stream;
+        }
+
+        public void handlePacketIn(OFPacketIn pi) {
+            // Build the Match
+            OFMatch match = new OFMatch();
+            match.loadFromPacket(pi.getPacketData(), pi.getInPort());
+            byte[] dlDst = match.getDataLayerDestination();
+            Integer dlDstKey = Arrays.hashCode(dlDst);
+            byte[] dlSrc = match.getDataLayerSource();
+            Integer dlSrcKey = Arrays.hashCode(dlSrc);
+            int bufferId = pi.getBufferId();
+
+            // if the src is not multicast, learn it
+            if ((dlSrc[0] & 0x1) == 0) {
+                if (!macTable.containsKey(dlSrcKey) ||
+                        !macTable.get(dlSrcKey).equals(pi.getInPort())) {
+                    macTable.put(dlSrcKey, pi.getInPort());
+                }
+            }
+
+            Short outPort = null;
+            // if the destination is not multicast, look it up
+            if ((dlDst[0] & 0x1) == 0) {
+                outPort = macTable.get(dlDstKey);
+            }
+
+            // push a flow mod if we know where the packet should be going
+            if (outPort != null) {
+                OFFlowMod fm = (OFFlowMod) factory.getMessage(OFType.FLOW_MOD);
+                fm.setBufferId(bufferId);
+                fm.setCommand((short) 0);
+                fm.setCookie(0);
+                fm.setFlags((short) 0);
+                fm.setHardTimeout((short) 0);
+                fm.setIdleTimeout((short) 5);
+                match.setInputPort(pi.getInPort());
+                match.setWildcards(0);
+                fm.setMatch(match);
+                fm.setOutPort((short) OFPort.OFPP_NONE.getValue());
+                fm.setPriority((short) 0);
+                OFActionOutput action = new OFActionOutput();
+                action.setMaxLength((short) 0);
+                action.setPort(outPort);
+                List<OFAction> actions = new ArrayList<OFAction>();
+                actions.add(action);
+                fm.setActions(actions);
+                fm.setLength(U16.t(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH));
+                try {
+                    stream.write(fm);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+
+            // Send a packet out
+            if (outPort == null || pi.getBufferId() == 0xffffffff) {
+                OFPacketOut po = new OFPacketOut();
+                po.setBufferId(bufferId);
+                po.setInPort(pi.getInPort());
+
+                // set actions
+                OFActionOutput action = new OFActionOutput();
+                action.setMaxLength((short) 0);
+                action.setPort((short) ((outPort == null) ? OFPort.OFPP_FLOOD
+                        .getValue() : outPort));
+                List<OFAction> actions = new ArrayList<OFAction>();
+                actions.add(action);
+                po.setActions(actions);
+                po.setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
+
+                // set data if needed
+                if (bufferId == 0xffffffff) {
+                    byte[] packetData = pi.getPacketData();
+                    po.setLength(U16.t(OFPacketOut.MINIMUM_LENGTH
+                            + po.getActionsLength() + packetData.length));
+                    po.setPacketData(packetData);
+                } else {
+                    po.setLength(U16.t(OFPacketOut.MINIMUM_LENGTH
+                            + po.getActionsLength()));
+                }
+                try {
+                    stream.write(po);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        public String toString() {
+            InetAddress remote = sock.socket().getInetAddress();
+            return remote.getHostAddress() + ":" + sock.socket().getPort();
+        }
+
+        public OFMessageAsyncStream getStream() {
+            return stream;
+        }
+    }
+
+    public SimpleController(int port) throws IOException{
+        listenSock = ServerSocketChannel.open();
+        listenSock.configureBlocking(false);
+        listenSock.socket().bind(new java.net.InetSocketAddress(port));
+        listenSock.socket().setReuseAddress(true);
+        this.port = port;
+        switchSelectLoops = new ArrayList<SelectLoop>();
+        switchSockets = new ConcurrentHashMap<SocketChannel,OFSwitch>();
+        threadCount = 1;
+        listenSelectLoop = new SelectLoop(this);
+        // register this connection for accepting
+        listenSelectLoop.register(listenSock, SelectionKey.OP_ACCEPT, listenSock);
+
+        this.factory = new BasicFactory();
+    }
+
+    @Override
+    public void handleEvent(SelectionKey key, Object arg) throws IOException {
+        if (arg instanceof ServerSocketChannel)
+            handleListenEvent(key, (ServerSocketChannel)arg);
+        else
+            handleSwitchEvent(key, (SocketChannel) arg);
+    }
+
+    protected void handleListenEvent(SelectionKey key, ServerSocketChannel ssc)
+            throws IOException {
+        SocketChannel sock = listenSock.accept();
+        OFMessageAsyncStream stream = new OFMessageAsyncStream(sock, factory);
+        switchSockets.put(sock, new OFSwitch(sock, stream));
+        System.err
+                .println("Got new connection from " + switchSockets.get(sock));
+        List<OFMessage> l = new ArrayList<OFMessage>();
+        l.add(factory.getMessage(OFType.HELLO));
+        l.add(factory.getMessage(OFType.FEATURES_REQUEST));
+        stream.write(l);
+
+        int ops = SelectionKey.OP_READ;
+        if (stream.needsFlush())
+            ops |= SelectionKey.OP_WRITE;
+
+        // hash this switch into a thread
+        SelectLoop sl = switchSelectLoops.get(sock.hashCode()
+                % switchSelectLoops.size());
+        sl.register(sock, ops, sock);
+        // force select to return and re-enter using the new set of keys
+        sl.wakeup();
+    }
+
+    protected void handleSwitchEvent(SelectionKey key, SocketChannel sock) {
+        OFSwitch sw = switchSockets.get(sock);
+        OFMessageAsyncStream stream = sw.getStream();
+        try {
+            if (key.isReadable()) {
+                List<OFMessage> msgs = stream.read();
+                if (msgs == null) {
+                    key.cancel();
+                    switchSockets.remove(sock);
+                    return;
+                }
+
+                for (OFMessage m : msgs) {
+                    switch (m.getType()) {
+                        case PACKET_IN:
+                            sw.handlePacketIn((OFPacketIn) m);
+                            break;
+                        case HELLO:
+                            System.err.println("GOT HELLO from " + sw);
+                            break;
+                        case ECHO_REQUEST:
+                            OFEchoReply reply = (OFEchoReply) stream
+                                .getMessageFactory().getMessage(
+                                        OFType.ECHO_REPLY);
+                            reply.setXid(m.getXid());
+                            stream.write(reply);
+                            break;
+                        default:
+                            System.err.println("Unhandled OF message: "
+                                    + m.getType() + " from "
+                                    + sock.socket().getInetAddress());
+                    }
+                }
+            }
+            if (key.isWritable()) {
+                stream.flush();
+            }
+
+            /**
+             * Only register for interest in R OR W, not both, causes stream
+             * deadlock after some period of time
+             */
+            if (stream.needsFlush())
+                key.interestOps(SelectionKey.OP_WRITE);
+            else
+                key.interestOps(SelectionKey.OP_READ);
+        } catch (IOException e) {
+            // if we have an exception, disconnect the switch
+            key.cancel();
+            switchSockets.remove(sock);
+        }
+    }
+
+    public void run() throws IOException{
+        System.err.println("Starting " + this.getClass().getCanonicalName() + 
+                " on port " + this.port + " with " + this.threadCount + " threads");
+        // Static number of threads equal to processor cores
+        es = Executors.newFixedThreadPool(threadCount);
+
+        // Launch one select loop per threadCount and start running
+        for (int i = 0; i < threadCount; ++i) {
+            final SelectLoop sl = new SelectLoop(this);
+            switchSelectLoops.add(sl);
+            es.execute(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        sl.doLoop();
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }}
+            );
+        }
+
+        // Start the listen loop
+        listenSelectLoop.doLoop();
+    }
+
+    public static void main(String [] args) throws IOException {
+        SimpleCLI cmd = parseArgs(args);
+        int port = Integer.valueOf(cmd.getOptionValue("p"));
+        SimpleController sc = new SimpleController(port);
+        sc.threadCount = Integer.valueOf(cmd.getOptionValue("t"));
+        sc.run();
+    }
+
+    public static SimpleCLI parseArgs(String[] args) {
+        Options options = new Options();
+        options.addOption("h", "help", "print help");
+        // unused?
+        // options.addOption("n", true, "the number of packets to send");
+        options.addOption("p", "port", 6633, "the port to listen on");
+        options.addOption("t", "threads", 1, "the number of threads to run");
+        try {
+            SimpleCLI cmd = SimpleCLI.parse(options, args);
+            if (cmd.hasOption("h")) {
+                printUsage(options);
+                System.exit(0);
+            }
+            return cmd;
+        } catch (ParseException e) {
+            System.err.println(e);
+            printUsage(options);
+        }
+
+        System.exit(-1);
+        return null;
+    }
+
+    public static void printUsage(Options options) {
+        SimpleCLI.printHelp("Usage: "
+                + SimpleController.class.getCanonicalName() + " [options]",
+                options);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/example/cli/Option.java b/third-party/openflowj/src/main/java/org/openflow/example/cli/Option.java
new file mode 100644 (file)
index 0000000..acf8446
--- /dev/null
@@ -0,0 +1,40 @@
+package org.openflow.example.cli;
+
+public class Option {
+    String shortOpt;
+    String longOpt;
+    Object defaultVal;
+    String val; // current value of this option, string form
+    boolean specified; // was this option found in the cmdline?
+    String comment;
+
+    /**
+     * Option information storrage
+     * 
+     * @param shortOpt
+     *            Short name for the option, e.g., "-p"
+     * @param longOpt
+     *            Long name for option, e.g., "--port"
+     * @param defaultVal
+     *            default value: "6633" or null if no default value
+     * @param comment
+     *            String to print to explain this option, e.g., a help message
+     */
+    public Option(String shortOpt, String longOpt, Object defaultVal,
+            String comment) {
+        super();
+        this.shortOpt = shortOpt;
+        this.longOpt = longOpt;
+        this.defaultVal = defaultVal;
+        this.comment = comment;
+        this.specified = false;
+    }
+
+    public Option(String shortOpt, String longOpt, String comment) {
+        this(shortOpt, longOpt, null, comment);
+    }
+
+    public boolean needsArg() {
+        return this.defaultVal != null;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/example/cli/Options.java b/third-party/openflowj/src/main/java/org/openflow/example/cli/Options.java
new file mode 100644 (file)
index 0000000..7f55b50
--- /dev/null
@@ -0,0 +1,69 @@
+package org.openflow.example.cli;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Very basic CLI options listing
+ * 
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ * 
+ */
+
+public class Options {
+    Map<String, Option> shortOptionsMap;
+    Map<String, Option> longOptionsMap;
+
+    public Options() {
+        this.shortOptionsMap = new HashMap<String, Option>();
+        this.longOptionsMap = new HashMap<String, Option>();
+    }
+
+    public static Options make(Option opts[]) {
+        Options options = new Options();
+        for (int i = 0; i < opts.length; i++)
+            options.addOption(opts[i]);
+        return options;
+    }
+
+    private void addOption(Option option) {
+        if (option.shortOpt != null)
+            this.shortOptionsMap.put(option.shortOpt, option);
+        if (option.longOpt != null)
+            this.longOptionsMap.put(option.longOpt, option);
+    }
+
+    protected void addOption(String shortName, String longName, Object o,
+            String comment) {
+        Option option = new Option(shortName, longName, o, comment);
+        addOption(option);
+    }
+
+    public void addOption(String shortName, String longName, boolean b,
+            String comment) {
+        this.addOption(shortName, longName, Boolean.valueOf(b), comment);
+    }
+
+    public void addOption(String shortName, String longName, int i,
+            String comment) {
+        this.addOption(shortName, longName, Integer.valueOf(i), comment);
+    }
+
+    public Option getOption(String shortName) {
+        return this.shortOptionsMap.get(shortName);
+    }
+
+    public Option getOptionByLongName(String longName) {
+        return this.longOptionsMap.get(longName);
+    }
+
+    public Collection<Option> getOptions() {
+        return this.shortOptionsMap.values();
+    }
+
+    public void addOption(String shortName, String longName, String comment) {
+        this.addOption(shortName, longName, null, comment);
+    }
+
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/example/cli/ParseException.java b/third-party/openflowj/src/main/java/org/openflow/example/cli/ParseException.java
new file mode 100644 (file)
index 0000000..a99e11d
--- /dev/null
@@ -0,0 +1,14 @@
+package org.openflow.example.cli;
+
+public class ParseException extends Exception {
+
+    public ParseException(String msg) {
+        super(msg);
+    }
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/example/cli/SimpleCLI.java b/third-party/openflowj/src/main/java/org/openflow/example/cli/SimpleCLI.java
new file mode 100644 (file)
index 0000000..8f37024
--- /dev/null
@@ -0,0 +1,132 @@
+package org.openflow.example.cli;
+
+import java.io.PrintStream;
+
+/**
+ * Very basic command line interface
+ * 
+ * (really should be something in java.* for this; only implementing this to
+ * remove external dependencies)
+ * 
+ * Modeled after org.apache.common.cli .
+ * 
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ * 
+ */
+
+public class SimpleCLI {
+
+    private static final String NAME_WIDTH = "-15";
+    private static final String VALUE_WIDTH = "-20";
+    private static final String FORMAT_STRING = "%1$" + NAME_WIDTH + "s%2$"
+            + VALUE_WIDTH + "s%3$s\n";
+    Options options;
+
+    int optind;
+
+    /**
+     * Need to use SimpleCLI.parse() instead
+     * 
+     * @param options
+     */
+
+    private SimpleCLI(Options options) {
+        this.options = options;
+    }
+
+    /**
+     * @return the index of the last parsed option
+     * 
+     *         Useful for finding options that don't start with "-" or "--"
+     */
+    public int getOptind() {
+        return optind;
+    }
+
+    /**
+     * @param optind
+     *            the optind to set
+     */
+    public void setOptind(int optind) {
+        this.optind = optind;
+    }
+
+    public boolean hasOption(String shortName) {
+        Option option = this.options.getOption(shortName);
+        if (option == null)
+            return false;
+        return option.specified;
+    }
+
+    public String getOptionValue(String shortName) {
+        Option option = this.options.getOption(shortName);
+        if (option == null)
+            return null;
+        if (!option.specified)
+            return option.defaultVal.toString();
+        else
+            return option.val;
+    }
+
+    public static SimpleCLI parse(Options options, String[] args)
+            throws ParseException {
+        SimpleCLI simpleCLI = new SimpleCLI(options);
+        int i;
+        for (i = 0; i < args.length; i++) {
+            if (!args[i].startsWith("-"))
+                break; // not a short or long option
+            String optName = args[i].replaceFirst("^-*", ""); // remove leading
+            // "--"
+            Option option;
+            if (args[i].startsWith("--"))
+                option = options.getOptionByLongName(optName);
+            else
+                option = options.getOption(optName);
+            if (option == null)
+                throw new ParseException("unknown option: " + optName);
+            option.specified = true;
+            if (option.needsArg()) {
+                if ((i + 1) >= args.length)
+                    throw new ParseException("option " + optName
+                            + " requires an argument:: " + option.comment);
+                option.val = args[i + 1];
+                i++; // skip next element; we've parsed it
+            }
+        }
+        simpleCLI.setOptind(i);
+        return simpleCLI;
+    }
+
+    public static void printHelp(String canonicalName, Options options) {
+        printHelp(canonicalName, options, System.err);
+    }
+
+    private static void printHelp(String helpString, Options options,
+            PrintStream err) {
+        err.println(helpString);
+        err.format(FORMAT_STRING, "\toption", "type [default]", "usage");
+        for (Option option : options.getOptions()) {
+            String msg = "\t";
+            if (option.shortOpt != null)
+                msg += "-" + option.shortOpt;
+            if (option.longOpt != null) {
+                if (!msg.equals("\t"))
+                    msg += "|";
+                msg += "--" + option.longOpt;
+            }
+            String val = "";
+            if (option.defaultVal != null)
+                val += option.defaultVal.getClass().getSimpleName() + " ["
+                        + option.defaultVal.toString() + "]";
+            String comment;
+            if (option.comment != null)
+                comment = option.comment;
+            else
+                comment = "";
+
+            err.format(FORMAT_STRING, msg, val, comment);
+        }
+        err.println(""); // print blank line at the end, to look pretty
+    }
+
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/io/OFMessageAsyncStream.java b/third-party/openflowj/src/main/java/org/openflow/io/OFMessageAsyncStream.java
new file mode 100644 (file)
index 0000000..c499b99
--- /dev/null
@@ -0,0 +1,121 @@
+/**
+ *
+ */
+package org.openflow.io;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.List;
+
+import org.openflow.protocol.OFMessage;
+import org.openflow.protocol.factory.OFMessageFactory;
+
+/**
+ * Asynchronous OpenFlow message marshalling and unmarshalling stream wrapped
+ * around an NIO SocketChannel
+ * 
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ * 
+ */
+public class OFMessageAsyncStream implements OFMessageInStream,
+        OFMessageOutStream {
+    static public int defaultBufferSize = 1048576; // 1MB
+
+    protected ByteBuffer inBuf, outBuf;
+    protected OFMessageFactory messageFactory;
+    protected SocketChannel sock;
+    protected int partialReadCount = 0;
+
+    public OFMessageAsyncStream(SocketChannel sock,
+            OFMessageFactory messageFactory) throws IOException {
+        inBuf = ByteBuffer
+                .allocateDirect(OFMessageAsyncStream.defaultBufferSize);
+        outBuf = ByteBuffer
+                .allocateDirect(OFMessageAsyncStream.defaultBufferSize);
+        this.sock = sock;
+        this.messageFactory = messageFactory;
+        this.sock.configureBlocking(false);
+    }
+
+    @Override
+    public List<OFMessage> read() throws IOException {
+        return this.read(0);
+    }
+
+    @Override
+    public List<OFMessage> read(int limit) throws IOException {
+        List<OFMessage> l;
+        int read = sock.read(inBuf);
+        if (read == -1)
+            return null;
+        inBuf.flip();
+        l = messageFactory.parseMessages(inBuf, limit);
+        if (inBuf.hasRemaining())
+            inBuf.compact();
+        else
+            inBuf.clear();
+        return l;
+    }
+
+    protected void appendMessageToOutBuf(OFMessage m) throws IOException {
+        int msglen = m.getLengthU();
+        if (outBuf.remaining() < msglen) {
+            throw new IOException(
+                    "Message length exceeds buffer capacity: " + msglen);
+        }
+        m.writeTo(outBuf);
+    }
+
+    /**
+     * Buffers a single outgoing openflow message
+     */
+    @Override
+    public void write(OFMessage m) throws IOException {
+        appendMessageToOutBuf(m);
+    }
+
+    /**
+     * Buffers a list of OpenFlow messages
+     */
+    @Override
+    public void write(List<OFMessage> l) throws IOException {
+        for (OFMessage m : l) {
+            appendMessageToOutBuf(m);
+        }
+    }
+
+    /**
+     * Flush buffered outgoing data. Keep flushing until needsFlush() returns
+     * false. Each flush() corresponds to a SocketChannel.write(), so this is
+     * designed for one flush() per select() event
+     */
+    public void flush() throws IOException {
+        outBuf.flip(); // swap pointers; lim = pos; pos = 0;
+        sock.write(outBuf); // write data starting at pos up to lim
+        outBuf.compact();
+    }
+
+    /**
+     * Is there outgoing buffered data that needs to be flush()'d?
+     */
+    public boolean needsFlush() {
+        return outBuf.position() > 0;
+    }
+
+    /**
+     * @return the messageFactory
+     */
+    public OFMessageFactory getMessageFactory() {
+        return messageFactory;
+    }
+
+    /**
+     * @param messageFactory
+     *            the messageFactory to set
+     */
+    public void setMessageFactory(OFMessageFactory messageFactory) {
+        this.messageFactory = messageFactory;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/io/OFMessageInStream.java b/third-party/openflowj/src/main/java/org/openflow/io/OFMessageInStream.java
new file mode 100644 (file)
index 0000000..39ec30d
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ *
+ */
+package org.openflow.io;
+
+import java.util.List;
+
+import org.openflow.protocol.OFMessage;
+import org.openflow.protocol.factory.OFMessageFactory;
+
+/**
+ * Interface for reading OFMessages from a buffered stream
+ * 
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ * 
+ */
+public interface OFMessageInStream {
+    /**
+     * Read OF messages from the stream
+     * 
+     * @return a list of OF Messages, empty if no complete messages are
+     *         available, null if the stream has closed
+     */
+    public List<OFMessage> read() throws java.io.IOException;
+
+    /**
+     * Read OF messages from the stream
+     * 
+     * @param limit
+     *            The maximum number of messages to read: 0 means all that are
+     *            buffered
+     * @return a list of OF Messages, empty if no complete messages are
+     *         available, null if the stream has closed
+     * 
+     */
+    public List<OFMessage> read(int limit) throws java.io.IOException;
+
+    /**
+     * Sets the OFMessageFactory used to create messages on this stream
+     * 
+     * @param factory
+     */
+    public void setMessageFactory(OFMessageFactory factory);
+
+    /**
+     * Returns the OFMessageFactory used to create messages on this stream
+     * 
+     * @return
+     */
+    public OFMessageFactory getMessageFactory();
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/io/OFMessageOutStream.java b/third-party/openflowj/src/main/java/org/openflow/io/OFMessageOutStream.java
new file mode 100644 (file)
index 0000000..56416ce
--- /dev/null
@@ -0,0 +1,41 @@
+/**
+ *
+ */
+package org.openflow.io;
+
+import java.util.List;
+import org.openflow.protocol.OFMessage;
+
+/**
+ * Interface for writing OFMessages to a buffered stream
+ *
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ *
+ */
+public interface OFMessageOutStream {
+    /**
+     * Write an OpenFlow message to the stream
+     * @param m An OF Message
+     */
+    public void write(OFMessage m) throws java.io.IOException;
+
+    /**
+     * Write an OpenFlow message to the stream.
+     *  Messages are sent in one large write() for efficiency
+     * @param l A list of OF Messages
+     */
+    public void write(List<OFMessage> l) throws java.io.IOException;
+
+    /**
+     * Pushes buffered data out the Stream; this is NOT guranteed to flush all
+     * data, multiple flush() calls may be required, until needFlush() returns
+     * false.
+     */
+    public void flush() throws java.io.IOException;
+
+    /**
+     * Is there buffered data that needs to be flushed?
+     * @return true if there is buffered data and flush() should be called
+     */
+    public boolean needsFlush();
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/Instantiable.java b/third-party/openflowj/src/main/java/org/openflow/protocol/Instantiable.java
new file mode 100644 (file)
index 0000000..38a3af0
--- /dev/null
@@ -0,0 +1,14 @@
+package org.openflow.protocol;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public interface Instantiable<E> {
+
+    /**
+     * Create a new instance of a given subclass.
+     * @return the new instance.
+     */
+    public E instantiate();
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFBarrierReply.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFBarrierReply.java
new file mode 100644 (file)
index 0000000..5a06efb
--- /dev/null
@@ -0,0 +1,15 @@
+package org.openflow.protocol;
+
+import org.openflow.util.U16;
+
+/**
+ * Represents an OFPT_BARRIER_REPLY message
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFBarrierReply extends OFMessage {
+    public OFBarrierReply() {
+        super();
+        this.type = OFType.BARRIER_REPLY;
+        this.length = U16.t(OFMessage.MINIMUM_LENGTH);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFBarrierRequest.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFBarrierRequest.java
new file mode 100644 (file)
index 0000000..3f6a8f5
--- /dev/null
@@ -0,0 +1,15 @@
+package org.openflow.protocol;
+
+import org.openflow.util.U16;
+
+/**
+ * Represents an OFPT_BARRIER_REQUEST message
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFBarrierRequest extends OFMessage {
+    public OFBarrierRequest() {
+        super();
+        this.type = OFType.BARRIER_REQUEST;
+        this.length = U16.t(OFMessage.MINIMUM_LENGTH);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFEchoReply.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFEchoReply.java
new file mode 100644 (file)
index 0000000..1f26104
--- /dev/null
@@ -0,0 +1,19 @@
+package org.openflow.protocol;
+
+import org.openflow.util.U16;
+
+/**
+ * Represents an ofp_echo_reply message
+ * 
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ */
+
+public class OFEchoReply extends OFEchoRequest {
+    public static int MINIMUM_LENGTH = 8;
+
+    public OFEchoReply() {
+        super();
+        this.type = OFType.ECHO_REPLY;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFEchoRequest.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFEchoRequest.java
new file mode 100644 (file)
index 0000000..a88850e
--- /dev/null
@@ -0,0 +1,54 @@
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+
+import org.openflow.util.U16;
+
+/**
+ * Represents an ofp_echo_request message
+ * 
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ */
+
+public class OFEchoRequest extends OFMessage {
+    public static int MINIMUM_LENGTH = 8;
+    byte[] payload;
+
+    public OFEchoRequest() {
+        super();
+        this.type = OFType.ECHO_REQUEST;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+
+    @Override
+    public void readFrom(ByteBuffer bb) {
+        super.readFrom(bb);
+        int datalen = this.getLengthU() - MINIMUM_LENGTH;
+        if (datalen > 0) {
+            this.payload = new byte[datalen];
+            bb.get(payload);
+        }
+    }
+
+    /**
+     * @return the payload
+     */
+    public byte[] getPayload() {
+        return payload;
+    }
+
+    /**
+     * @param payload
+     *            the payload to set
+     */
+    public void setPayload(byte[] payload) {
+        this.payload = payload;
+    }
+
+    @Override
+    public void writeTo(ByteBuffer bb) {
+        super.writeTo(bb);
+        if (payload != null)
+            bb.put(payload);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFError.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFError.java
new file mode 100644 (file)
index 0000000..74e39b2
--- /dev/null
@@ -0,0 +1,257 @@
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
+
+import org.openflow.protocol.factory.OFMessageFactory;
+import org.openflow.protocol.factory.OFMessageFactoryAware;
+import org.openflow.util.U16;
+
+/**
+ * Represents an ofp_error_msg
+ * 
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ */
+public class OFError extends OFMessage implements OFMessageFactoryAware {
+    public static int MINIMUM_LENGTH = 12;
+
+    public enum OFErrorType {
+        OFPET_HELLO_FAILED, OFPET_BAD_REQUEST, OFPET_BAD_ACTION, OFPET_FLOW_MOD_FAILED, OFPET_PORT_MOD_FAILED, OFPET_QUEUE_OP_FAILED
+    }
+
+    public enum OFHelloFailedCode {
+        OFPHFC_INCOMPATIBLE, OFPHFC_EPERM
+    }
+
+    public enum OFBadRequestCode {
+        OFPBRC_BAD_VERSION, OFPBRC_BAD_TYPE, OFPBRC_BAD_STAT, OFPBRC_BAD_VENDOR, OFPBRC_BAD_SUBTYPE, OFPBRC_EPERM, OFPBRC_BAD_LEN, OFPBRC_BUFFER_EMPTY, OFPBRC_BUFFER_UNKNOWN
+    }
+
+    public enum OFBadActionCode {
+        OFPBAC_BAD_TYPE, OFPBAC_BAD_LEN, OFPBAC_BAD_VENDOR, OFPBAC_BAD_VENDOR_TYPE, OFPBAC_BAD_OUT_PORT, OFPBAC_BAD_ARGUMENT, OFPBAC_EPERM, OFPBAC_TOO_MANY, OFPBAC_BAD_QUEUE
+    }
+
+    public enum OFFlowModFailedCode {
+        OFPFMFC_ALL_TABLES_FULL, OFPFMFC_OVERLAP, OFPFMFC_EPERM, OFPFMFC_BAD_EMERG_TIMEOUT, OFPFMFC_BAD_COMMAND, OFPFMFC_UNSUPPORTED
+    }
+
+    public enum OFPortModFailedCode {
+        OFPPMFC_BAD_PORT, OFPPMFC_BAD_HW_ADDR
+    }
+
+    public enum OFQueueOpFailedCode {
+        OFPQOFC_BAD_PORT, OFPQOFC_BAD_QUEUE, OFPQOFC_EPERM
+    }
+
+    protected short errorType;
+    protected short errorCode;
+    protected OFMessageFactory factory;
+    protected byte[] error;
+    protected boolean errorIsAscii;
+
+    public OFError() {
+        super();
+        this.type = OFType.ERROR;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+
+    /**
+     * @return the errorType
+     */
+    public short getErrorType() {
+        return errorType;
+    }
+
+    /**
+     * @param errorType
+     *            the errorType to set
+     */
+    public void setErrorType(short errorType) {
+        this.errorType = errorType;
+    }
+
+    public void setErrorType(OFErrorType type) {
+        this.errorType = (short) type.ordinal();
+    }
+
+    /**
+     * @return the errorCode
+     */
+    public short getErrorCode() {
+        return errorCode;
+    }
+
+    /**
+     * @param errorCode
+     *            the errorCode to set
+     */
+    public void setErrorCode(OFHelloFailedCode code) {
+        this.errorCode = (short) code.ordinal();
+    }
+
+    public void setErrorCode(short errorCode) {
+        this.errorCode = errorCode;
+    }
+
+    public void setErrorCode(OFBadRequestCode code) {
+        this.errorCode = (short) code.ordinal();
+    }
+
+    public void setErrorCode(OFBadActionCode code) {
+        this.errorCode = (short) code.ordinal();
+    }
+
+    public void setErrorCode(OFFlowModFailedCode code) {
+        this.errorCode = (short) code.ordinal();
+    }
+
+    public void setErrorCode(OFPortModFailedCode code) {
+        this.errorCode = (short) code.ordinal();
+    }
+
+    public void setErrorCode(OFQueueOpFailedCode code) {
+        this.errorCode = (short) code.ordinal();
+    }
+
+    public OFMessage getOffendingMsg() {
+        // should only have one message embedded; if more than one, just
+        // grab first
+        if (this.error == null)
+            return null;
+        ByteBuffer errorMsg = ByteBuffer.wrap(this.error);
+        if (factory == null)
+            throw new RuntimeException("MessageFactory not set");
+        List<OFMessage> messages = this.factory.parseMessages(errorMsg,
+                error.length);
+        // OVS apparently sends partial messages in errors
+        // need to be careful of that AND can't use data.limit() as
+        // a packet boundary because there could be more data queued
+        if (messages.size() > 0)
+            return messages.get(0);
+        else
+            return null;
+    }
+
+    /**
+     * Write this offending message into the payload of the Error message
+     * 
+     * @param offendingMsg
+     */
+
+    public void setOffendingMsg(OFMessage offendingMsg) {
+        if (offendingMsg == null) {
+            super.setLengthU(MINIMUM_LENGTH);
+        } else {
+            this.error = new byte[offendingMsg.getLengthU()];
+            ByteBuffer data = ByteBuffer.wrap(this.error);
+            offendingMsg.writeTo(data);
+            super.setLengthU(MINIMUM_LENGTH + offendingMsg.getLengthU());
+        }
+    }
+
+    public OFMessageFactory getFactory() {
+        return factory;
+    }
+
+    @Override
+    public void setMessageFactory(OFMessageFactory factory) {
+        this.factory = factory;
+    }
+
+    /**
+     * @return the error
+     */
+    public byte[] getError() {
+        return error;
+    }
+
+    /**
+     * @param error
+     *            the error to set
+     */
+    public void setError(byte[] error) {
+        this.error = error;
+    }
+
+    /**
+     * @return the errorIsAscii
+     */
+    public boolean isErrorIsAscii() {
+        return errorIsAscii;
+    }
+
+    /**
+     * @param errorIsAscii
+     *            the errorIsAscii to set
+     */
+    public void setErrorIsAscii(boolean errorIsAscii) {
+        this.errorIsAscii = errorIsAscii;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.errorType = data.getShort();
+        this.errorCode = data.getShort();
+        int dataLength = this.getLengthU() - MINIMUM_LENGTH;
+        if (dataLength > 0) {
+            this.error = new byte[dataLength];
+            data.get(this.error);
+            if (this.errorType == OFErrorType.OFPET_HELLO_FAILED.ordinal())
+                this.errorIsAscii = true;
+        }
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putShort(errorType);
+        data.putShort(errorCode);
+        if (error != null)
+            data.put(error);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + Arrays.hashCode(error);
+        result = prime * result + errorCode;
+        result = prime * result + (errorIsAscii ? 1231 : 1237);
+        result = prime * result + errorType;
+        return result;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!super.equals(obj))
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        OFError other = (OFError) obj;
+        if (!Arrays.equals(error, other.error))
+            return false;
+        if (errorCode != other.errorCode)
+            return false;
+        if (errorIsAscii != other.errorIsAscii)
+            return false;
+        if (errorType != other.errorType)
+            return false;
+        return true;
+    }
+
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFFeaturesReply.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFFeaturesReply.java
new file mode 100644 (file)
index 0000000..8447d88
--- /dev/null
@@ -0,0 +1,238 @@
+package org.openflow.protocol;
+
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openflow.util.U16;
+
+
+/**
+ * Represents a features reply message
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ *
+ */
+public class OFFeaturesReply extends OFMessage implements Serializable {
+    public static int MINIMUM_LENGTH = 32;
+
+    /**
+     * Corresponds to bits on the capabilities field
+     */
+    public enum OFCapabilities {
+        OFPC_FLOW_STATS     (1 << 0),
+        OFPC_TABLE_STATS    (1 << 1),
+        OFPC_PORT_STATS     (1 << 2),
+        OFPC_STP            (1 << 3),
+        OFPC_RESERVED       (1 << 4),
+        OFPC_IP_REASM       (1 << 5),
+        OFPC_QUEUE_STATS    (1 << 6),
+        OFPC_ARP_MATCH_IP   (1 << 7);
+
+        protected int value;
+
+        private OFCapabilities(int value) {
+            this.value = value;
+        }
+
+        /**
+         * @return the value
+         */
+        public int getValue() {
+            return value;
+        }
+    }
+
+    protected long datapathId;
+    protected int buffers;
+    protected byte tables;
+    protected int capabilities;
+    protected int actions;
+    protected List<OFPhysicalPort> ports;
+
+    public OFFeaturesReply() {
+        super();
+        this.type = OFType.FEATURES_REPLY;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+
+    /**
+     * @return the datapathId
+     */
+    public long getDatapathId() {
+        return datapathId;
+    }
+
+    /**
+     * @param datapathId the datapathId to set
+     */
+    public void setDatapathId(long datapathId) {
+        this.datapathId = datapathId;
+    }
+
+    /**
+     * @return the buffers
+     */
+    public int getBuffers() {
+        return buffers;
+    }
+
+    /**
+     * @param buffers the buffers to set
+     */
+    public void setBuffers(int buffers) {
+        this.buffers = buffers;
+    }
+
+    /**
+     * @return the tables
+     */
+    public byte getTables() {
+        return tables;
+    }
+
+    /**
+     * @param tables the tables to set
+     */
+    public void setTables(byte tables) {
+        this.tables = tables;
+    }
+
+    /**
+     * @return the capabilities
+     */
+    public int getCapabilities() {
+        return capabilities;
+    }
+
+    /**
+     * @param capabilities the capabilities to set
+     */
+    public void setCapabilities(int capabilities) {
+        this.capabilities = capabilities;
+    }
+
+    /**
+     * @return the actions
+     */
+    public int getActions() {
+        return actions;
+    }
+
+    /**
+     * @param actions the actions to set
+     */
+    public void setActions(int actions) {
+        this.actions = actions;
+    }
+
+    /**
+     * @return the ports
+     */
+    public List<OFPhysicalPort> getPorts() {
+        return ports;
+    }
+
+    /**
+     * @param ports the ports to set
+     */
+    public void setPorts(List<OFPhysicalPort> ports) {
+        this.ports = ports;
+        if (ports == null) {
+            this.setLengthU(MINIMUM_LENGTH);
+        } else {
+            this.setLengthU(MINIMUM_LENGTH + ports.size()
+                    * OFPhysicalPort.MINIMUM_LENGTH);
+        }
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.datapathId = data.getLong();
+        this.buffers = data.getInt();
+        this.tables = data.get();
+        data.position(data.position() + 3); // pad
+        this.capabilities = data.getInt();
+        this.actions = data.getInt();
+        if (this.ports == null) {
+            this.ports = new ArrayList<OFPhysicalPort>();
+        } else {
+            this.ports.clear();
+        }
+        int portCount = (super.getLengthU() - 32)
+                / OFPhysicalPort.MINIMUM_LENGTH;
+        OFPhysicalPort port;
+        for (int i = 0; i < portCount; ++i) {
+            port = new OFPhysicalPort();
+            port.readFrom(data);
+            this.ports.add(port);
+        }
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putLong(this.datapathId);
+        data.putInt(this.buffers);
+        data.put(this.tables);
+        data.putShort((short) 0); // pad
+        data.put((byte) 0); // pad
+        data.putInt(this.capabilities);
+        data.putInt(this.actions);
+        if (this.ports != null)
+            for (OFPhysicalPort port : this.ports) {
+                port.writeTo(data);
+            }
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 139;
+        int result = super.hashCode();
+        result = prime * result + actions;
+        result = prime * result + buffers;
+        result = prime * result + capabilities;
+        result = prime * result + (int) (datapathId ^ (datapathId >>> 32));
+        result = prime * result + ((ports == null) ? 0 : ports.hashCode());
+        result = prime * result + tables;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFFeaturesReply)) {
+            return false;
+        }
+        OFFeaturesReply other = (OFFeaturesReply) obj;
+        if (actions != other.actions) {
+            return false;
+        }
+        if (buffers != other.buffers) {
+            return false;
+        }
+        if (capabilities != other.capabilities) {
+            return false;
+        }
+        if (datapathId != other.datapathId) {
+            return false;
+        }
+        if (ports == null) {
+            if (other.ports != null) {
+                return false;
+            }
+        } else if (!ports.equals(other.ports)) {
+            return false;
+        }
+        if (tables != other.tables) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFFeaturesRequest.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFFeaturesRequest.java
new file mode 100644 (file)
index 0000000..8c9001a
--- /dev/null
@@ -0,0 +1,19 @@
+package org.openflow.protocol;
+
+import org.openflow.util.U16;
+
+
+/**
+ * Represents a features request message
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ *
+ */
+public class OFFeaturesRequest extends OFMessage {
+    public static int MINIMUM_LENGTH = 8;
+
+    public OFFeaturesRequest() {
+        super();
+        this.type = OFType.FEATURES_REQUEST;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFFlowMod.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFFlowMod.java
new file mode 100644 (file)
index 0000000..92eac4e
--- /dev/null
@@ -0,0 +1,371 @@
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.openflow.protocol.action.OFAction;
+import org.openflow.protocol.factory.OFActionFactory;
+import org.openflow.protocol.factory.OFActionFactoryAware;
+import org.openflow.util.U16;
+
+/**
+ * Represents an ofp_flow_mod message
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ *
+ */
+public class OFFlowMod extends OFMessage implements OFActionFactoryAware, Cloneable {
+    public static int MINIMUM_LENGTH = 72;
+
+    public static final short OFPFC_ADD = 0;                /* New flow. */
+    public static final short OFPFC_MODIFY = 1;             /* Modify all matching flows. */
+    public static final short OFPFC_MODIFY_STRICT = 2;      /* Modify entry strictly matching wildcards */
+    public static final short OFPFC_DELETE=3;               /* Delete all matching flows. */
+    public static final short OFPFC_DELETE_STRICT =4;       /* Strictly match wildcards and priority. */
+
+    protected OFActionFactory actionFactory;
+    protected OFMatch match;
+    protected long cookie;
+    protected short command;
+    protected short idleTimeout;
+    protected short hardTimeout;
+    protected short priority;
+    protected int bufferId;
+    protected short outPort;
+    protected short flags;
+    protected List<OFAction> actions;
+
+    public OFFlowMod() {
+        super();
+        this.type = OFType.FLOW_MOD;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+
+    /**
+     * Get buffer_id
+     * @return
+     */
+    public int getBufferId() {
+        return this.bufferId;
+    }
+
+    /**
+     * Set buffer_id
+     * @param bufferId
+     */
+    public OFFlowMod setBufferId(int bufferId) {
+        this.bufferId = bufferId;
+        return this;
+    }
+
+    /**
+     * Get cookie
+     * @return
+     */
+    public long getCookie() {
+        return this.cookie;
+    }
+
+    /**
+     * Set cookie
+     * @param cookie
+     */
+    public OFFlowMod setCookie(long cookie) {
+        this.cookie = cookie;
+        return this;
+    }
+
+    /**
+     * Get command
+     * @return
+     */
+    public short getCommand() {
+        return this.command;
+    }
+
+    /**
+     * Set command
+     * @param command
+     */
+    public OFFlowMod setCommand(short command) {
+        this.command = command;
+        return this;
+    }
+
+    /**
+     * Get flags
+     * @return
+     */
+    public short getFlags() {
+        return this.flags;
+    }
+
+    /**
+     * Set flags
+     * @param flags
+     */
+    public OFFlowMod setFlags(short flags) {
+        this.flags = flags;
+        return this;
+    }
+
+    /**
+     * Get hard_timeout
+     * @return
+     */
+    public short getHardTimeout() {
+        return this.hardTimeout;
+    }
+
+    /**
+     * Set hard_timeout
+     * @param hardTimeout
+     */
+    public OFFlowMod setHardTimeout(short hardTimeout) {
+        this.hardTimeout = hardTimeout;
+        return this;
+    }
+
+    /**
+     * Get idle_timeout
+     * @return
+     */
+    public short getIdleTimeout() {
+        return this.idleTimeout;
+    }
+
+    /**
+     * Set idle_timeout
+     * @param idleTimeout
+     */
+    public OFFlowMod setIdleTimeout(short idleTimeout) {
+        this.idleTimeout = idleTimeout;
+        return this;
+    }
+
+    /**
+     * Gets a copy of the OFMatch object for this FlowMod, changes to this
+     * object do not modify the FlowMod
+     * @return
+     */
+    public OFMatch getMatch() {
+        return this.match;
+    }
+
+    /**
+     * Set match
+     * @param match
+     */
+    public OFFlowMod setMatch(OFMatch match) {
+        this.match = match;
+        return this;
+    }
+
+    /**
+     * Get out_port
+     * @return
+     */
+    public short getOutPort() {
+        return this.outPort;
+    }
+
+    /**
+     * Set out_port
+     * @param outPort
+     */
+    public OFFlowMod setOutPort(short outPort) {
+        this.outPort = outPort;
+        return this;
+    }
+
+    /**
+     * Set out_port
+     * @param port
+     */
+    public OFFlowMod setOutPort(OFPort port) {
+        this.outPort = port.getValue();
+        return this;
+    }
+
+    /**
+     * Get priority
+     * @return
+     */
+    public short getPriority() {
+        return this.priority;
+    }
+
+    /**
+     * Set priority
+     * @param priority
+     */
+    public OFFlowMod setPriority(short priority) {
+        this.priority = priority;
+        return this;
+    }
+
+    /**
+     * Returns read-only copies of the actions contained in this Flow Mod
+     * @return a list of ordered OFAction objects
+     */
+    public List<OFAction> getActions() {
+        return this.actions;
+    }
+
+    /**
+     * Sets the list of actions this Flow Mod contains
+     * @param actions a list of ordered OFAction objects
+     */
+    public OFFlowMod setActions(List<OFAction> actions) {
+        this.actions = actions;
+        return this;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        if (this.match == null)
+            this.match = new OFMatch();
+        this.match.readFrom(data);
+        this.cookie = data.getLong();
+        this.command = data.getShort();
+        this.idleTimeout = data.getShort();
+        this.hardTimeout = data.getShort();
+        this.priority = data.getShort();
+        this.bufferId = data.getInt();
+        this.outPort = data.getShort();
+        this.flags = data.getShort();
+        if (this.actionFactory == null)
+            throw new RuntimeException("OFActionFactory not set");
+        this.actions = this.actionFactory.parseActions(data, getLengthU() -
+                MINIMUM_LENGTH);
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        this.match.writeTo(data);
+        data.putLong(cookie);
+        data.putShort(command);
+        data.putShort(idleTimeout);
+        data.putShort(hardTimeout);
+        data.putShort(priority);
+        data.putInt(bufferId);
+        data.putShort(outPort);
+        data.putShort(flags);
+        if (actions != null) {
+            for (OFAction action : actions) {
+                action.writeTo(data);
+            }
+        }
+    }
+
+    @Override
+    public void setActionFactory(OFActionFactory actionFactory) {
+        this.actionFactory = actionFactory;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 227;
+        int result = super.hashCode();
+        result = prime * result + ((actions == null) ? 0 : actions.hashCode());
+        result = prime * result + bufferId;
+        result = prime * result + command;
+        result = prime * result + (int) (cookie ^ (cookie >>> 32));
+        result = prime * result + flags;
+        result = prime * result + hardTimeout;
+        result = prime * result + idleTimeout;
+        result = prime * result + ((match == null) ? 0 : match.hashCode());
+        result = prime * result + outPort;
+        result = prime * result + priority;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFFlowMod)) {
+            return false;
+        }
+        OFFlowMod other = (OFFlowMod) obj;
+        if (actions == null) {
+            if (other.actions != null) {
+                return false;
+            }
+        } else if (!actions.equals(other.actions)) {
+            return false;
+        }
+        if (bufferId != other.bufferId) {
+            return false;
+        }
+        if (command != other.command) {
+            return false;
+        }
+        if (cookie != other.cookie) {
+            return false;
+        }
+        if (flags != other.flags) {
+            return false;
+        }
+        if (hardTimeout != other.hardTimeout) {
+            return false;
+        }
+        if (idleTimeout != other.idleTimeout) {
+            return false;
+        }
+        if (match == null) {
+            if (other.match != null) {
+                return false;
+            }
+        } else if (!match.equals(other.match)) {
+            return false;
+        }
+        if (outPort != other.outPort) {
+            return false;
+        }
+        if (priority != other.priority) {
+            return false;
+        }
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#clone()
+     */
+    @Override
+    public OFFlowMod clone() {
+        try {
+            OFMatch neoMatch = match.clone();
+            OFFlowMod flowMod = (OFFlowMod) super.clone();
+            flowMod.setMatch(neoMatch);
+            List<OFAction> neoActions = new LinkedList<OFAction>();
+            for(OFAction action: this.actions)
+                neoActions.add((OFAction) action.clone());
+            flowMod.setActions(neoActions);
+            return flowMod;
+        } catch (CloneNotSupportedException e) {
+            // Won't happen
+            throw new RuntimeException(e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "OFFlowMod [actionFactory=" + actionFactory + ", actions="
+                + actions + ", bufferId=" + bufferId + ", command=" + command
+                + ", cookie=" + cookie + ", flags=" + flags + ", hardTimeout="
+                + hardTimeout + ", idleTimeout=" + idleTimeout + ", match="
+                + match + ", outPort=" + outPort + ", priority=" + priority
+                + ", length=" + length + ", type=" + type + ", version="
+                + version + ", xid=" + xid + "]";
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFFlowRemoved.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFFlowRemoved.java
new file mode 100644 (file)
index 0000000..56c32f1
--- /dev/null
@@ -0,0 +1,273 @@
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+
+import org.openflow.util.U16;
+
+/**
+ * Represents an ofp_flow_removed message
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ *
+ */
+public class OFFlowRemoved extends OFMessage {
+    public static int MINIMUM_LENGTH = 88;
+
+    public enum OFFlowRemovedReason {
+        OFPRR_IDLE_TIMEOUT,
+        OFPRR_HARD_TIMEOUT,
+        OFPRR_DELETE
+    }
+
+    protected OFMatch match;
+    protected long cookie;
+    protected short priority;
+    protected OFFlowRemovedReason reason;
+    protected int durationSeconds;
+    protected int durationNanoseconds;
+    protected short idleTimeout;
+    protected long packetCount;
+    protected long byteCount;
+    
+    public OFFlowRemoved() {
+        super();
+        this.type = OFType.FLOW_REMOVED;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+
+    /**
+     * Get cookie
+     * @return
+     */
+    public long getCookie() {
+        return this.cookie;
+    }
+
+    /**
+     * Set cookie
+     * @param cookie
+     */
+    public void setCookie(long cookie) {
+        this.cookie = cookie;
+    }
+
+    /**
+     * Get idle_timeout
+     * @return
+     */
+    public short getIdleTimeout() {
+        return this.idleTimeout;
+    }
+
+    /**
+     * Set idle_timeout
+     * @param idleTimeout
+     */
+    public void setIdleTimeout(short idleTimeout) {
+        this.idleTimeout = idleTimeout;
+    }
+
+    /**
+     * Gets a copy of the OFMatch object for this FlowMod, changes to this
+     * object do not modify the FlowMod
+     * @return
+     */
+    public OFMatch getMatch() {
+        return this.match;
+    }
+
+    /**
+     * Set match
+     * @param match
+     */
+    public void setMatch(OFMatch match) {
+        this.match = match;
+    }
+
+    /**
+     * Get priority
+     * @return
+     */
+    public short getPriority() {
+        return this.priority;
+    }
+
+    /**
+     * Set priority
+     * @param priority
+     */
+    public void setPriority(short priority) {
+        this.priority = priority;
+    }
+
+    /**
+     * @return the reason
+     */
+    public OFFlowRemovedReason getReason() {
+        return reason;
+    }
+
+    /**
+     * @param reason the reason to set
+     */
+    public void setReason(OFFlowRemovedReason reason) {
+        this.reason = reason;
+    }
+
+    /**
+     * @return the durationSeconds
+     */
+    public int getDurationSeconds() {
+        return durationSeconds;
+    }
+
+    /**
+     * @param durationSeconds the durationSeconds to set
+     */
+    public void setDurationSeconds(int durationSeconds) {
+        this.durationSeconds = durationSeconds;
+    }
+
+    /**
+     * @return the durationNanoseconds
+     */
+    public int getDurationNanoseconds() {
+        return durationNanoseconds;
+    }
+
+    /**
+     * @param durationNanoseconds the durationNanoseconds to set
+     */
+    public void setDurationNanoseconds(int durationNanoseconds) {
+        this.durationNanoseconds = durationNanoseconds;
+    }
+
+    /**
+     * @return the packetCount
+     */
+    public long getPacketCount() {
+        return packetCount;
+    }
+
+    /**
+     * @param packetCount the packetCount to set
+     */
+    public void setPacketCount(long packetCount) {
+        this.packetCount = packetCount;
+    }
+
+    /**
+     * @return the byteCount
+     */
+    public long getByteCount() {
+        return byteCount;
+    }
+
+    /**
+     * @param byteCount the byteCount to set
+     */
+    public void setByteCount(long byteCount) {
+        this.byteCount = byteCount;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        if (this.match == null)
+            this.match = new OFMatch();
+        this.match.readFrom(data);
+        this.cookie = data.getLong();
+        this.priority = data.getShort();
+        this.reason = OFFlowRemovedReason.values()[(0xff & data.get())];
+        data.get(); // pad
+        this.durationSeconds = data.getInt();
+        this.durationNanoseconds = data.getInt();
+        this.idleTimeout = data.getShort();
+        data.get(); // pad
+        data.get(); // pad
+        this.packetCount = data.getLong();
+        this.byteCount = data.getLong();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        this.match.writeTo(data);
+        data.putLong(cookie);
+        data.putShort(priority);
+        data.put((byte) this.reason.ordinal());
+        data.put((byte) 0);
+        data.putInt(this.durationSeconds);
+        data.putInt(this.durationNanoseconds);
+        data.putShort(idleTimeout);
+        data.put((byte) 0); // pad
+        data.put((byte) 0); // pad
+        data.putLong(this.packetCount);
+        data.putLong(this.byteCount);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 271;
+        int result = super.hashCode();
+        result = prime * result + (int) (byteCount ^ (byteCount >>> 32));
+        result = prime * result + (int) (cookie ^ (cookie >>> 32));
+        result = prime * result + durationNanoseconds;
+        result = prime * result + durationSeconds;
+        result = prime * result + idleTimeout;
+        result = prime * result + ((match == null) ? 0 : match.hashCode());
+        result = prime * result + (int) (packetCount ^ (packetCount >>> 32));
+        result = prime * result + priority;
+        result = prime * result + ((reason == null) ? 0 : reason.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFFlowRemoved)) {
+            return false;
+        }
+        OFFlowRemoved other = (OFFlowRemoved) obj;
+        if (byteCount != other.byteCount) {
+            return false;
+        }
+        if (cookie != other.cookie) {
+            return false;
+        }
+        if (durationNanoseconds != other.durationNanoseconds) {
+            return false;
+        }
+        if (durationSeconds != other.durationSeconds) {
+            return false;
+        }
+        if (idleTimeout != other.idleTimeout) {
+            return false;
+        }
+        if (match == null) {
+            if (other.match != null) {
+                return false;
+            }
+        } else if (!match.equals(other.match)) {
+            return false;
+        }
+        if (packetCount != other.packetCount) {
+            return false;
+        }
+        if (priority != other.priority) {
+            return false;
+        }
+        if (reason == null) {
+            if (other.reason != null) {
+                return false;
+            }
+        } else if (!reason.equals(other.reason)) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFGetConfigReply.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFGetConfigReply.java
new file mode 100644 (file)
index 0000000..7348afd
--- /dev/null
@@ -0,0 +1,12 @@
+package org.openflow.protocol;
+
+/**
+ * Represents an OFPT_GET_CONFIG_REPLY type message
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFGetConfigReply extends OFSwitchConfig {
+    public OFGetConfigReply() {
+        super();
+        this.type = OFType.GET_CONFIG_REPLY;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFGetConfigRequest.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFGetConfigRequest.java
new file mode 100644 (file)
index 0000000..111ce03
--- /dev/null
@@ -0,0 +1,15 @@
+package org.openflow.protocol;
+
+import org.openflow.util.U16;
+
+/**
+ * Represents an OFPT_GET_CONFIG_REQUEST type message
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFGetConfigRequest extends OFMessage {
+    public OFGetConfigRequest() {
+        super();
+        this.type = OFType.GET_CONFIG_REQUEST;
+        this.length = U16.t(OFMessage.MINIMUM_LENGTH);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFHello.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFHello.java
new file mode 100644 (file)
index 0000000..47340e5
--- /dev/null
@@ -0,0 +1,22 @@
+package org.openflow.protocol;
+
+import org.openflow.util.U16;
+
+
+/**
+ * Represents an ofp_hello message
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Feb 8, 2010
+ */
+public class OFHello extends OFMessage {
+    public static int MINIMUM_LENGTH = 8;
+
+    /**
+     * Construct a ofp_hello message
+     */
+    public OFHello() {
+        super();
+        this.type = OFType.HELLO;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFMatch.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFMatch.java
new file mode 100644 (file)
index 0000000..c93290e
--- /dev/null
@@ -0,0 +1,1047 @@
+package org.openflow.protocol;
+
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import org.openflow.util.HexString;
+import org.openflow.util.U16;
+import org.openflow.util.U8;
+
+/**
+ * Represents an ofp_match structure
+ * 
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ * 
+ */
+public class OFMatch implements Cloneable, Serializable {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+    public static int MINIMUM_LENGTH = 40;
+    final public static int OFPFW_ALL = ((1 << 22) - 1);
+
+    final public static int OFPFW_IN_PORT = 1 << 0; /* Switch input port. */
+    final public static int OFPFW_DL_VLAN = 1 << 1; /* VLAN id. */
+    final public static int OFPFW_DL_SRC = 1 << 2; /* Ethernet source address. */
+    final public static int OFPFW_DL_DST = 1 << 3; /*
+                                                    * Ethernet destination
+                                                    * address.
+                                                    */
+    final public static int OFPFW_DL_TYPE = 1 << 4; /* Ethernet frame type. */
+    final public static int OFPFW_NW_PROTO = 1 << 5; /* IP protocol. */
+    final public static int OFPFW_TP_SRC = 1 << 6; /* TCP/UDP source port. */
+    final public static int OFPFW_TP_DST = 1 << 7; /* TCP/UDP destination port. */
+
+    /*
+     * IP source address wildcard bit count. 0 is exact match, 1 ignores the
+     * LSB, 2 ignores the 2 least-significant bits, ..., 32 and higher wildcard
+     * the entire field. This is the *opposite* of the usual convention where
+     * e.g. /24 indicates that 8 bits (not 24 bits) are wildcarded.
+     */
+    final public static int OFPFW_NW_SRC_SHIFT = 8;
+    final public static int OFPFW_NW_SRC_BITS = 6;
+    final public static int OFPFW_NW_SRC_MASK = ((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT;
+    final public static int OFPFW_NW_SRC_ALL = 32 << OFPFW_NW_SRC_SHIFT;
+
+    /* IP destination address wildcard bit count. Same format as source. */
+    final public static int OFPFW_NW_DST_SHIFT = 14;
+    final public static int OFPFW_NW_DST_BITS = 6;
+    final public static int OFPFW_NW_DST_MASK = ((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT;
+    final public static int OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT;
+
+    final public static int OFPFW_DL_VLAN_PCP = 1 << 20; /* VLAN priority. */
+    final public static int OFPFW_NW_TOS = 1 << 21; /*
+                                                     * IP ToS (DSCP field, 6
+                                                     * bits).
+                                                     */
+
+    /* List of Strings for marshalling and unmarshalling to human readable forms */
+    final public static String STR_IN_PORT = "in_port";
+    final public static String STR_DL_DST = "dl_dst";
+    final public static String STR_DL_SRC = "dl_src";
+    final public static String STR_DL_TYPE = "dl_type";
+    final public static String STR_DL_VLAN = "dl_vlan";
+    final public static String STR_DL_VLAN_PCP = "dl_vpcp";
+    final public static String STR_NW_DST = "nw_dst";
+    final public static String STR_NW_SRC = "nw_src";
+    final public static String STR_NW_PROTO = "nw_proto";
+    final public static String STR_NW_TOS = "nw_tos";
+    final public static String STR_TP_DST = "tp_dst";
+    final public static String STR_TP_SRC = "tp_src";
+
+    protected int wildcards;
+    protected short inputPort;
+    protected byte[] dataLayerSource;
+    protected byte[] dataLayerDestination;
+    protected short dataLayerVirtualLan;
+    protected byte dataLayerVirtualLanPriorityCodePoint;
+    protected short dataLayerType;
+    protected byte networkTypeOfService;
+    protected byte networkProtocol;
+    protected int networkSource;
+    protected int networkDestination;
+    protected short transportSource;
+    protected short transportDestination;
+
+    /**
+     * By default, create a OFMatch that matches everything
+     * 
+     * (mostly because it's the least amount of work to make a valid OFMatch)
+     */
+    public OFMatch() {
+        this.wildcards = OFPFW_ALL;
+        this.dataLayerDestination = new byte[6];
+        this.dataLayerSource = new byte[6];
+    }
+
+    /**
+     * Get dl_dst
+     * 
+     * @return an arrays of bytes
+     */
+    public byte[] getDataLayerDestination() {
+        return this.dataLayerDestination;
+    }
+
+    /**
+     * Set dl_dst
+     * 
+     * @param dataLayerDestination
+     */
+    public OFMatch setDataLayerDestination(byte[] dataLayerDestination) {
+        this.dataLayerDestination = dataLayerDestination;
+        return this;
+    }
+
+    /**
+     * Set dl_dst, but first translate to byte[] using HexString
+     * 
+     * @param mac
+     *            A colon separated string of 6 pairs of octets, e..g.,
+     *            "00:17:42:EF:CD:8D"
+     */
+    public OFMatch setDataLayerDestination(String mac) {
+        byte bytes[] = HexString.fromHexString(mac);
+        if (bytes.length != 6)
+            throw new IllegalArgumentException(
+                    "expected string with 6 octets, got '" + mac + "'");
+        this.dataLayerDestination = bytes;
+        return this;
+    }
+
+    /**
+     * Get dl_src
+     * 
+     * @return an array of bytes
+     */
+    public byte[] getDataLayerSource() {
+        return this.dataLayerSource;
+    }
+
+    /**
+     * Set dl_src
+     * 
+     * @param dataLayerSource
+     */
+    public OFMatch setDataLayerSource(byte[] dataLayerSource) {
+        this.dataLayerSource = dataLayerSource;
+        return this;
+    }
+
+    /**
+     * Set dl_src, but first translate to byte[] using HexString
+     * 
+     * @param mac
+     *            A colon separated string of 6 pairs of octets, e..g.,
+     *            "00:17:42:EF:CD:8D"
+     */
+    public OFMatch setDataLayerSource(String mac) {
+        byte bytes[] = HexString.fromHexString(mac);
+        if (bytes.length != 6)
+            throw new IllegalArgumentException(
+                    "expected string with 6 octets, got '" + mac + "'");
+        this.dataLayerSource = bytes;
+        return this;
+    }
+
+    /**
+     * Get dl_type
+     * 
+     * @return ether_type
+     */
+    public short getDataLayerType() {
+        return this.dataLayerType;
+    }
+
+    /**
+     * Set dl_type
+     * 
+     * @param dataLayerType
+     */
+    public OFMatch setDataLayerType(short dataLayerType) {
+        this.dataLayerType = dataLayerType;
+        return this;
+    }
+
+    /**
+     * Get dl_vlan
+     * 
+     * @return vlan tag; VLAN_NONE == no tag
+     */
+    public short getDataLayerVirtualLan() {
+        return this.dataLayerVirtualLan;
+    }
+
+    /**
+     * Set dl_vlan
+     * 
+     * @param dataLayerVirtualLan
+     */
+    public OFMatch setDataLayerVirtualLan(short dataLayerVirtualLan) {
+        this.dataLayerVirtualLan = dataLayerVirtualLan;
+        return this;
+    }
+
+    /**
+     * Get dl_vlan_pcp
+     * 
+     * @return
+     */
+    public byte getDataLayerVirtualLanPriorityCodePoint() {
+        return this.dataLayerVirtualLanPriorityCodePoint;
+    }
+
+    /**
+     * Set dl_vlan_pcp
+     * 
+     * @param pcp
+     */
+    public OFMatch setDataLayerVirtualLanPriorityCodePoint(byte pcp) {
+        this.dataLayerVirtualLanPriorityCodePoint = pcp;
+        return this;
+    }
+
+    /**
+     * Get in_port
+     * 
+     * @return
+     */
+    public short getInputPort() {
+        return this.inputPort;
+    }
+
+    /**
+     * Set in_port
+     * 
+     * @param inputPort
+     */
+    public OFMatch setInputPort(short inputPort) {
+        this.inputPort = inputPort;
+        return this;
+    }
+
+    /**
+     * Get nw_dst
+     * 
+     * @return
+     */
+    public int getNetworkDestination() {
+        return this.networkDestination;
+    }
+
+    /**
+     * Set nw_dst
+     * 
+     * @param networkDestination
+     */
+    public OFMatch setNetworkDestination(int networkDestination) {
+        this.networkDestination = networkDestination;
+        return this;
+    }
+
+    /**
+     * Parse this match's wildcard fields and return the number of significant
+     * bits in the IP destination field.
+     * 
+     * NOTE: this returns the number of bits that are fixed, i.e., like CIDR,
+     * not the number of bits that are free like OpenFlow encodes.
+     * 
+     * @return a number between 0 (matches all IPs) and 63 ( 32>= implies exact
+     *         match)
+     */
+    public int getNetworkDestinationMaskLen() {
+        return Math
+                .max(32 - ((wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT),
+                        0);
+    }
+
+    /**
+     * Parse this match's wildcard fields and return the number of significant
+     * bits in the IP destination field.
+     * 
+     * NOTE: this returns the number of bits that are fixed, i.e., like CIDR,
+     * not the number of bits that are free like OpenFlow encodes.
+     * 
+     * @return a number between 0 (matches all IPs) and 32 (exact match)
+     */
+    public int getNetworkSourceMaskLen() {
+        return Math
+                .max(32 - ((wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT),
+                        0);
+    }
+
+    /**
+     * Get nw_proto
+     * 
+     * @return
+     */
+    public byte getNetworkProtocol() {
+        return this.networkProtocol;
+    }
+
+    /**
+     * Set nw_proto
+     * 
+     * @param networkProtocol
+     */
+    public OFMatch setNetworkProtocol(byte networkProtocol) {
+        this.networkProtocol = networkProtocol;
+        return this;
+    }
+
+    /**
+     * Get nw_src
+     * 
+     * @return
+     */
+    public int getNetworkSource() {
+        return this.networkSource;
+    }
+
+    /**
+     * Set nw_src
+     * 
+     * @param networkSource
+     */
+    public OFMatch setNetworkSource(int networkSource) {
+        this.networkSource = networkSource;
+        return this;
+    }
+
+    /**
+     * Get nw_tos
+     * 
+     * @return
+     */
+    public byte getNetworkTypeOfService() {
+        return this.networkTypeOfService;
+    }
+
+    /**
+     * Set nw_tos
+     * 
+     * @param networkTypeOfService
+     */
+    public OFMatch setNetworkTypeOfService(byte networkTypeOfService) {
+        this.networkTypeOfService = networkTypeOfService;
+        return this;
+    }
+
+    /**
+     * Get tp_dst
+     * 
+     * @return
+     */
+    public short getTransportDestination() {
+        return this.transportDestination;
+    }
+
+    /**
+     * Set tp_dst
+     * 
+     * @param transportDestination
+     */
+    public OFMatch setTransportDestination(short transportDestination) {
+        this.transportDestination = transportDestination;
+        return this;
+    }
+
+    /**
+     * Get tp_src
+     * 
+     * @return
+     */
+    public short getTransportSource() {
+        return this.transportSource;
+    }
+
+    /**
+     * Set tp_src
+     * 
+     * @param transportSource
+     */
+    public OFMatch setTransportSource(short transportSource) {
+        this.transportSource = transportSource;
+        return this;
+    }
+
+    /**
+     * Get wildcards
+     * 
+     * @return
+     */
+    public int getWildcards() {
+        return this.wildcards;
+    }
+
+    /**
+     * Set wildcards
+     * 
+     * @param wildcards
+     */
+    public OFMatch setWildcards(int wildcards) {
+        this.wildcards = wildcards;
+        return this;
+    }
+
+    /**
+     * Initializes this OFMatch structure with the corresponding data from the
+     * specified packet.
+     * 
+     * Must specify the input port, to ensure that this.in_port is set
+     * correctly.
+     * 
+     * Specify OFPort.NONE or OFPort.ANY if input port not applicable or
+     * available
+     * 
+     * @param packetData
+     *            The packet's data
+     * @param inputPort
+     *            the port the packet arrived on
+     */
+    public OFMatch loadFromPacket(byte[] packetData, short inputPort) {
+        short scratch;
+        int transportOffset = 34;
+        ByteBuffer packetDataBB = ByteBuffer.wrap(packetData);
+        int limit = packetDataBB.limit();
+
+        this.wildcards = 0; // all fields have explicit entries
+
+        this.inputPort = inputPort;
+
+        if (inputPort == OFPort.OFPP_ALL.getValue())
+            this.wildcards |= OFPFW_IN_PORT;
+
+        assert (limit >= 14);
+        // dl dst
+        this.dataLayerDestination = new byte[6];
+        packetDataBB.get(this.dataLayerDestination);
+        // dl src
+        this.dataLayerSource = new byte[6];
+        packetDataBB.get(this.dataLayerSource);
+        // dl type
+        this.dataLayerType = packetDataBB.getShort();
+
+        if (getDataLayerType() != (short) 0x8100) { // need cast to avoid signed
+            // bug
+            setDataLayerVirtualLan((short) 0xffff);
+            setDataLayerVirtualLanPriorityCodePoint((byte) 0);
+        } else {
+            // has vlan tag
+            scratch = packetDataBB.getShort();
+            setDataLayerVirtualLan((short) (0xfff & scratch));
+            setDataLayerVirtualLanPriorityCodePoint((byte) ((0xe000 & scratch) >> 13));
+            this.dataLayerType = packetDataBB.getShort();
+        }
+
+        switch (getDataLayerType()) {
+        case 0x0800:
+            // ipv4
+            // check packet length
+            scratch = packetDataBB.get();
+            scratch = (short) (0xf & scratch);
+            transportOffset = (packetDataBB.position() - 1) + (scratch * 4);
+            // nw tos (dscp)
+            scratch = packetDataBB.get();
+            setNetworkTypeOfService((byte) ((0xfc & scratch) >> 2));
+            // nw protocol
+            packetDataBB.position(packetDataBB.position() + 7);
+            this.networkProtocol = packetDataBB.get();
+            // nw src
+            packetDataBB.position(packetDataBB.position() + 2);
+            this.networkSource = packetDataBB.getInt();
+            // nw dst
+            this.networkDestination = packetDataBB.getInt();
+            packetDataBB.position(transportOffset);
+            break;
+        case 0x0806:
+            // arp
+            int arpPos = packetDataBB.position();
+            // opcode
+            scratch = packetDataBB.getShort(arpPos + 6);
+            setNetworkProtocol((byte) (0xff & scratch));
+
+            scratch = packetDataBB.getShort(arpPos + 2);
+            // if ipv4 and addr len is 4
+            if (scratch == 0x800 && packetDataBB.get(arpPos + 5) == 4) {
+                // nw src
+                this.networkSource = packetDataBB.getInt(arpPos + 14);
+                // nw dst
+                this.networkDestination = packetDataBB.getInt(arpPos + 24);
+            } else {
+                setNetworkSource(0);
+                setNetworkDestination(0);
+            }
+            break;
+        default:
+            setNetworkTypeOfService((byte) 0);
+            setNetworkProtocol((byte) 0);
+            setNetworkSource(0);
+            setNetworkDestination(0);
+            break;
+        }
+
+        switch (getNetworkProtocol()) {
+        case 0x01:
+            // icmp
+            // type
+            this.transportSource = U8.f(packetDataBB.get());
+            // code
+            this.transportDestination = U8.f(packetDataBB.get());
+            break;
+        case 0x06:
+            // tcp
+            // tcp src
+            this.transportSource = packetDataBB.getShort();
+            // tcp dest
+            this.transportDestination = packetDataBB.getShort();
+            break;
+        case 0x11:
+            // udp
+            // udp src
+            this.transportSource = packetDataBB.getShort();
+            // udp dest
+            this.transportDestination = packetDataBB.getShort();
+            break;
+        default:
+            setTransportDestination((short) 0);
+            setTransportSource((short) 0);
+            break;
+        }
+        return this;
+    }
+
+    /**
+     * Read this message off the wire from the specified ByteBuffer
+     * 
+     * @param data
+     */
+    public void readFrom(ByteBuffer data) {
+        this.wildcards = data.getInt();
+        this.inputPort = data.getShort();
+        this.dataLayerSource = new byte[6];
+        data.get(this.dataLayerSource);
+        this.dataLayerDestination = new byte[6];
+        data.get(this.dataLayerDestination);
+        this.dataLayerVirtualLan = data.getShort();
+        this.dataLayerVirtualLanPriorityCodePoint = data.get();
+        data.get(); // pad
+        this.dataLayerType = data.getShort();
+        this.networkTypeOfService = data.get();
+        this.networkProtocol = data.get();
+        data.get(); // pad
+        data.get(); // pad
+        this.networkSource = data.getInt();
+        this.networkDestination = data.getInt();
+        this.transportSource = data.getShort();
+        this.transportDestination = data.getShort();
+    }
+
+    /**
+     * Write this message's binary format to the specified ByteBuffer
+     * 
+     * @param data
+     */
+    public void writeTo(ByteBuffer data) {
+        data.putInt(wildcards);
+        data.putShort(inputPort);
+        data.put(this.dataLayerSource);
+        data.put(this.dataLayerDestination);
+        data.putShort(dataLayerVirtualLan);
+        data.put(dataLayerVirtualLanPriorityCodePoint);
+        data.put((byte) 0x0); // pad
+        data.putShort(dataLayerType);
+        data.put(networkTypeOfService);
+        data.put(networkProtocol);
+        data.put((byte) 0x0); // pad
+        data.put((byte) 0x0); // pad
+        data.putInt(networkSource);
+        data.putInt(networkDestination);
+        data.putShort(transportSource);
+        data.putShort(transportDestination);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 131;
+        int result = 1;
+        result = prime * result + Arrays.hashCode(dataLayerDestination);
+        result = prime * result + Arrays.hashCode(dataLayerSource);
+        result = prime * result + dataLayerType;
+        result = prime * result + dataLayerVirtualLan;
+        result = prime * result + dataLayerVirtualLanPriorityCodePoint;
+        result = prime * result + inputPort;
+        result = prime * result + networkDestination;
+        result = prime * result + networkProtocol;
+        result = prime * result + networkSource;
+        result = prime * result + networkTypeOfService;
+        result = prime * result + transportDestination;
+        result = prime * result + transportSource;
+        result = prime * result + wildcards;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFMatch)) {
+            return false;
+        }
+        OFMatch other = (OFMatch) obj;
+        if (!Arrays.equals(dataLayerDestination, other.dataLayerDestination)) {
+            return false;
+        }
+        if (!Arrays.equals(dataLayerSource, other.dataLayerSource)) {
+            return false;
+        }
+        if (dataLayerType != other.dataLayerType) {
+            return false;
+        }
+        if (dataLayerVirtualLan != other.dataLayerVirtualLan) {
+            return false;
+        }
+        if (dataLayerVirtualLanPriorityCodePoint != other.dataLayerVirtualLanPriorityCodePoint) {
+            return false;
+        }
+        if (inputPort != other.inputPort) {
+            return false;
+        }
+        if (networkDestination != other.networkDestination) {
+            return false;
+        }
+        if (networkProtocol != other.networkProtocol) {
+            return false;
+        }
+        if (networkSource != other.networkSource) {
+            return false;
+        }
+        if (networkTypeOfService != other.networkTypeOfService) {
+            return false;
+        }
+        if (transportDestination != other.transportDestination) {
+            return false;
+        }
+        if (transportSource != other.transportSource) {
+            return false;
+        }
+        if ((wildcards & OFMatch.OFPFW_ALL) != (other.wildcards & OFPFW_ALL)) { // only
+            // consider
+            // allocated
+            // part
+            // of
+            // wildcards
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Implement clonable interface
+     */
+    @Override
+    public OFMatch clone() {
+        try {
+            OFMatch ret = (OFMatch) super.clone();
+            ret.dataLayerDestination = this.dataLayerDestination.clone();
+            ret.dataLayerSource = this.dataLayerSource.clone();
+            return ret;
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Output a dpctl-styled string, i.e., only list the elements that are not
+     * wildcarded
+     * 
+     * A match-everything OFMatch outputs "OFMatch[]"
+     * 
+     * @return 
+     *         "OFMatch[dl_src:00:20:01:11:22:33,nw_src:192.168.0.0/24,tp_dst:80]"
+     */
+    @Override
+    public String toString() {
+        String str = "";
+
+        // l1
+        if ((wildcards & OFPFW_IN_PORT) == 0)
+            str += "," + STR_IN_PORT + "=" + U16.f(this.inputPort);
+
+        // l2
+        if ((wildcards & OFPFW_DL_DST) == 0)
+            str += "," + STR_DL_DST + "="
+                    + HexString.toHexString(this.dataLayerDestination);
+        if ((wildcards & OFPFW_DL_SRC) == 0)
+            str += "," + STR_DL_SRC + "="
+                    + HexString.toHexString(this.dataLayerSource);
+        if ((wildcards & OFPFW_DL_TYPE) == 0)
+            str += "," + STR_DL_TYPE + "=0x"
+                    + Integer.toHexString(U16.f(this.dataLayerType));
+        if ((wildcards & OFPFW_DL_VLAN) == 0)
+            str += "," + STR_DL_VLAN + "=0x"
+                    + Integer.toHexString(U16.f(this.dataLayerVirtualLan));
+        if ((wildcards & OFPFW_DL_VLAN_PCP) == 0)
+            str += ","
+                    + STR_DL_VLAN_PCP
+                    + "="
+                    + Integer.toHexString(U8
+                            .f(this.dataLayerVirtualLanPriorityCodePoint));
+
+        // l3
+        if (getNetworkDestinationMaskLen() > 0)
+            str += ","
+                    + STR_NW_DST
+                    + "="
+                    + cidrToString(networkDestination,
+                            getNetworkDestinationMaskLen());
+        if (getNetworkSourceMaskLen() > 0)
+            str += "," + STR_NW_SRC + "="
+                    + cidrToString(networkSource, getNetworkSourceMaskLen());
+        if ((wildcards & OFPFW_NW_PROTO) == 0)
+            str += "," + STR_NW_PROTO + "=" + this.networkProtocol;
+        if ((wildcards & OFPFW_NW_TOS) == 0)
+            str += "," + STR_NW_TOS + "=" + this.networkTypeOfService;
+
+        // l4
+        if ((wildcards & OFPFW_TP_DST) == 0)
+            str += "," + STR_TP_DST + "=" + this.transportDestination;
+        if ((wildcards & OFPFW_TP_SRC) == 0)
+            str += "," + STR_TP_SRC + "=" + this.transportSource;
+        if ((str.length() > 0) && (str.charAt(0) == ','))
+            str = str.substring(1); // trim the leading ","
+        // done
+        return "OFMatch[" + str + "]";
+    }
+
+    private String cidrToString(int ip, int prefix) {
+        String str;
+        if (prefix >= 32) {
+            str = ipToString(ip);
+        } else {
+            // use the negation of mask to fake endian magic
+            int mask = ~((1 << (32 - prefix)) - 1);
+            str = ipToString(ip & mask) + "/" + prefix;
+        }
+
+        return str;
+    }
+
+    /**
+     * Set this OFMatch's parameters based on a comma-separated key=value pair
+     * dpctl-style string, e.g., from the output of OFMatch.toString() <br>
+     * <p>
+     * Supported keys/values include <br>
+     * <p>
+     * <TABLE border=1>
+     * <TR>
+     * <TD>KEY(s)
+     * <TD>VALUE
+     * </TR>
+     * <TR>
+     * <TD>"in_port","input_port"
+     * <TD>integer
+     * </TR>
+     * <TR>
+     * <TD>"dl_src","eth_src", "dl_dst","eth_dst"
+     * <TD>hex-string
+     * </TR>
+     * <TR>
+     * <TD>"dl_type", "dl_vlan", "dl_vlan_pcp"
+     * <TD>integer
+     * </TR>
+     * <TR>
+     * <TD>"nw_src", "nw_dst", "ip_src", "ip_dst"
+     * <TD>CIDR-style netmask
+     * </TR>
+     * <TR>
+     * <TD>"tp_src","tp_dst"
+     * <TD>integer (max 64k)
+     * </TR>
+     * </TABLE>
+     * <p>
+     * The CIDR-style netmasks assume 32 netmask if none given, so:
+     * "128.8.128.118/32" is the same as "128.8.128.118"
+     * 
+     * @param match
+     *            a key=value comma separated string, e.g.
+     *            "in_port=5,ip_dst=192.168.0.0/16,tp_src=80"
+     * @throws IllegalArgumentException
+     *             on unexpected key or value
+     */
+
+    public void fromString(String match) throws IllegalArgumentException {
+        if (match.equals("") || match.equalsIgnoreCase("any")
+                || match.equalsIgnoreCase("all") || match.equals("[]"))
+            match = "OFMatch[]";
+        String[] tokens = match.split("[\\[,\\]]");
+        String[] values;
+        int initArg = 0;
+        if (tokens[0].equals("OFMatch"))
+            initArg = 1;
+        this.wildcards = OFPFW_ALL;
+        int i;
+        for (i = initArg; i < tokens.length; i++) {
+            values = tokens[i].split("=");
+            if (values.length != 2)
+                throw new IllegalArgumentException("Token " + tokens[i]
+                        + " does not have form 'key=value' parsing " + match);
+            values[0] = values[0].toLowerCase(); // try to make this case insens
+            if (values[0].equals(STR_IN_PORT) || values[0].equals("input_port")) {
+                this.inputPort = U16.t(Integer.valueOf(values[1]));
+                this.wildcards &= ~OFPFW_IN_PORT;
+            } else if (values[0].equals(STR_DL_DST)
+                    || values[0].equals("eth_dst")) {
+                this.dataLayerDestination = HexString.fromHexString(values[1]);
+                this.wildcards &= ~OFPFW_DL_DST;
+            } else if (values[0].equals(STR_DL_SRC)
+                    || values[0].equals("eth_src")) {
+                this.dataLayerSource = HexString.fromHexString(values[1]);
+                this.wildcards &= ~OFPFW_DL_SRC;
+            } else if (values[0].equals(STR_DL_TYPE)
+                    || values[0].equals("eth_type")) {
+                if (values[1].startsWith("0x"))
+                    this.dataLayerType = U16.t(Integer.valueOf(
+                            values[1].replaceFirst("0x", ""), 16));
+                else
+                    this.dataLayerType = U16.t(Integer.valueOf(values[1]));
+                this.wildcards &= ~OFPFW_DL_TYPE;
+            } else if (values[0].equals(STR_DL_VLAN)) {
+                this.dataLayerVirtualLan = U16.t(Integer.valueOf(values[1]));
+                this.wildcards &= ~OFPFW_DL_VLAN;
+            } else if (values[0].equals(STR_DL_VLAN_PCP)) {
+                this.dataLayerVirtualLanPriorityCodePoint = U8.t(Short
+                        .valueOf(values[1]));
+                this.wildcards &= ~OFPFW_DL_VLAN_PCP;
+            } else if (values[0].equals(STR_NW_DST)
+                    || values[0].equals("ip_dst"))
+                setFromCIDR(values[1], STR_NW_DST);
+            else if (values[0].equals(STR_NW_SRC) || values[0].equals("ip_src"))
+                setFromCIDR(values[1], STR_NW_SRC);
+            else if (values[0].equals(STR_NW_PROTO)) {
+                this.networkProtocol = U8.t(Short.valueOf(values[1]));
+                this.wildcards &= ~OFPFW_NW_PROTO;
+            } else if (values[0].equals(STR_NW_TOS)) {
+                this.networkTypeOfService = U8.t(Short.valueOf(values[1]));
+                this.wildcards &= ~OFPFW_NW_TOS;
+            } else if (values[0].equals(STR_TP_DST)) {
+                this.transportDestination = U16.t(Integer.valueOf(values[1]));
+                this.wildcards &= ~OFPFW_TP_DST;
+            } else if (values[0].equals(STR_TP_SRC)) {
+                this.transportSource = U16.t(Integer.valueOf(values[1]));
+                this.wildcards &= ~OFPFW_TP_SRC;
+            } else
+                throw new IllegalArgumentException("unknown token " + tokens[i]
+                        + " parsing " + match);
+        }
+    }
+
+    /**
+     * Set the networkSource or networkDestionation address and their wildcards
+     * from the CIDR string
+     * 
+     * @param cidr
+     *            "192.168.0.0/16" or "172.16.1.5"
+     * @param which
+     *            one of STR_NW_DST or STR_NW_SRC
+     * @throws IllegalArgumentException
+     */
+    private void setFromCIDR(String cidr, String which)
+            throws IllegalArgumentException {
+        String values[] = cidr.split("/");
+        String[] ip_str = values[0].split("\\.");
+        int ip = 0;
+        ip += Integer.valueOf(ip_str[0]) << 24;
+        ip += Integer.valueOf(ip_str[1]) << 16;
+        ip += Integer.valueOf(ip_str[2]) << 8;
+        ip += Integer.valueOf(ip_str[3]);
+        int prefix = 32; // all bits are fixed, by default
+
+        if (values.length >= 2)
+            prefix = Integer.valueOf(values[1]);
+        int mask = 32 - prefix;
+        if (which.equals(STR_NW_DST)) {
+            this.networkDestination = ip;
+            this.wildcards = (wildcards & ~OFPFW_NW_DST_MASK)
+                    | (mask << OFPFW_NW_DST_SHIFT);
+        } else if (which.equals(STR_NW_SRC)) {
+            this.networkSource = ip;
+            this.wildcards = (wildcards & ~OFPFW_NW_SRC_MASK)
+                    | (mask << OFPFW_NW_SRC_SHIFT);
+        }
+    }
+
+    protected static String ipToString(int ip) {
+        return Integer.toString(U8.f((byte) ((ip & 0xff000000) >> 24))) + "."
+                + Integer.toString((ip & 0x00ff0000) >> 16) + "."
+                + Integer.toString((ip & 0x0000ff00) >> 8) + "."
+                + Integer.toString(ip & 0x000000ff);
+    }
+
+    /**
+     * Reverses a match such that source and destination values plus
+     * corresponding masks are swapped. An input port must be explicitly
+     * passed in as the match does not contain an output port.
+     *
+     * @param inputPort new input port to use in match
+     * @param wildcardInputPort should the input port be wildcarded
+     *
+     * @return Reversed copy of match
+     */
+    public OFMatch reverse(short inputPort, boolean wildcardInputPort) {
+        OFMatch ret = this.clone();
+
+        // Set the input port
+        if (wildcardInputPort) {
+            ret.inputPort = 0;
+            ret.wildcards |= OFPFW_IN_PORT;
+        } else {
+            ret.inputPort = inputPort;
+            ret.wildcards &= ~OFPFW_IN_PORT;
+        }
+
+        // Switch the source/dest fields
+        ret.dataLayerDestination = this.dataLayerSource.clone();
+        ret.dataLayerSource = this.dataLayerDestination.clone();
+
+        ret.networkDestination = this.networkSource;
+        ret.networkSource = this.networkDestination;
+
+        ret.transportDestination = this.transportSource;
+        ret.transportSource = this.transportDestination;
+
+        // Switch the wildcards on source/dest fields
+        ret.wildcards &= ~(OFPFW_DL_DST | OFPFW_DL_SRC |
+                OFPFW_NW_DST_MASK | OFPFW_NW_SRC_MASK |
+                OFPFW_TP_DST | OFPFW_TP_SRC);
+        ret.wildcards |= ((this.wildcards & OFPFW_DL_DST) != 0 ) ? OFPFW_DL_SRC : 0;
+        ret.wildcards |= ((this.wildcards & OFPFW_DL_SRC) != 0 ) ? OFPFW_DL_DST : 0;
+        ret.wildcards |= (((this.wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT) << OFPFW_NW_SRC_SHIFT);
+        ret.wildcards |= (((this.wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT) << OFPFW_NW_DST_SHIFT);
+        ret.wildcards |= ((this.wildcards & OFPFW_TP_DST) != 0 ) ? OFPFW_TP_SRC : 0;
+        ret.wildcards |= ((this.wildcards & OFPFW_TP_SRC) != 0 ) ? OFPFW_TP_DST : 0;
+
+        return ret;
+    }
+
+    /**
+     * Check whether this match subsumes another match.
+     *
+     * This match subsumes another match if each field in this
+     * object either:
+     * <ol>
+     *   <li> exactly matches the corresponding field in the other match
+     *   <li> the field is wildcarded in this object
+     * </ol>
+     * Note: The network source and destination wildcards must have fewer
+     * or the same number of bits wildcarded in this object as the other.
+     *
+     * @param match match used for comparison when checking subsumes
+     * @return boolean indicating whether this match subsumes another match
+     */
+    public boolean subsumes(OFMatch match) {
+        // L1
+        if ((wildcards & OFPFW_IN_PORT) == 0) {
+            if (inputPort != match.inputPort) {
+                return false;
+            }
+        }
+
+        // L2
+        if ((wildcards & OFPFW_DL_DST) == 0) {
+            if (!Arrays.equals(dataLayerDestination, match.dataLayerDestination)) {
+                return false;
+            }
+        }
+        if ((wildcards & OFPFW_DL_SRC) == 0) {
+            if (!Arrays.equals(dataLayerSource, match.dataLayerSource)) {
+                return false;
+            }
+        }
+        if ((wildcards & OFPFW_DL_TYPE) == 0) {
+            if (dataLayerType != match.dataLayerType) {
+                return false;
+            }
+        }
+        if ((wildcards & OFPFW_DL_VLAN) == 0) {
+            if (dataLayerVirtualLan!= match.dataLayerVirtualLan) {
+                return false;
+            }
+        }
+        if ((wildcards & OFPFW_DL_VLAN_PCP) == 0) {
+            if (dataLayerVirtualLanPriorityCodePoint != match.dataLayerVirtualLanPriorityCodePoint) {
+                return false;
+            }
+        }
+
+        // L3
+        int maskLen = getNetworkDestinationMaskLen();
+        if (maskLen > match.getNetworkDestinationMaskLen()) {
+            return false;
+        }
+        int mask = (maskLen == 0) ? 0 : (0xffffffff << (32 - maskLen));
+        if ((networkDestination & mask) != (match.networkDestination & mask)) {
+            return false;
+        }
+        maskLen = getNetworkSourceMaskLen();
+        if (maskLen > match.getNetworkSourceMaskLen()) {
+            return false;
+        }
+        mask = (maskLen == 0) ? 0 : (0xffffffff << (32 - maskLen));
+        if ((networkSource & mask) != (match.networkSource & mask)) {
+            return false;
+        }
+        if ((wildcards & OFPFW_NW_PROTO) == 0) {
+            if (networkProtocol != match.networkProtocol) {
+                return false;
+            }
+        }
+        if ((wildcards & OFPFW_NW_TOS) == 0) {
+            if (networkTypeOfService != match.networkTypeOfService) {
+                return false;
+            }
+        }
+
+        // L4
+        if ((wildcards & OFPFW_TP_DST) == 0) {
+            if (transportDestination != match.transportDestination) {
+                return false;
+            }
+        }
+        if ((wildcards & OFPFW_TP_SRC) == 0) {
+            if (transportSource != match.transportSource) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFMatchBeanInfo.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFMatchBeanInfo.java
new file mode 100644 (file)
index 0000000..9f7a40e
--- /dev/null
@@ -0,0 +1,90 @@
+package org.openflow.protocol;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.beans.SimpleBeanInfo;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Extra info for how to treat OFMatch as a JavaBean
+ * 
+ * For some (inane!) reason, using chained setters in OFMatch breaks a lot of the JavaBean defaults.
+ * 
+ * We don't really use OFMatch as a java bean, but there are a lot of nice XML utils that work for
+ * free if OFMatch follows the java bean paradigm.
+ * 
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ *
+ */
+
+public class OFMatchBeanInfo extends SimpleBeanInfo {
+
+    @Override
+    public PropertyDescriptor[] getPropertyDescriptors() {
+        List<PropertyDescriptor> descs = new LinkedList<PropertyDescriptor>();
+        Field[] fields = OFMatch.class.getDeclaredFields();
+        String name;
+        for (int i=0; i< fields.length; i++) {
+            int mod = fields[i].getModifiers();
+            if(Modifier.isFinal(mod) ||     // don't expose static or final fields 
+                    Modifier.isStatic(mod))
+                continue;
+            
+            name = fields[i].getName();
+            Class<?> type = fields[i].getType();
+            
+            try {
+                descs.add(new PropertyDescriptor(name, 
+                        name2getter(OFMatch.class, name), 
+                        name2setter(OFMatch.class, name, type)));
+            } catch (IntrospectionException e) {
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
+        }
+        
+        return descs.toArray(new PropertyDescriptor[0]);
+    }
+
+
+    private Method name2setter(Class<OFMatch> c, String name, Class<?> type) {
+        String mName = "set" + toLeadingCaps(name);
+        Method m = null;
+        try {
+            m = c.getMethod(mName, new Class[]{ type});
+        } catch (SecurityException e) {
+            
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        } catch (NoSuchMethodException e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+        return m;
+    }
+
+    private Method name2getter(Class<OFMatch> c, String name) {
+        String mName= "get" + toLeadingCaps(name);
+        Method m = null;
+        try {
+            m = c.getMethod(mName, new Class[]{});
+        } catch (SecurityException e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        } catch (NoSuchMethodException e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+        return m;
+    }
+    
+    private String toLeadingCaps(String s) {
+        char[] array = s.toCharArray();
+        array[0] = Character.toUpperCase(array[0]);
+        return String.valueOf(array, 0, array.length);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFMessage.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFMessage.java
new file mode 100644 (file)
index 0000000..5b40a6e
--- /dev/null
@@ -0,0 +1,197 @@
+package org.openflow.protocol;
+
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+
+import org.openflow.util.U16;
+import org.openflow.util.U32;
+import org.openflow.util.U8;
+
+/**
+ * The base class for all OpenFlow protocol messages. This class contains the
+ * equivalent of the ofp_header which is present in all OpenFlow messages.
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Feb 3, 2010
+ * @author Rob Sherwood (rob.sherwood@stanford.edu) - Feb 3, 2010
+ */
+public class OFMessage implements Serializable{
+    public static byte OFP_VERSION = 0x01;
+    public static int MINIMUM_LENGTH = 8;
+
+    protected byte version;
+    protected OFType type;
+    protected short length;
+    protected int xid;
+
+    public OFMessage() {
+        this.version = OFP_VERSION;
+    }
+
+    /**
+     * Get the length of this message
+     *
+     * @return
+     */
+    public short getLength() {
+        return length;
+    }
+
+    /**
+     * Get the length of this message, unsigned
+     *
+     * @return
+     */
+    public int getLengthU() {
+        return U16.f(length);
+    }
+
+    /**
+     * Set the length of this message
+     *
+     * @param length
+     */
+    public OFMessage setLength(short length) {
+        this.length = length;
+        return this;
+    }
+
+    /**
+     * Set the length of this message, unsigned
+     *
+     * @param length
+     */
+    public OFMessage setLengthU(int length) {
+        this.length = U16.t(length);
+        return this;
+    }
+
+    /**
+     * Get the type of this message
+     *
+     * @return
+     */
+    public OFType getType() {
+        return type;
+    }
+
+    /**
+     * Set the type of this message
+     *
+     * @param type
+     */
+    public void setType(OFType type) {
+        this.type = type;
+    }
+
+    /**
+     * Get the OpenFlow version of this message
+     *
+     * @return
+     */
+    public byte getVersion() {
+        return version;
+    }
+
+    /**
+     * Set the OpenFlow version of this message
+     *
+     * @param version
+     */
+    public void setVersion(byte version) {
+        this.version = version;
+    }
+
+    /**
+     * Get the transaction id of this message
+     *
+     * @return
+     */
+    public int getXid() {
+        return xid;
+    }
+
+    /**
+     * Set the transaction id of this message
+     *
+     * @param xid
+     */
+    public void setXid(int xid) {
+        this.xid = xid;
+    }
+
+    /**
+     * Read this message off the wire from the specified ByteBuffer
+     * @param data
+     */
+    public void readFrom(ByteBuffer data) {
+        this.version = data.get();
+        this.type = OFType.valueOf(data.get());
+        this.length = data.getShort();
+        this.xid = data.getInt();
+    }
+
+    /**
+     * Write this message's binary format to the specified ByteBuffer
+     * @param data
+     */
+    public void writeTo(ByteBuffer data) {
+        data.put(version);
+        data.put(type.getTypeValue());
+        data.putShort(length);
+        data.putInt(xid);
+    }
+
+    /**
+     * Returns a summary of the message
+     * @return "ofmsg=v=$version;t=$type:l=$len:xid=$xid"
+     */
+    public String toString() {
+        return "ofmsg" +
+            ":v=" + U8.f(this.getVersion()) +
+            ";t=" + this.getType() +
+            ";l=" + this.getLengthU() +
+            ";x=" + U32.f(this.getXid());
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 97;
+        int result = 1;
+        result = prime * result + length;
+        result = prime * result + ((type == null) ? 0 : type.hashCode());
+        result = prime * result + version;
+        result = prime * result + xid;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFMessage)) {
+            return false;
+        }
+        OFMessage other = (OFMessage) obj;
+        if (length != other.length) {
+            return false;
+        }
+        if (type == null) {
+            if (other.type != null) {
+                return false;
+            }
+        } else if (!type.equals(other.type)) {
+            return false;
+        }
+        if (version != other.version) {
+            return false;
+        }
+        if (xid != other.xid) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFPacketIn.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFPacketIn.java
new file mode 100644 (file)
index 0000000..927b7bf
--- /dev/null
@@ -0,0 +1,187 @@
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import org.openflow.util.U16;
+import org.openflow.util.U8;
+
+/**
+ * Represents an ofp_packet_in
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Feb 8, 2010
+ */
+public class OFPacketIn extends OFMessage {
+    public static int MINIMUM_LENGTH = 18;
+
+    public enum OFPacketInReason {
+        NO_MATCH, ACTION
+    }
+
+    protected int bufferId;
+    protected short totalLength;
+    protected short inPort;
+    protected OFPacketInReason reason;
+    protected byte[] packetData;
+
+    public OFPacketIn() {
+        super();
+        this.type = OFType.PACKET_IN;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+
+    /**
+     * Get buffer_id
+     * @return
+     */
+    public int getBufferId() {
+        return this.bufferId;
+    }
+
+    /**
+     * Set buffer_id
+     * @param bufferId
+     */
+    public OFPacketIn setBufferId(int bufferId) {
+        this.bufferId = bufferId;
+        return this;
+    }
+
+    /**
+     * Returns the packet data
+     * @return
+     */
+    public byte[] getPacketData() {
+        return this.packetData;
+    }
+
+    /**
+     * Sets the packet data, and updates the length of this message
+     * @param packetData
+     */
+    public OFPacketIn setPacketData(byte[] packetData) {
+        this.packetData = packetData;
+        this.length = U16.t(OFPacketIn.MINIMUM_LENGTH + packetData.length);
+        return this;
+    }
+
+    /**
+     * Get in_port
+     * @return
+     */
+    public short getInPort() {
+        return this.inPort;
+    }
+
+    /**
+     * Set in_port
+     * @param inPort
+     */
+    public OFPacketIn setInPort(short inPort) {
+        this.inPort = inPort;
+        return this;
+    }
+
+    /**
+     * Get reason
+     * @return
+     */
+    public OFPacketInReason getReason() {
+        return this.reason;
+    }
+
+    /**
+     * Set reason
+     * @param reason
+     */
+    public OFPacketIn setReason(OFPacketInReason reason) {
+        this.reason = reason;
+        return this;
+    }
+
+    /**
+     * Get total_len
+     * @return
+     */
+    public short getTotalLength() {
+        return this.totalLength;
+    }
+
+    /**
+     * Set total_len
+     * @param totalLength
+     */
+    public OFPacketIn setTotalLength(short totalLength) {
+        this.totalLength = totalLength;
+        return this;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.bufferId = data.getInt();
+        this.totalLength = data.getShort();
+        this.inPort = data.getShort();
+        this.reason = OFPacketInReason.values()[U8.f(data.get())];
+        data.get(); // pad
+        this.packetData = new byte[getLengthU() - MINIMUM_LENGTH];
+        data.get(this.packetData);
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putInt(bufferId);
+        data.putShort(totalLength);
+        data.putShort(inPort);
+        data.put((byte) reason.ordinal());
+        data.put((byte) 0x0); // pad
+        data.put(this.packetData);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 283;
+        int result = super.hashCode();
+        result = prime * result + bufferId;
+        result = prime * result + inPort;
+        result = prime * result + Arrays.hashCode(packetData);
+        result = prime * result + ((reason == null) ? 0 : reason.hashCode());
+        result = prime * result + totalLength;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFPacketIn)) {
+            return false;
+        }
+        OFPacketIn other = (OFPacketIn) obj;
+        if (bufferId != other.bufferId) {
+            return false;
+        }
+        if (inPort != other.inPort) {
+            return false;
+        }
+        if (!Arrays.equals(packetData, other.packetData)) {
+            return false;
+        }
+        if (reason == null) {
+            if (other.reason != null) {
+                return false;
+            }
+        } else if (!reason.equals(other.reason)) {
+            return false;
+        }
+        if (totalLength != other.totalLength) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFPacketOut.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFPacketOut.java
new file mode 100644 (file)
index 0000000..7eded8d
--- /dev/null
@@ -0,0 +1,223 @@
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
+
+import org.openflow.protocol.action.OFAction;
+import org.openflow.protocol.factory.OFActionFactory;
+import org.openflow.protocol.factory.OFActionFactoryAware;
+import org.openflow.util.U16;
+
+/**
+ * Represents an ofp_packet_out message
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 12, 2010
+ */
+public class OFPacketOut extends OFMessage implements OFActionFactoryAware {
+    public static int MINIMUM_LENGTH = 16;
+    public static int BUFFER_ID_NONE = 0xffffffff;
+
+    protected OFActionFactory actionFactory;
+    protected int bufferId;
+    protected short inPort;
+    protected short actionsLength;
+    protected List<OFAction> actions;
+    protected byte[] packetData;
+
+    public OFPacketOut() {
+        super();
+        this.type = OFType.PACKET_OUT;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+
+    /**
+     * Get buffer_id
+     * @return
+     */
+    public int getBufferId() {
+        return this.bufferId;
+    }
+
+    /**
+     * Set buffer_id
+     * @param bufferId
+     */
+    public OFPacketOut setBufferId(int bufferId) {
+        this.bufferId = bufferId;
+        return this;
+    }
+
+    /**
+     * Returns the packet data
+     * @return
+     */
+    public byte[] getPacketData() {
+        return this.packetData;
+    }
+
+    /**
+     * Sets the packet data
+     * @param packetData
+     */
+    public OFPacketOut setPacketData(byte[] packetData) {
+        this.packetData = packetData;
+        return this;
+    }
+
+    /**
+     * Get in_port
+     * @return
+     */
+    public short getInPort() {
+        return this.inPort;
+    }
+
+    /**
+     * Set in_port
+     * @param inPort
+     */
+    public OFPacketOut setInPort(short inPort) {
+        this.inPort = inPort;
+        return this;
+    }
+
+    /**
+     * Set in_port. Convenience method using OFPort enum.
+     * @param inPort
+     */
+    public OFPacketOut setInPort(OFPort inPort) {
+        this.inPort = inPort.getValue();
+        return this;
+    }
+
+    /**
+     * Get actions_len
+     * @return
+     */
+    public short getActionsLength() {
+        return this.actionsLength;
+    }
+
+    /**
+     * Get actions_len, unsigned
+     * @return
+     */
+    public int getActionsLengthU() {
+        return U16.f(this.actionsLength);
+    }
+
+    /**
+     * Set actions_len
+     * @param actionsLength
+     */
+    public OFPacketOut setActionsLength(short actionsLength) {
+        this.actionsLength = actionsLength;
+        return this;
+    }
+
+    /**
+     * Returns the actions contained in this message
+     * @return a list of ordered OFAction objects
+     */
+    public List<OFAction> getActions() {
+        return this.actions;
+    }
+
+    /**
+     * Sets the list of actions on this message
+     * @param actions a list of ordered OFAction objects
+     */
+    public OFPacketOut setActions(List<OFAction> actions) {
+        this.actions = actions;
+        return this;
+    }
+
+    @Override
+    public void setActionFactory(OFActionFactory actionFactory) {
+        this.actionFactory = actionFactory;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.bufferId = data.getInt();
+        this.inPort = data.getShort();
+        this.actionsLength = data.getShort();
+        if ( this.actionFactory == null)
+            throw new RuntimeException("ActionFactory not set");
+        this.actions = this.actionFactory.parseActions(data, getActionsLengthU());
+        this.packetData = new byte[getLengthU() - MINIMUM_LENGTH - getActionsLengthU()];
+        data.get(this.packetData);
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putInt(bufferId);
+        data.putShort(inPort);
+        data.putShort(actionsLength);
+        for (OFAction action : actions) {
+            action.writeTo(data);
+        }
+        if (this.packetData != null)
+            data.put(this.packetData);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 293;
+        int result = super.hashCode();
+        result = prime * result + ((actions == null) ? 0 : actions.hashCode());
+        result = prime * result + actionsLength;
+        result = prime * result + bufferId;
+        result = prime * result + inPort;
+        result = prime * result + Arrays.hashCode(packetData);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFPacketOut)) {
+            return false;
+        }
+        OFPacketOut other = (OFPacketOut) obj;
+        if (actions == null) {
+            if (other.actions != null) {
+                return false;
+            }
+        } else if (!actions.equals(other.actions)) {
+            return false;
+        }
+        if (actionsLength != other.actionsLength) {
+            return false;
+        }
+        if (bufferId != other.bufferId) {
+            return false;
+        }
+        if (inPort != other.inPort) {
+            return false;
+        }
+        if (!Arrays.equals(packetData, other.packetData)) {
+            return false;
+        }
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "OFPacketOut [actionFactory=" + actionFactory + ", actions="
+                + actions + ", actionsLength=" + actionsLength + ", bufferId=0x"
+                + Integer.toHexString(bufferId) + ", inPort=" + inPort + ", packetData="
+                + Arrays.toString(packetData) + "]";
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFPhysicalPort.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFPhysicalPort.java
new file mode 100644 (file)
index 0000000..b3dfd34
--- /dev/null
@@ -0,0 +1,365 @@
+package org.openflow.protocol;
+
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.HashMap;
+
+
+
+/**
+ * Represents ofp_phy_port
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 25, 2010
+ */
+public class OFPhysicalPort implements Cloneable, Serializable {
+    public static int MINIMUM_LENGTH = 48;
+    public static int OFP_ETH_ALEN = 6;
+
+    public enum OFPortConfig {
+        OFPPC_PORT_DOWN    (1 << 0),
+        OFPPC_NO_STP       (1 << 1),
+        OFPPC_NO_RECV      (1 << 2),
+        OFPPC_NO_RECV_STP  (1 << 3),
+        OFPPC_NO_FLOOD     (1 << 4),
+        OFPPC_NO_FWD       (1 << 5),
+        OFPPC_NO_PACKET_IN (1 << 6);
+
+        protected int value;
+
+        private OFPortConfig(int value) {
+            this.value = value;
+        }
+
+        /**
+         * @return the value
+         */
+        public int getValue() {
+            return value;
+        }
+    }
+
+    public enum OFPortState {
+        OFPPS_LINK_DOWN   (1 << 0),
+        OFPPS_STP_LISTEN  (0 << 8),
+        OFPPS_STP_LEARN   (1 << 8),
+        OFPPS_STP_FORWARD (2 << 8),
+        OFPPS_STP_BLOCK   (3 << 8),
+        OFPPS_STP_MASK    (3 << 8);
+
+        protected int value;
+
+        private OFPortState(int value) {
+            this.value = value;
+        }
+
+        /**
+         * @return the value
+         */
+        public int getValue() {
+            return value;
+        }
+    }
+
+    public enum OFPortFeatures {
+        OFPPF_10MB_HD    (1 << 0),
+        OFPPF_10MB_FD    (1 << 1),
+        OFPPF_100MB_HD   (1 << 2),
+        OFPPF_100MB_FD   (1 << 3),
+        OFPPF_1GB_HD     (1 << 4),
+        OFPPF_1GB_FD     (1 << 5),
+        OFPPF_10GB_FD    (1 << 6),
+        OFPPF_COPPER     (1 << 7),
+        OFPPF_FIBER      (1 << 8),
+        OFPPF_AUTONEG    (1 << 9),
+        OFPPF_PAUSE      (1 << 10),
+        OFPPF_PAUSE_ASYM (1 << 11);
+
+        protected int value;
+
+        private OFPortFeatures(int value) {
+            this.value = value;
+        }
+
+        /**
+         * @return the value
+         */
+        public int getValue() {
+            return value;
+        }
+    }
+
+    protected short portNumber;
+    protected byte[] hardwareAddress;
+    protected String name;
+    protected int config;
+    protected int state;
+    protected int currentFeatures;
+    protected int advertisedFeatures;
+    protected int supportedFeatures;
+    protected int peerFeatures;
+
+    /**
+     * @return the portNumber
+     */
+    public short getPortNumber() {
+        return portNumber;
+    }
+
+    /**
+     * @param portNumber the portNumber to set
+     */
+    public void setPortNumber(short portNumber) {
+        this.portNumber = portNumber;
+    }
+
+    /**
+     * @return the hardwareAddress
+     */
+    public byte[] getHardwareAddress() {
+        return hardwareAddress;
+    }
+
+    /**
+     * @param hardwareAddress the hardwareAddress to set
+     */
+    public void setHardwareAddress(byte[] hardwareAddress) {
+        if (hardwareAddress.length != OFP_ETH_ALEN)
+            throw new RuntimeException("Hardware address must have length "
+                    + OFP_ETH_ALEN);
+        this.hardwareAddress = hardwareAddress;
+    }
+
+    /**
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name the name to set
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return the config
+     */
+    public int getConfig() {
+        return config;
+    }
+
+    /**
+     * @param config the config to set
+     */
+    public void setConfig(int config) {
+        this.config = config;
+    }
+
+    /**
+     * @return the state
+     */
+    public int getState() {
+        return state;
+    }
+
+    /**
+     * @param state the state to set
+     */
+    public void setState(int state) {
+        this.state = state;
+    }
+
+    /**
+     * @return the currentFeatures
+     */
+    public int getCurrentFeatures() {
+        return currentFeatures;
+    }
+
+    /**
+     * @param currentFeatures the currentFeatures to set
+     */
+    public void setCurrentFeatures(int currentFeatures) {
+        this.currentFeatures = currentFeatures;
+    }
+
+    /**
+     * @return the advertisedFeatures
+     */
+    public int getAdvertisedFeatures() {
+        return advertisedFeatures;
+    }
+
+    /**
+     * @param advertisedFeatures the advertisedFeatures to set
+     */
+    public void setAdvertisedFeatures(int advertisedFeatures) {
+        this.advertisedFeatures = advertisedFeatures;
+    }
+
+    /**
+     * @return the supportedFeatures
+     */
+    public int getSupportedFeatures() {
+        return supportedFeatures;
+    }
+
+    /**
+     * @param supportedFeatures the supportedFeatures to set
+     */
+    public void setSupportedFeatures(int supportedFeatures) {
+        this.supportedFeatures = supportedFeatures;
+    }
+
+    /**
+     * @return the peerFeatures
+     */
+    public int getPeerFeatures() {
+        return peerFeatures;
+    }
+
+    /**
+     * @param peerFeatures the peerFeatures to set
+     */
+    public void setPeerFeatures(int peerFeatures) {
+        this.peerFeatures = peerFeatures;
+    }
+
+    /**
+     * Read this message off the wire from the specified ByteBuffer
+     * @param data
+     */
+    public void readFrom(ByteBuffer data) {
+        this.portNumber = data.getShort();
+        if (this.hardwareAddress == null)
+            this.hardwareAddress = new byte[OFP_ETH_ALEN];
+        data.get(this.hardwareAddress);
+        byte[] name = new byte[16];
+        data.get(name);
+        // find the first index of 0
+        int index = 0;
+        for (byte b : name) {
+            if (0 == b)
+                break;
+            ++index;
+        }
+        this.name = new String(Arrays.copyOf(name, index),
+                Charset.forName("ascii"));
+        this.config = data.getInt();
+        this.state = data.getInt();
+        this.currentFeatures = data.getInt();
+        this.advertisedFeatures = data.getInt();
+        this.supportedFeatures = data.getInt();
+        this.peerFeatures = data.getInt();
+    }
+
+    /**
+     * Write this message's binary format to the specified ByteBuffer
+     * @param data
+     */
+    public void writeTo(ByteBuffer data) {
+        data.putShort(this.portNumber);
+        data.put(hardwareAddress);
+        try {
+            byte[] name = this.name.getBytes("ASCII");
+            if (name.length < 16) {
+                data.put(name);
+                for (int i = name.length; i < 16; ++i) {
+                    data.put((byte) 0);
+                }
+            } else {
+                data.put(name, 0, 15);
+                data.put((byte) 0);
+            }
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+        data.putInt(this.config);
+        data.putInt(this.state);
+        data.putInt(this.currentFeatures);
+        data.putInt(this.advertisedFeatures);
+        data.putInt(this.supportedFeatures);
+        data.putInt(this.peerFeatures);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 307;
+        int result = 1;
+        result = prime * result + advertisedFeatures;
+        result = prime * result + config;
+        result = prime * result + currentFeatures;
+        result = prime * result + Arrays.hashCode(hardwareAddress);
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + peerFeatures;
+        result = prime * result + portNumber;
+        result = prime * result + state;
+        result = prime * result + supportedFeatures;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFPhysicalPort)) {
+            return false;
+        }
+        OFPhysicalPort other = (OFPhysicalPort) obj;
+        if (advertisedFeatures != other.advertisedFeatures) {
+            return false;
+        }
+        if (config != other.config) {
+            return false;
+        }
+        if (currentFeatures != other.currentFeatures) {
+            return false;
+        }
+        if (!Arrays.equals(hardwareAddress, other.hardwareAddress)) {
+            return false;
+        }
+        if (name == null) {
+            if (other.name != null) {
+                return false;
+            }
+        } else if (!name.equals(other.name)) {
+            return false;
+        }
+        if (peerFeatures != other.peerFeatures) {
+            return false;
+        }
+        if (portNumber != other.portNumber) {
+            return false;
+        }
+        if (state != other.state) {
+            return false;
+        }
+        if (supportedFeatures != other.supportedFeatures) {
+            return false;
+        }
+        return true;
+    }
+    
+    public OFPhysicalPort cloneOFPhysicalPort() {
+        OFPhysicalPort p;
+        try
+        {
+            p = (OFPhysicalPort) this.clone();
+            
+        }
+        catch (CloneNotSupportedException e)
+        {
+            throw new AssertionError();
+        }
+        return p;
+    }
+    
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFPort.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFPort.java
new file mode 100644 (file)
index 0000000..fd07f24
--- /dev/null
@@ -0,0 +1,26 @@
+package org.openflow.protocol;
+
+public enum OFPort {
+    OFPP_MAX                ((short)0xff00),
+    OFPP_IN_PORT            ((short)0xfff8),
+    OFPP_TABLE              ((short)0xfff9),
+    OFPP_NORMAL             ((short)0xfffa),
+    OFPP_FLOOD              ((short)0xfffb),
+    OFPP_ALL                ((short)0xfffc),
+    OFPP_CONTROLLER         ((short)0xfffd),
+    OFPP_LOCAL              ((short)0xfffe),
+    OFPP_NONE               ((short)0xffff);
+
+    protected short value;
+
+    private OFPort(short value) {
+        this.value = value;
+    }
+
+    /**
+     * @return the value
+     */
+    public short getValue() {
+        return value;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFPortMod.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFPortMod.java
new file mode 100644 (file)
index 0000000..82b5de6
--- /dev/null
@@ -0,0 +1,165 @@
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import org.openflow.util.U16;
+
+/**
+ * Represents an ofp_port_mod message
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFPortMod extends OFMessage {
+    public static int MINIMUM_LENGTH = 32;
+
+    protected short portNumber;
+    protected byte[] hardwareAddress;
+    protected int config;
+    protected int mask;
+    protected int advertise;
+
+    public OFPortMod() {
+        super();
+        this.type = OFType.PORT_MOD;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+
+    /**
+     * @return the portNumber
+     */
+    public short getPortNumber() {
+        return portNumber;
+    }
+
+    /**
+     * @param portNumber the portNumber to set
+     */
+    public void setPortNumber(short portNumber) {
+        this.portNumber = portNumber;
+    }
+
+    /**
+     * @return the hardwareAddress
+     */
+    public byte[] getHardwareAddress() {
+        return hardwareAddress;
+    }
+
+    /**
+     * @param hardwareAddress the hardwareAddress to set
+     */
+    public void setHardwareAddress(byte[] hardwareAddress) {
+        if (hardwareAddress.length != OFPhysicalPort.OFP_ETH_ALEN)
+            throw new RuntimeException("Hardware address must have length "
+                    + OFPhysicalPort.OFP_ETH_ALEN);
+        this.hardwareAddress = hardwareAddress;
+    }
+
+    /**
+     * @return the config
+     */
+    public int getConfig() {
+        return config;
+    }
+
+    /**
+     * @param config the config to set
+     */
+    public void setConfig(int config) {
+        this.config = config;
+    }
+
+    /**
+     * @return the mask
+     */
+    public int getMask() {
+        return mask;
+    }
+
+    /**
+     * @param mask the mask to set
+     */
+    public void setMask(int mask) {
+        this.mask = mask;
+    }
+
+    /**
+     * @return the advertise
+     */
+    public int getAdvertise() {
+        return advertise;
+    }
+
+    /**
+     * @param advertise the advertise to set
+     */
+    public void setAdvertise(int advertise) {
+        this.advertise = advertise;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.portNumber = data.getShort();
+        if (this.hardwareAddress == null)
+            this.hardwareAddress = new byte[OFPhysicalPort.OFP_ETH_ALEN];
+        data.get(this.hardwareAddress);
+        this.config = data.getInt();
+        this.mask = data.getInt();
+        this.advertise = data.getInt();
+        data.getInt(); // pad
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putShort(this.portNumber);
+        data.put(this.hardwareAddress);
+        data.putInt(this.config);
+        data.putInt(this.mask);
+        data.putInt(this.advertise);
+        data.putInt(0); // pad
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 311;
+        int result = super.hashCode();
+        result = prime * result + advertise;
+        result = prime * result + config;
+        result = prime * result + Arrays.hashCode(hardwareAddress);
+        result = prime * result + mask;
+        result = prime * result + portNumber;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFPortMod)) {
+            return false;
+        }
+        OFPortMod other = (OFPortMod) obj;
+        if (advertise != other.advertise) {
+            return false;
+        }
+        if (config != other.config) {
+            return false;
+        }
+        if (!Arrays.equals(hardwareAddress, other.hardwareAddress)) {
+            return false;
+        }
+        if (mask != other.mask) {
+            return false;
+        }
+        if (portNumber != other.portNumber) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFPortStatus.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFPortStatus.java
new file mode 100644 (file)
index 0000000..d70d6cb
--- /dev/null
@@ -0,0 +1,109 @@
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+
+import org.openflow.util.U16;
+
+/**
+ * Represents an ofp_port_status message
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFPortStatus extends OFMessage {
+    public static int MINIMUM_LENGTH = 64;
+
+    public enum OFPortReason {
+        OFPPR_ADD,
+        OFPPR_DELETE,
+        OFPPR_MODIFY
+    }
+
+    protected byte reason;
+    protected OFPhysicalPort desc;
+
+    /**
+     * @return the reason
+     */
+    public byte getReason() {
+        return reason;
+    }
+
+    /**
+     * @param reason the reason to set
+     */
+    public void setReason(byte reason) {
+        this.reason = reason;
+    }
+
+    /**
+     * @return the desc
+     */
+    public OFPhysicalPort getDesc() {
+        return desc;
+    }
+
+    /**
+     * @param desc the desc to set
+     */
+    public void setDesc(OFPhysicalPort desc) {
+        this.desc = desc;
+    }
+
+    public OFPortStatus() {
+        super();
+        this.type = OFType.PORT_STATUS;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.reason = data.get();
+        data.position(data.position() + 7); // skip 7 bytes of padding
+        if (this.desc == null)
+            this.desc = new OFPhysicalPort();
+        this.desc.readFrom(data);
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.put(this.reason);
+        for (int i = 0; i < 7; ++i)
+            data.put((byte) 0);
+        this.desc.writeTo(data);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 313;
+        int result = super.hashCode();
+        result = prime * result + ((desc == null) ? 0 : desc.hashCode());
+        result = prime * result + reason;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFPortStatus)) {
+            return false;
+        }
+        OFPortStatus other = (OFPortStatus) obj;
+        if (desc == null) {
+            if (other.desc != null) {
+                return false;
+            }
+        } else if (!desc.equals(other.desc)) {
+            return false;
+        }
+        if (reason != other.reason) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFQueueConfigReply.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFQueueConfigReply.java
new file mode 100644 (file)
index 0000000..2dc52fb
--- /dev/null
@@ -0,0 +1,150 @@
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openflow.util.U16;
+import org.openflow.protocol.factory.OFQueuePropertyFactory;
+import org.openflow.protocol.factory.OFQueuePropertyFactoryAware;
+import org.openflow.protocol.queue.OFPacketQueue;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFQueueConfigReply extends OFMessage implements Cloneable, OFQueuePropertyFactoryAware {
+    public static int MINIMUM_LENGTH = 16;
+
+    protected OFQueuePropertyFactory queuePropertyFactory;
+
+    protected short port;
+    protected List<OFPacketQueue> queues;
+
+    /**
+     * 
+     */
+    public OFQueueConfigReply() {
+        super();
+        this.type = OFType.QUEUE_CONFIG_REPLY;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+
+    /**
+     * @return the port
+     */
+    public short getPort() {
+        return port;
+    }
+
+    /**
+     * @param port the port to set
+     */
+    public OFQueueConfigReply setPort(short port) {
+        this.port = port;
+        return this;
+    }
+
+    /**
+     * @return the queues
+     */
+    public List<OFPacketQueue> getQueues() {
+        return queues;
+    }
+
+    /**
+     * @param queues the queues to set
+     */
+    public void setQueues(List<OFPacketQueue> queues) {
+        this.queues = queues;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.port = data.getShort();
+        data.getShort(); // pad
+        data.getInt(); // pad
+        int remaining = this.getLengthU() - MINIMUM_LENGTH;
+        if (data.remaining() < remaining)
+            remaining = data.remaining();
+        this.queues = new ArrayList<OFPacketQueue>();
+        while (remaining >= OFPacketQueue.MINIMUM_LENGTH) {
+            OFPacketQueue queue = new OFPacketQueue();
+            queue.setQueuePropertyFactory(this.queuePropertyFactory);
+            queue.readFrom(data);
+            remaining -= U16.f(queue.getLength());
+            this.queues.add(queue);
+        }
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putShort(this.port);
+        data.putShort((short) 0); // pad
+        data.putInt(0); // pad
+        if (this.queues != null) {
+            for (OFPacketQueue queue : this.queues) {
+                queue.writeTo(data);
+            }
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 4549;
+        int result = super.hashCode();
+        result = prime * result + port;
+        result = prime * result + ((queues == null) ? 0 : queues.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!super.equals(obj))
+            return false;
+        if (!(obj instanceof OFQueueConfigReply))
+            return false;
+        OFQueueConfigReply other = (OFQueueConfigReply) obj;
+        if (port != other.port)
+            return false;
+        if (queues == null) {
+            if (other.queues != null)
+                return false;
+        } else if (!queues.equals(other.queues))
+            return false;
+        return true;
+    }
+
+    @Override
+    public void setQueuePropertyFactory(
+            OFQueuePropertyFactory queuePropertyFactory) {
+        this.queuePropertyFactory = queuePropertyFactory;
+    }
+
+    @Override
+    public OFQueueConfigReply clone() {
+        try {
+            OFQueueConfigReply clone = (OFQueueConfigReply) super.clone();
+            if (this.queues != null) {
+                List<OFPacketQueue> queues = new ArrayList<OFPacketQueue>();
+                for (OFPacketQueue queue : this.queues) {
+                    queues.add(queue.clone());
+                }
+                clone.setQueues(queues);
+            }
+            return clone;
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "OFQueueConfigReply [port=" + U16.f(port) + ", queues=" + queues
+                + ", xid=" + xid + "]";
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFQueueConfigRequest.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFQueueConfigRequest.java
new file mode 100644 (file)
index 0000000..dcd8f2e
--- /dev/null
@@ -0,0 +1,84 @@
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+
+import org.openflow.util.U16;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFQueueConfigRequest extends OFMessage implements Cloneable {
+    public static int MINIMUM_LENGTH = 12;
+
+    protected short port;
+
+    /**
+     * 
+     */
+    public OFQueueConfigRequest() {
+        super();
+        this.type = OFType.QUEUE_CONFIG_REQUEST;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+
+    /**
+     * @return the port
+     */
+    public short getPort() {
+        return port;
+    }
+
+    /**
+     * @param port the port to set
+     */
+    public void setPort(short port) {
+        this.port = port;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.port = data.getShort();
+        data.get(); // pad
+        data.get(); // pad
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putShort(this.port);
+        data.putShort((short) 0); // pad
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 7211;
+        int result = super.hashCode();
+        result = prime * result + port;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!super.equals(obj))
+            return false;
+        if (!(obj instanceof OFQueueConfigRequest))
+            return false;
+        OFQueueConfigRequest other = (OFQueueConfigRequest) obj;
+        if (port != other.port)
+            return false;
+        return true;
+    }
+
+    @Override
+    public OFQueueConfigRequest clone() {
+        try {
+            return (OFQueueConfigRequest) super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFSetConfig.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFSetConfig.java
new file mode 100644 (file)
index 0000000..0a6709d
--- /dev/null
@@ -0,0 +1,12 @@
+package org.openflow.protocol;
+
+/**
+ * Represents an OFPT_SET_CONFIG type message
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFSetConfig extends OFSwitchConfig {
+    public OFSetConfig() {
+        super();
+        this.type = OFType.SET_CONFIG;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFStatisticsMessageBase.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFStatisticsMessageBase.java
new file mode 100644 (file)
index 0000000..0014bcf
--- /dev/null
@@ -0,0 +1,140 @@
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.openflow.protocol.factory.OFStatisticsFactory;
+import org.openflow.protocol.factory.OFStatisticsFactoryAware;
+import org.openflow.protocol.statistics.OFStatistics;
+import org.openflow.protocol.statistics.OFStatisticsType;
+
+
+/**
+ * Base class for statistics requests/replies
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 27, 2010
+ */
+public abstract class OFStatisticsMessageBase extends OFMessage implements
+        OFStatisticsFactoryAware {
+    public static int MINIMUM_LENGTH = 12;
+
+    protected OFStatisticsFactory statisticsFactory;
+    protected OFStatisticsType statisticType;
+    protected short flags;
+    protected List<OFStatistics> statistics;
+
+    /**
+     * @return the statisticType
+     */
+    public OFStatisticsType getStatisticType() {
+        return statisticType;
+    }
+
+    /**
+     * @param statisticType the statisticType to set
+     */
+    public void setStatisticType(OFStatisticsType statisticType) {
+        this.statisticType = statisticType;
+    }
+
+    /**
+     * @return the flags
+     */
+    public short getFlags() {
+        return flags;
+    }
+
+    /**
+     * @param flags the flags to set
+     */
+    public void setFlags(short flags) {
+        this.flags = flags;
+    }
+
+    /**
+     * @return the statistics
+     */
+    public List<OFStatistics> getStatistics() {
+        return statistics;
+    }
+
+    /**
+     * @param statistics the statistics to set
+     */
+    public void setStatistics(List<OFStatistics> statistics) {
+        this.statistics = statistics;
+    }
+
+    @Override
+    public void setStatisticsFactory(OFStatisticsFactory statisticsFactory) {
+        this.statisticsFactory = statisticsFactory;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.statisticType = OFStatisticsType.valueOf(data.getShort(), this
+                .getType());
+        this.flags = data.getShort();
+        if (this.statisticsFactory == null)
+            throw new RuntimeException("OFStatisticsFactory not set");
+        this.statistics = statisticsFactory.parseStatistics(this.getType(),
+                this.statisticType, data, super.getLengthU() - MINIMUM_LENGTH);
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putShort(this.statisticType.getTypeValue());
+        data.putShort(this.flags);
+        if (this.statistics != null) {
+            for (OFStatistics statistic : this.statistics) {
+                statistic.writeTo(data);
+            }
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 317;
+        int result = super.hashCode();
+        result = prime * result + flags;
+        result = prime * result
+                + ((statisticType == null) ? 0 : statisticType.hashCode());
+        result = prime * result
+                + ((statistics == null) ? 0 : statistics.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFStatisticsMessageBase)) {
+            return false;
+        }
+        OFStatisticsMessageBase other = (OFStatisticsMessageBase) obj;
+        if (flags != other.flags) {
+            return false;
+        }
+        if (statisticType == null) {
+            if (other.statisticType != null) {
+                return false;
+            }
+        } else if (!statisticType.equals(other.statisticType)) {
+            return false;
+        }
+        if (statistics == null) {
+            if (other.statistics != null) {
+                return false;
+            }
+        } else if (!statistics.equals(other.statistics)) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFStatisticsReply.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFStatisticsReply.java
new file mode 100644 (file)
index 0000000..e5f705c
--- /dev/null
@@ -0,0 +1,29 @@
+package org.openflow.protocol;
+
+import org.openflow.util.U16;
+
+/**
+ * Represents an ofp_stats_reply message
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFStatisticsReply extends OFStatisticsMessageBase {
+    public enum OFStatisticsReplyFlags {
+        REPLY_MORE      (1 << 0);
+
+        protected short type;
+
+        OFStatisticsReplyFlags(int type) {
+            this.type = (short) type;
+        }
+
+        public short getTypeValue() {
+            return type;
+        }
+    }
+
+    public OFStatisticsReply() {
+        super();
+        this.type = OFType.STATS_REPLY;
+        this.length = U16.t(OFStatisticsMessageBase.MINIMUM_LENGTH);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFStatisticsRequest.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFStatisticsRequest.java
new file mode 100644 (file)
index 0000000..94a28ad
--- /dev/null
@@ -0,0 +1,15 @@
+package org.openflow.protocol;
+
+import org.openflow.util.U16;
+
+/**
+ * Represents an ofp_stats_request message
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFStatisticsRequest extends OFStatisticsMessageBase {
+    public OFStatisticsRequest() {
+        super();
+        this.type = OFType.STATS_REQUEST;
+        this.length = U16.t(OFStatisticsMessageBase.MINIMUM_LENGTH);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFSwitchConfig.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFSwitchConfig.java
new file mode 100644 (file)
index 0000000..16e66d6
--- /dev/null
@@ -0,0 +1,100 @@
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Base class representing ofp_switch_config based messages
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public abstract class OFSwitchConfig extends OFMessage {
+    public static int MINIMUM_LENGTH = 12;
+
+    public enum OFConfigFlags {
+        OFPC_FRAG_NORMAL,
+        OFPC_FRAG_DROP,
+        OFPC_FRAG_REASM,
+        OFPC_FRAG_MASK
+    }
+
+    protected short flags;
+    protected short missSendLength;
+
+    public OFSwitchConfig() {
+        super();
+        super.setLengthU(MINIMUM_LENGTH);
+    }
+
+    /**
+     * @return the flags
+     */
+    public short getFlags() {
+        return flags;
+    }
+
+    /**
+     * @param flags the flags to set
+     */
+    public OFSwitchConfig setFlags(short flags) {
+        this.flags = flags;
+        return this;
+    }
+
+    /**
+     * @return the missSendLength
+     */
+    public short getMissSendLength() {
+        return missSendLength;
+    }
+
+    /**
+     * @param missSendLength the missSendLength to set
+     */
+    public OFSwitchConfig setMissSendLength(short missSendLength) {
+        this.missSendLength = missSendLength;
+        return this;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.flags = data.getShort();
+        this.missSendLength = data.getShort();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putShort(this.flags);
+        data.putShort(this.missSendLength);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 331;
+        int result = super.hashCode();
+        result = prime * result + flags;
+        result = prime * result + missSendLength;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFSwitchConfig)) {
+            return false;
+        }
+        OFSwitchConfig other = (OFSwitchConfig) obj;
+        if (flags != other.flags) {
+            return false;
+        }
+        if (missSendLength != other.missSendLength) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFType.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFType.java
new file mode 100644 (file)
index 0000000..92a2e86
--- /dev/null
@@ -0,0 +1,232 @@
+package org.openflow.protocol;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * List of OpenFlow types and mappings to wire protocol value and derived
+ * classes
+ *
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ *
+ */
+public enum OFType {
+    HELLO               (0, OFHello.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFHello();
+                            }}),
+    ERROR               (1, OFError.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFError();
+                            }}),
+    ECHO_REQUEST        (2, OFEchoRequest.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFEchoRequest();
+                            }}),
+    ECHO_REPLY          (3, OFEchoReply.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFEchoReply();
+                            }}),
+    VENDOR              (4, OFVendor.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFVendor();
+                            }}),
+    FEATURES_REQUEST    (5, OFFeaturesRequest.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFFeaturesRequest();
+                            }}),
+    FEATURES_REPLY      (6, OFFeaturesReply.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFFeaturesReply();
+                            }}),
+    GET_CONFIG_REQUEST  (7, OFGetConfigRequest.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFGetConfigRequest();
+                            }}),
+    GET_CONFIG_REPLY    (8, OFGetConfigReply.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFGetConfigReply();
+                            }}),
+    SET_CONFIG          (9, OFSetConfig.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFSetConfig();
+                            }}),
+    PACKET_IN           (10, OFPacketIn.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFPacketIn();
+                            }}),
+    FLOW_REMOVED        (11, OFFlowRemoved.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFFlowRemoved();
+                            }}),
+    PORT_STATUS         (12, OFPortStatus.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFPortStatus();
+                            }}),
+    PACKET_OUT          (13, OFPacketOut.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFPacketOut();
+                            }}),
+    FLOW_MOD            (14, OFFlowMod.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFFlowMod();
+                            }}),
+    PORT_MOD            (15, OFPortMod.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFPortMod();
+                            }}),
+    STATS_REQUEST       (16, OFStatisticsRequest.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFStatisticsRequest();
+                            }}),
+    STATS_REPLY         (17, OFStatisticsReply.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFStatisticsReply();
+                            }}),
+    BARRIER_REQUEST     (18, OFBarrierRequest.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFBarrierRequest();
+                            }}),
+    BARRIER_REPLY       (19, OFBarrierReply.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFBarrierReply();
+                            }}),
+    QUEUE_CONFIG_REQUEST    (20, OFMessage.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFQueueConfigRequest();
+                            }}),
+    QUEUE_CONFIG_REPLY  (21, OFMessage.class, new Instantiable<OFMessage>() {
+                            @Override
+                            public OFMessage instantiate() {
+                                return new OFQueueConfigReply();
+                            }});
+
+    static OFType[] mapping;
+
+    protected Class<? extends OFMessage> clazz;
+    protected Constructor<? extends OFMessage> constructor;
+    protected Instantiable<OFMessage> instantiable;
+    protected byte type;
+
+    /**
+     * Store some information about the OpenFlow type, including wire protocol
+     * type number, length, and derived class
+     *
+     * @param type Wire protocol number associated with this OFType
+     * @param requestClass The Java class corresponding to this type of OpenFlow
+     *              message
+     * @param instantiator An Instantiator<OFMessage> implementation that creates an
+     *          instance of the specified OFMessage
+     */
+    OFType(int type, Class<? extends OFMessage> clazz, Instantiable<OFMessage> instantiator) {
+        this.type = (byte) type;
+        this.clazz = clazz;
+        this.instantiable = instantiator;
+        try {
+            this.constructor = clazz.getConstructor(new Class[]{});
+        } catch (Exception e) {
+            throw new RuntimeException(
+                    "Failure getting constructor for class: " + clazz, e);
+        }
+        OFType.addMapping(this.type, this);
+    }
+
+    /**
+     * Adds a mapping from type value to OFType enum
+     *
+     * @param i OpenFlow wire protocol type
+     * @param t type
+     */
+    static public void addMapping(byte i, OFType t) {
+        if (mapping == null)
+            mapping = new OFType[32];
+        OFType.mapping[i] = t;
+    }
+
+    /**
+     * Remove a mapping from type value to OFType enum
+     *
+     * @param i OpenFlow wire protocol type
+     */
+    static public void removeMapping(byte i) {
+        OFType.mapping[i] = null;
+    }
+
+    /**
+     * Given a wire protocol OpenFlow type number, return the OFType associated
+     * with it
+     *
+     * @param i wire protocol number
+     * @return OFType enum type
+     */
+
+    static public OFType valueOf(Byte i) {
+        return OFType.mapping[i];
+    }
+
+    /**
+     * @return Returns the wire protocol value corresponding to this OFType
+     */
+    public byte getTypeValue() {
+        return this.type;
+    }
+
+    /**
+     * @return return the OFMessage subclass corresponding to this OFType
+     */
+    public Class<? extends OFMessage> toClass() {
+        return clazz;
+    }
+
+    /**
+     * Returns the no-argument Constructor of the implementation class for
+     * this OFType
+     * @return the constructor
+     */
+    public Constructor<? extends OFMessage> getConstructor() {
+        return constructor;
+    }
+
+    /**
+     * Returns a new instance of the OFMessage represented by this OFType
+     * @return the new object
+     */
+    public OFMessage newInstance() {
+        return instantiable.instantiate();
+    }
+
+    /**
+     * @return the instantiable
+     */
+    public Instantiable<OFMessage> getInstantiable() {
+        return instantiable;
+    }
+
+    /**
+     * @param instantiable the instantiable to set
+     */
+    public void setInstantiable(Instantiable<OFMessage> instantiable) {
+        this.instantiable = instantiable;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/OFVendor.java b/third-party/openflowj/src/main/java/org/openflow/protocol/OFVendor.java
new file mode 100644 (file)
index 0000000..f372650
--- /dev/null
@@ -0,0 +1,100 @@
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import org.openflow.util.U16;
+
+/**
+ * Represents ofp_vendor_header
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFVendor extends OFMessage {
+    public static int MINIMUM_LENGTH = 12;
+
+    protected int vendor;
+    protected byte[] data;
+
+    public OFVendor() {
+        super();
+        this.type = OFType.VENDOR;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+
+    /**
+     * @return the vendor
+     */
+    public int getVendor() {
+        return vendor;
+    }
+
+    /**
+     * @param vendor the vendor to set
+     */
+    public void setVendor(int vendor) {
+        this.vendor = vendor;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.vendor = data.getInt();
+        if (this.length > MINIMUM_LENGTH) {
+            this.data = new byte[this.length - MINIMUM_LENGTH];
+            data.get(this.data);
+        }
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putInt(this.vendor);
+        if (this.data != null)
+            data.put(this.data);
+    }
+
+    /**
+     * @return the data
+     */
+    public byte[] getData() {
+        return data;
+    }
+
+    /**
+     * @param data the data to set
+     */
+    public void setData(byte[] data) {
+        this.data = data;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 337;
+        int result = super.hashCode();
+        result = prime * result + Arrays.hashCode(data);
+        result = prime * result + vendor;
+        return result;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!super.equals(obj))
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        OFVendor other = (OFVendor) obj;
+        if (!Arrays.equals(data, other.data))
+            return false;
+        if (vendor != other.vendor)
+            return false;
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/ActionVendorOutputNextHop.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/ActionVendorOutputNextHop.java
new file mode 100644 (file)
index 0000000..d5e5ab0
--- /dev/null
@@ -0,0 +1,192 @@
+package org.openflow.protocol.action;
+
+       import java.net.Inet4Address;
+       import java.net.InetAddress;
+       import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+
+import org.openflow.util.HexString;
+
+
+       public class ActionVendorOutputNextHop extends OFActionVendor {
+               private static final long serialVersionUID = 1L;
+               private static int VENDOR_CISCO = 0xC;
+               private enum ONHLength {
+                       ONH_LEN_MIN(16),
+                       ONH_LEN_P2P(16),
+                       ONH_LEN_IPV4(24),
+                       ONH_LEN_MAC(32),
+                       ONH_LEN_IPV6(40);
+               private int value;
+               private ONHLength(int value) {
+                       this.value = value;
+               }
+               public int getValue() {
+                       return this.value;
+               }
+               }       
+               private enum ONHActionType {
+                       ONH_ACTION_NONE(0),
+                       ONH_ACTION_OUTPUT_NH(1),
+                       ONH_ACTION_NETFLOW(2);
+               private int value;
+               private ONHActionType(int value) {
+                       this.value = value;
+               }
+               public int getValue() {
+                       return this.value;
+               }
+               }
+               private enum ONHAddressType {
+               ONH_ADDRTYPE_NONE(0),
+               ONH_ADDRTYPE_P2P(1),
+               ONH_ADDRTYPE_IPV4(2),
+               ONH_ADDRTYPE_IPV6(3),
+               ONH_ADDRTYPE_MAC48(4);
+               private int value;
+               private ONHAddressType(int value) {
+                       this.value = value;
+               }
+               public int getValue() {
+                       return this.value;
+               }
+           }
+           private enum ONHXAddressType {
+               ONH_XADDRTYPE_NONE(0),
+               ONH_XADDRTYPE_PORT(1),
+               ONH_XADDRTYPE_VPNID(2);
+               private int value;
+               private ONHXAddressType(int value) {
+                       this.value = value;
+               }
+               public int getValue() {
+                       return this.value;
+               }
+          }
+               protected InetAddress address; 
+                       
+               public ActionVendorOutputNextHop() {
+               super();
+               super.setLength((short)ONHLength.ONH_LEN_MIN.getValue());
+                       super.setVendor(VENDOR_CISCO);
+                       this.address = null;
+               }
+               
+               public void setNextHop(InetAddress address) {
+                       short actionLen;
+                       if (address instanceof Inet4Address) 
+                               actionLen = (short)ONHLength.ONH_LEN_IPV4.getValue();
+                       else
+                               actionLen = (short)ONHLength.ONH_LEN_IPV6.getValue();
+                       super.setLength(actionLen);
+                       this.address = address;
+               }
+               public InetAddress getNextHop() {
+                       return this.address;
+               }
+           @Override
+           public void readFrom(ByteBuffer data) {
+               /*
+                * For now, only contains the next hop address
+                */
+               //super.readFrom(data); don't need this
+               
+               if (data.remaining() < super.getLength()-8) {
+                       /*
+                        * malformed element, skip over 
+                        */
+                       data.position(data.remaining());
+                       return;
+               }
+               if ((super.getLength() !=  (short)ONHLength.ONH_LEN_IPV4.getValue()) &&
+                       (super.getLength() !=  (short)ONHLength.ONH_LEN_IPV6.getValue())) {
+                       /*
+                        * mal-formed element, skip over 
+                        */
+                       data.position(super.getLength());
+                       return;
+               }
+               data.getShort();  // skip the ONH_ACTION_OUTPUT_NH
+               data.getShort(); // skip address and xtraaddress types
+               data.getInt();     // skip the extra address (8 bytes)
+               data.getInt();
+               byte[] a;
+               if (super.getLength() == (short)ONHLength.ONH_LEN_IPV4.getValue()) {
+                       a = new byte[4];
+                       data.get(a);
+               } else {
+                       a = new byte[16];
+                       data.get(a);
+                       data.getInt(); //4 bytes pad
+               }
+               try {
+                       this.address = InetAddress.getByAddress(a);
+               } catch (UnknownHostException e) {
+                       e.printStackTrace();
+               }
+           }
+
+           @Override
+           public void writeTo(ByteBuffer data) {
+               byte atype = (byte)(ONHAddressType.ONH_ADDRTYPE_NONE.getValue());
+               byte xatype = (byte)(ONHXAddressType.ONH_XADDRTYPE_NONE.getValue());
+               if (address instanceof Inet4Address) 
+                       atype =  (byte)(ONHAddressType.ONH_ADDRTYPE_IPV4.getValue());
+               else
+                       atype = (byte)(ONHAddressType.ONH_ADDRTYPE_IPV6.getValue());
+               super.writeTo(data); // this writes the standard  8byte ofp_action_vendor_header
+               data.putShort((short)(ONHActionType.ONH_ACTION_OUTPUT_NH.getValue()));
+               data.put(atype);
+               data.put(xatype);
+               /*
+                * write the xtra address. For now it is all 0
+                */
+               data.putInt(0); // 8-byte pad
+               data.putInt(0);
+               /* 
+                * write the address only when address type is not P2P
+                */
+               if (atype == (byte)(ONHAddressType.ONH_ADDRTYPE_IPV4.getValue())) {
+                       data.put(address.getAddress()); // no need to pad
+                       //avnh.put(address.getAddress()); 
+               } else if (atype == (byte)(ONHAddressType.ONH_ADDRTYPE_IPV6.getValue())) {
+                       data.put(address.getAddress());
+                       //avnh.put(address.getAddress());
+                       data.putInt(0); // 4-byte pad
+                       //avnh.putInt(0);
+               }
+               ActionVendorOutputNextHop a = new ActionVendorOutputNextHop();
+               a.setLength((short)24);
+           }
+
+           @Override
+           public int hashCode() {
+               final int prime = 347;
+               int result = super.hashCode();
+               result = prime * result + address.hashCode();
+               return result;
+           }
+
+           @Override
+           public boolean equals(Object obj) {
+               if (this == obj) {
+                   return true;
+               }
+               if (!super.equals(obj)) {
+                   return false;
+               }
+               if (!(obj instanceof ActionVendorOutputNextHop)) {
+                   return false;
+               }
+               ActionVendorOutputNextHop other = (ActionVendorOutputNextHop) obj;
+               if (!other.address.equals(this.address))
+                       return false;
+               return true;
+           }
+
+               public String toString() {
+                       return ("OutputNextHop: " + address.getHostAddress());
+               }
+
+       }
+
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFAction.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFAction.java
new file mode 100644 (file)
index 0000000..d5a4eac
--- /dev/null
@@ -0,0 +1,157 @@
+package org.openflow.protocol.action;
+
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+
+import org.openflow.util.U16;
+
+/**
+ * The base class for all OpenFlow Actions.
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+public class OFAction implements Cloneable, Serializable{
+    /**
+     * Note the true minimum length for this header is 8 including a pad to 64
+     * bit alignment, however as this base class is used for demuxing an
+     * incoming Action, it is only necessary to read the first 4 bytes.  All
+     * Actions extending this class are responsible for reading/writing the
+     * first 8 bytes, including the pad if necessary.
+     */
+    public static int MINIMUM_LENGTH = 4;
+    public static int OFFSET_LENGTH = 2;
+    public static int OFFSET_TYPE = 0;
+
+    protected OFActionType type;
+    protected short length;
+
+    /**
+     * Get the length of this message
+     *
+     * @return
+     */
+    public short getLength() {
+        return length;
+    }
+
+    /**
+     * Get the length of this message, unsigned
+     *
+     * @return
+     */
+    public int getLengthU() {
+        return U16.f(length);
+    }
+
+    /**
+     * Set the length of this message
+     *
+     * @param length
+     */
+    public OFAction setLength(short length) {
+        this.length = length;
+        return this;
+    }
+
+    /**
+     * Get the type of this message
+     *
+     * @return OFActionType enum
+     */
+    public OFActionType getType() {
+        return this.type;
+    }
+
+    /**
+     * Set the type of this message
+     *
+     * @param type
+     */
+    public void setType(OFActionType type) {
+        this.type = type;
+    }
+
+    /**
+     * Returns a summary of the message
+     * @return "ofmsg=v=$version;t=$type:l=$len:xid=$xid"
+     */
+    public String toString() {
+        return "ofaction" +
+            ";t=" + this.getType() +
+            ";l=" + this.getLength();
+    }
+    
+    /**
+     * Given the output from toString(), 
+     * create a new OFAction
+     * @param val
+     * @return
+     */
+    public static OFAction fromString(String val) {
+        String tokens[] = val.split(";");
+        if (!tokens[0].equals("ofaction"))
+            throw new IllegalArgumentException("expected 'ofaction' but got '" + 
+                    tokens[0] + "'");
+        String type_tokens[] = tokens[1].split("="); 
+        String len_tokens[] = tokens[2].split("=");
+        OFAction action = new OFAction();
+        action.setLength(Short.valueOf(len_tokens[1]));
+        action.setType(OFActionType.valueOf(type_tokens[1]));
+        return action;
+    }
+
+    public void readFrom(ByteBuffer data) {
+        this.type = OFActionType.valueOf(data.getShort());
+        this.length = data.getShort();
+        // Note missing PAD, see MINIMUM_LENGTH comment for details
+    }
+
+    public void writeTo(ByteBuffer data) {
+        data.putShort(type.getTypeValue());
+        data.putShort(length);
+        // Note missing PAD, see MINIMUM_LENGTH comment for details
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 347;
+        int result = 1;
+        result = prime * result + length;
+        result = prime * result + ((type == null) ? 0 : type.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFAction)) {
+            return false;
+        }
+        OFAction other = (OFAction) obj;
+        if (length != other.length) {
+            return false;
+        }
+        if (type == null) {
+            if (other.type != null) {
+                return false;
+            }
+        } else if (!type.equals(other.type)) {
+            return false;
+        }
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#clone()
+     */
+    @Override
+    public OFAction clone() throws CloneNotSupportedException {
+        return (OFAction) super.clone();
+    }
+    
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionDataLayer.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionDataLayer.java
new file mode 100644 (file)
index 0000000..79edf90
--- /dev/null
@@ -0,0 +1,77 @@
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+package org.openflow.protocol.action;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import org.openflow.protocol.OFPhysicalPort;
+
+/**
+ * Represents an ofp_action_dl_addr
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+public abstract class OFActionDataLayer extends OFAction {
+    public static int MINIMUM_LENGTH = 16;
+
+    protected byte[] dataLayerAddress;
+
+    /**
+     * @return the dataLayerAddress
+     */
+    public byte[] getDataLayerAddress() {
+        return dataLayerAddress;
+    }
+
+    /**
+     * @param dataLayerAddress the dataLayerAddress to set
+     */
+    public void setDataLayerAddress(byte[] dataLayerAddress) {
+        this.dataLayerAddress = dataLayerAddress;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        if (this.dataLayerAddress == null)
+            this.dataLayerAddress = new byte[OFPhysicalPort.OFP_ETH_ALEN];
+        data.get(this.dataLayerAddress);
+        data.getInt();
+        data.getShort();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.put(this.dataLayerAddress);
+        data.putInt(0);
+        data.putShort((short) 0);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 347;
+        int result = super.hashCode();
+        result = prime * result + Arrays.hashCode(dataLayerAddress);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFActionDataLayer)) {
+            return false;
+        }
+        OFActionDataLayer other = (OFActionDataLayer) obj;
+        if (!Arrays.equals(dataLayerAddress, other.dataLayerAddress)) {
+            return false;
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionDataLayerDestination.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionDataLayerDestination.java
new file mode 100644 (file)
index 0000000..75014f4
--- /dev/null
@@ -0,0 +1,13 @@
+package org.openflow.protocol.action;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFActionDataLayerDestination extends OFActionDataLayer {
+    public OFActionDataLayerDestination() {
+        super();
+        super.setType(OFActionType.SET_DL_DST);
+        super.setLength((short) OFActionDataLayer.MINIMUM_LENGTH);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionDataLayerSource.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionDataLayerSource.java
new file mode 100644 (file)
index 0000000..f0e2fa9
--- /dev/null
@@ -0,0 +1,13 @@
+package org.openflow.protocol.action;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFActionDataLayerSource extends OFActionDataLayer {
+    public OFActionDataLayerSource() {
+        super();
+        super.setType(OFActionType.SET_DL_SRC);
+        super.setLength((short) OFActionDataLayer.MINIMUM_LENGTH);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionEnqueue.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionEnqueue.java
new file mode 100644 (file)
index 0000000..1791bc5
--- /dev/null
@@ -0,0 +1,100 @@
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+package org.openflow.protocol.action;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Represents an ofp_action_enqueue
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+public class OFActionEnqueue extends OFAction {
+    public static int MINIMUM_LENGTH = 16;
+
+    protected short port;
+    protected int queueId;
+
+    public OFActionEnqueue() {
+        super.setType(OFActionType.OPAQUE_ENQUEUE);
+        super.setLength((short) MINIMUM_LENGTH);
+    }
+
+    /**
+     * Get the output port
+     * @return
+     */
+    public short getPort() {
+        return this.port;
+    }
+
+    /**
+     * Set the output port
+     * @param port
+     */
+    public void setPort(short port) {
+        this.port = port;
+    }
+
+    /**
+     * @return the queueId
+     */
+    public int getQueueId() {
+        return queueId;
+    }
+
+    /**
+     * @param queueId the queueId to set
+     */
+    public void setQueueId(int queueId) {
+        this.queueId = queueId;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.port = data.getShort();
+        data.getShort();
+        data.getInt();
+        this.queueId = data.getInt();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putShort(this.port);
+        data.putShort((short) 0);
+        data.putInt(0);
+        data.putInt(this.queueId);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 349;
+        int result = super.hashCode();
+        result = prime * result + port;
+        result = prime * result + queueId;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFActionEnqueue)) {
+            return false;
+        }
+        OFActionEnqueue other = (OFActionEnqueue) obj;
+        if (port != other.port) {
+            return false;
+        }
+        if (queueId != other.queueId) {
+            return false;
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionNetworkLayerAddress.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionNetworkLayerAddress.java
new file mode 100644 (file)
index 0000000..5567684
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+package org.openflow.protocol.action;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Represents an ofp_action_nw_addr
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+public abstract class OFActionNetworkLayerAddress extends OFAction {
+    public static int MINIMUM_LENGTH = 8;
+
+    protected int networkAddress;
+
+    /**
+     * @return the networkAddress
+     */
+    public int getNetworkAddress() {
+        return networkAddress;
+    }
+
+    /**
+     * @param networkAddress the networkAddress to set
+     */
+    public void setNetworkAddress(int networkAddress) {
+        this.networkAddress = networkAddress;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.networkAddress = data.getInt();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putInt(this.networkAddress);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 353;
+        int result = super.hashCode();
+        result = prime * result + networkAddress;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFActionNetworkLayerAddress)) {
+            return false;
+        }
+        OFActionNetworkLayerAddress other = (OFActionNetworkLayerAddress) obj;
+        if (networkAddress != other.networkAddress) {
+            return false;
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionNetworkLayerDestination.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionNetworkLayerDestination.java
new file mode 100644 (file)
index 0000000..579570f
--- /dev/null
@@ -0,0 +1,13 @@
+package org.openflow.protocol.action;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFActionNetworkLayerDestination extends OFActionNetworkLayerAddress {
+    public OFActionNetworkLayerDestination() {
+        super();
+        super.setType(OFActionType.SET_NW_DST);
+        super.setLength((short) OFActionNetworkLayerAddress.MINIMUM_LENGTH);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionNetworkLayerSource.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionNetworkLayerSource.java
new file mode 100644 (file)
index 0000000..45e74a8
--- /dev/null
@@ -0,0 +1,13 @@
+package org.openflow.protocol.action;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFActionNetworkLayerSource extends OFActionNetworkLayerAddress {
+    public OFActionNetworkLayerSource() {
+        super();
+        super.setType(OFActionType.SET_NW_SRC);
+        super.setLength((short) OFActionNetworkLayerAddress.MINIMUM_LENGTH);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionNetworkTypeOfService.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionNetworkTypeOfService.java
new file mode 100644 (file)
index 0000000..d3075f8
--- /dev/null
@@ -0,0 +1,77 @@
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+package org.openflow.protocol.action;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Represents an ofp_action_enqueue
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+public class OFActionNetworkTypeOfService extends OFAction {
+    public static int MINIMUM_LENGTH = 8;
+
+    protected byte networkTypeOfService;
+
+    public OFActionNetworkTypeOfService() {
+        super.setType(OFActionType.SET_NW_TOS);
+        super.setLength((short) MINIMUM_LENGTH);
+    }
+
+    /**
+     * @return the networkTypeOfService
+     */
+    public byte getNetworkTypeOfService() {
+        return networkTypeOfService;
+    }
+
+    /**
+     * @param networkTypeOfService the networkTypeOfService to set
+     */
+    public void setNetworkTypeOfService(byte networkTypeOfService) {
+        this.networkTypeOfService = networkTypeOfService;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.networkTypeOfService = data.get();
+        data.getShort();
+        data.get();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.put(this.networkTypeOfService);
+        data.putShort((short) 0);
+        data.put((byte) 0);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 359;
+        int result = super.hashCode();
+        result = prime * result + networkTypeOfService;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFActionNetworkTypeOfService)) {
+            return false;
+        }
+        OFActionNetworkTypeOfService other = (OFActionNetworkTypeOfService) obj;
+        if (networkTypeOfService != other.networkTypeOfService) {
+            return false;
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionOutput.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionOutput.java
new file mode 100644 (file)
index 0000000..95208cd
--- /dev/null
@@ -0,0 +1,119 @@
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+package org.openflow.protocol.action;
+
+import java.nio.ByteBuffer;
+
+import org.openflow.util.U16;
+
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ */
+public class OFActionOutput extends OFAction implements Cloneable {
+    public static int MINIMUM_LENGTH = 8;
+
+    protected short port;
+    protected short maxLength;
+
+    public OFActionOutput() {
+        super.setType(OFActionType.OUTPUT);
+        super.setLength((short) MINIMUM_LENGTH);
+    }
+
+    public OFActionOutput(short port, short maxLength) {
+        super();
+        super.setType(OFActionType.OUTPUT);
+        super.setLength((short) MINIMUM_LENGTH);
+        this.port = port;
+        this.maxLength = maxLength;
+    }
+
+    /**
+     * Get the output port
+     * @return
+     */
+    public short getPort() {
+        return this.port;
+    }
+
+    /**
+     * Set the output port
+     * @param port
+     */
+    public OFActionOutput setPort(short port) {
+        this.port = port;
+        return this;
+    }
+
+    /**
+     * Get the max length to send to the controller
+     * @return
+     */
+    public short getMaxLength() {
+        return this.maxLength;
+    }
+
+    /**
+     * Set the max length to send to the controller
+     * @param maxLength
+     */
+    public OFActionOutput setMaxLength(short maxLength) {
+        this.maxLength = maxLength;
+        return this;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.port = data.getShort();
+        this.maxLength = data.getShort();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putShort(port);
+        data.putShort(maxLength);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 367;
+        int result = super.hashCode();
+        result = prime * result + maxLength;
+        result = prime * result + port;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFActionOutput)) {
+            return false;
+        }
+        OFActionOutput other = (OFActionOutput) obj;
+        if (maxLength != other.maxLength) {
+            return false;
+        }
+        if (port != other.port) {
+            return false;
+        }
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "OFActionOutput [maxLength=" + maxLength + ", port=" + U16.f(port)
+                + ", length=" + length + ", type=" + type + "]";
+    }
+}
\ No newline at end of file
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionStripVirtualLan.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionStripVirtualLan.java
new file mode 100644 (file)
index 0000000..eca3681
--- /dev/null
@@ -0,0 +1,35 @@
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+package org.openflow.protocol.action;
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * Represents an ofp_action_strip_vlan
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+public class OFActionStripVirtualLan extends OFAction {
+    public static int MINIMUM_LENGTH = 8;
+
+    public OFActionStripVirtualLan() {
+        super();
+        super.setType(OFActionType.STRIP_VLAN);
+        super.setLength((short) MINIMUM_LENGTH);
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        // PAD
+        data.getInt();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        // PAD
+        data.putInt(0);
+    }
+}
\ No newline at end of file
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionTransportLayer.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionTransportLayer.java
new file mode 100644 (file)
index 0000000..85c5e9f
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+package org.openflow.protocol.action;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Represents an ofp_action_tp_port
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+public abstract class OFActionTransportLayer extends OFAction {
+    public static int MINIMUM_LENGTH = 8;
+
+    protected short transportPort;
+
+    /**
+     * @return the transportPort
+     */
+    public short getTransportPort() {
+        return transportPort;
+    }
+
+    /**
+     * @param transportPort the transportPort to set
+     */
+    public void setTransportPort(short transportPort) {
+        this.transportPort = transportPort;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.transportPort = data.getShort();
+        data.getShort();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putShort(this.transportPort);
+        data.putShort((short) 0);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 373;
+        int result = super.hashCode();
+        result = prime * result + transportPort;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFActionTransportLayer)) {
+            return false;
+        }
+        OFActionTransportLayer other = (OFActionTransportLayer) obj;
+        if (transportPort != other.transportPort) {
+            return false;
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionTransportLayerDestination.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionTransportLayerDestination.java
new file mode 100644 (file)
index 0000000..8e91e59
--- /dev/null
@@ -0,0 +1,13 @@
+package org.openflow.protocol.action;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFActionTransportLayerDestination extends OFActionTransportLayer {
+    public OFActionTransportLayerDestination() {
+        super();
+        super.setType(OFActionType.SET_TP_DST);
+        super.setLength((short) OFActionTransportLayer.MINIMUM_LENGTH);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionTransportLayerSource.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionTransportLayerSource.java
new file mode 100644 (file)
index 0000000..555d4d1
--- /dev/null
@@ -0,0 +1,13 @@
+package org.openflow.protocol.action;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFActionTransportLayerSource extends OFActionTransportLayer {
+    public OFActionTransportLayerSource() {
+        super();
+        super.setType(OFActionType.SET_TP_SRC);
+        super.setLength((short) OFActionTransportLayer.MINIMUM_LENGTH);
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionType.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionType.java
new file mode 100644 (file)
index 0000000..211752e
--- /dev/null
@@ -0,0 +1,187 @@
+/**
+ *
+ */
+package org.openflow.protocol.action;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+
+import org.openflow.protocol.Instantiable;
+
+/**
+ * List of OpenFlow Action types and mappings to wire protocol value and
+ * derived classes
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public enum OFActionType implements Serializable{
+    OUTPUT              (0, OFActionOutput.class, new Instantiable<OFAction>() {
+                            @Override
+                            public OFAction instantiate() {
+                                return new OFActionOutput();
+                            }}),
+    SET_VLAN_VID        (1, OFActionVirtualLanIdentifier.class, new Instantiable<OFAction>() {
+                            @Override
+                            public OFAction instantiate() {
+                                return new OFActionVirtualLanIdentifier();
+                            }}),
+    SET_VLAN_PCP        (2, OFActionVirtualLanPriorityCodePoint.class, new Instantiable<OFAction>() {
+                            @Override
+                            public OFAction instantiate() {
+                                return new OFActionVirtualLanPriorityCodePoint();
+                            }}),
+    STRIP_VLAN          (3, OFActionStripVirtualLan.class, new Instantiable<OFAction>() {
+                            @Override
+                            public OFAction instantiate() {
+                                return new OFActionStripVirtualLan();
+                            }}),
+    SET_DL_SRC          (4, OFActionDataLayerSource.class, new Instantiable<OFAction>() {
+                            @Override
+                            public OFAction instantiate() {
+                                return new OFActionDataLayerSource();
+                            }}),
+    SET_DL_DST          (5, OFActionDataLayerDestination.class, new Instantiable<OFAction>() {
+                            @Override
+                            public OFAction instantiate() {
+                                return new OFActionDataLayerDestination();
+                            }}),
+    SET_NW_SRC          (6, OFActionNetworkLayerSource.class, new Instantiable<OFAction>() {
+                            @Override
+                            public OFAction instantiate() {
+                                return new OFActionNetworkLayerSource();
+                            }}),
+    SET_NW_DST          (7, OFActionNetworkLayerDestination.class, new Instantiable<OFAction>() {
+                            @Override
+                            public OFAction instantiate() {
+                                return new OFActionNetworkLayerDestination();
+                            }}),
+    SET_NW_TOS          (8, OFActionNetworkTypeOfService.class, new Instantiable<OFAction>() {
+                            @Override
+                            public OFAction instantiate() {
+                                return new OFActionNetworkTypeOfService();
+                            }}),
+    SET_TP_SRC          (9, OFActionTransportLayerSource.class, new Instantiable<OFAction>() {
+                            @Override
+                            public OFAction instantiate() {
+                                return new OFActionTransportLayerSource();
+                            }}),
+    SET_TP_DST          (10, OFActionTransportLayerDestination.class, new Instantiable<OFAction>() {
+                            @Override
+                            public OFAction instantiate() {
+                                return new OFActionTransportLayerDestination();
+                            }}),
+    OPAQUE_ENQUEUE      (11, OFActionEnqueue.class, new Instantiable<OFAction>() {
+                            @Override
+                            public OFAction instantiate() {
+                                return new OFActionEnqueue();
+                            }}),
+    VENDOR              (0xffff, OFActionVendor.class, new Instantiable<OFAction>() {
+                            @Override
+                            public OFAction instantiate() {
+                                return new OFActionVendor();
+                            }});
+
+    protected static OFActionType[] mapping;
+
+    protected Class<? extends OFAction> clazz;
+    protected Constructor<? extends OFAction> constructor;
+    protected Instantiable<OFAction> instantiable;
+    protected int minLen;
+    protected short type;
+
+    /**
+     * Store some information about the OpenFlow Action type, including wire
+     * protocol type number, length, and derrived class
+     *
+     * @param type Wire protocol number associated with this OFType
+     * @param clazz The Java class corresponding to this type of OpenFlow Action
+     * @param instantiable the instantiable for the OFAction this type represents
+     */
+    OFActionType(int type, Class<? extends OFAction> clazz, Instantiable<OFAction> instantiable) {
+        this.type = (short) type;
+        this.clazz = clazz;
+        this.instantiable = instantiable;
+        try {
+            this.constructor = clazz.getConstructor(new Class[]{});
+        } catch (Exception e) {
+            throw new RuntimeException(
+                    "Failure getting constructor for class: " + clazz, e);
+        }
+        OFActionType.addMapping(this.type, this);
+    }
+
+    /**
+     * Adds a mapping from type value to OFActionType enum
+     *
+     * @param i OpenFlow wire protocol Action type value
+     * @param t type
+     */
+    static public void addMapping(short i, OFActionType t) {
+        if (mapping == null)
+            mapping = new OFActionType[16];
+        // bring higher mappings down to the edge of our array
+        if (i < 0)
+            i = (short) (16 + i);
+        OFActionType.mapping[i] = t;
+    }
+
+    /**
+     * Given a wire protocol OpenFlow type number, return the OFType associated
+     * with it
+     *
+     * @param i wire protocol number
+     * @return OFType enum type
+     */
+
+    static public OFActionType valueOf(short i) {
+        if (i < 0)
+            i = (short) (16+i);
+        return OFActionType.mapping[i];
+    }
+
+    /**
+     * @return Returns the wire protocol value corresponding to this
+     *         OFActionType
+     */
+    public short getTypeValue() {
+        return this.type;
+    }
+
+    /**
+     * @return return the OFAction subclass corresponding to this OFActionType
+     */
+    public Class<? extends OFAction> toClass() {
+        return clazz;
+    }
+
+    /**
+     * Returns the no-argument Constructor of the implementation class for
+     * this OFActionType
+     * @return the constructor
+     */
+    public Constructor<? extends OFAction> getConstructor() {
+        return constructor;
+    }
+
+    /**
+     * Returns a new instance of the OFAction represented by this OFActionType
+     * @return the new object
+     */
+    public OFAction newInstance() {
+        return instantiable.instantiate();
+    }
+
+    /**
+     * @return the instantiable
+     */
+    public Instantiable<OFAction> getInstantiable() {
+        return instantiable;
+    }
+
+    /**
+     * @param instantiable the instantiable to set
+     */
+    public void setInstantiable(Instantiable<OFAction> instantiable) {
+        this.instantiable = instantiable;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionVendor.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionVendor.java
new file mode 100644 (file)
index 0000000..430c895
--- /dev/null
@@ -0,0 +1,87 @@
+package org.openflow.protocol.action;
+
+import java.nio.ByteBuffer;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFActionVendor extends OFAction {
+    public static int MINIMUM_LENGTH = 8;
+    
+    protected int vendor;
+
+       public enum ActionVendorID {
+               AVI_CISCO(0xC);
+       private int value;
+       private ActionVendorID(int value) {
+               this.value = value;
+       }
+       public int getValue() {
+               return this.value;
+       }
+       }       
+
+    public OFActionVendor() {
+        super();
+        super.setType(OFActionType.VENDOR);
+        super.setLength((short) MINIMUM_LENGTH);
+    }
+
+    /**
+     * @return the vendor
+     */
+    public int getVendor() {
+        return vendor;
+    }
+
+    /**
+     * @param vendor the vendor to set
+     */
+    public void setVendor(int vendor) {
+        this.vendor = vendor;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.vendor = data.getInt();
+        if (this.vendor == ActionVendorID.AVI_CISCO.getValue()) {
+               ActionVendorOutputNextHop nh = new ActionVendorOutputNextHop();
+               nh.readFrom(data);
+        }
+               
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putInt(this.vendor);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 379;
+        int result = super.hashCode();
+        result = prime * result + vendor;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFActionVendor)) {
+            return false;
+        }
+        OFActionVendor other = (OFActionVendor) obj;
+        if (vendor != other.vendor) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionVirtualLanIdentifier.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionVirtualLanIdentifier.java
new file mode 100644 (file)
index 0000000..f112fad
--- /dev/null
@@ -0,0 +1,75 @@
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+package org.openflow.protocol.action;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Represents an ofp_action_vlan_vid
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+public class OFActionVirtualLanIdentifier extends OFAction {
+    public static int MINIMUM_LENGTH = 8;
+
+    protected short virtualLanIdentifier;
+
+    public OFActionVirtualLanIdentifier() {
+        super.setType(OFActionType.SET_VLAN_VID);
+        super.setLength((short) MINIMUM_LENGTH);
+    }
+
+    /**
+     * @return the virtualLanIdentifier
+     */
+    public short getVirtualLanIdentifier() {
+        return virtualLanIdentifier;
+    }
+
+    /**
+     * @param virtualLanIdentifier the virtualLanIdentifier to set
+     */
+    public void setVirtualLanIdentifier(short virtualLanIdentifier) {
+        this.virtualLanIdentifier = virtualLanIdentifier;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.virtualLanIdentifier = data.getShort();
+        data.getShort();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putShort(this.virtualLanIdentifier);
+        data.putShort((short) 0);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 383;
+        int result = super.hashCode();
+        result = prime * result + virtualLanIdentifier;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFActionVirtualLanIdentifier)) {
+            return false;
+        }
+        OFActionVirtualLanIdentifier other = (OFActionVirtualLanIdentifier) obj;
+        if (virtualLanIdentifier != other.virtualLanIdentifier) {
+            return false;
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionVirtualLanPriorityCodePoint.java b/third-party/openflowj/src/main/java/org/openflow/protocol/action/OFActionVirtualLanPriorityCodePoint.java
new file mode 100644 (file)
index 0000000..11b7d43
--- /dev/null
@@ -0,0 +1,77 @@
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+package org.openflow.protocol.action;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Represents an ofp_action_vlan_pcp
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+public class OFActionVirtualLanPriorityCodePoint extends OFAction {
+    public static int MINIMUM_LENGTH = 8;
+
+    protected byte virtualLanPriorityCodePoint;
+
+    public OFActionVirtualLanPriorityCodePoint() {
+        super.setType(OFActionType.SET_VLAN_PCP);
+        super.setLength((short) MINIMUM_LENGTH);
+    }
+
+    /**
+     * @return the virtualLanPriorityCodePoint
+     */
+    public byte getVirtualLanPriorityCodePoint() {
+        return virtualLanPriorityCodePoint;
+    }
+
+    /**
+     * @param virtualLanPriorityCodePoint the virtualLanPriorityCodePoint to set
+     */
+    public void setVirtualLanPriorityCodePoint(byte virtualLanPriorityCodePoint) {
+        this.virtualLanPriorityCodePoint = virtualLanPriorityCodePoint;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.virtualLanPriorityCodePoint = data.get();
+        data.getShort(); // pad
+        data.get(); // pad
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.put(this.virtualLanPriorityCodePoint);
+        data.putShort((short) 0);
+        data.put((byte) 0);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 389;
+        int result = super.hashCode();
+        result = prime * result + virtualLanPriorityCodePoint;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (!(obj instanceof OFActionVirtualLanPriorityCodePoint)) {
+            return false;
+        }
+        OFActionVirtualLanPriorityCodePoint other = (OFActionVirtualLanPriorityCodePoint) obj;
+        if (virtualLanPriorityCodePoint != other.virtualLanPriorityCodePoint) {
+            return false;
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/factory/BasicFactory.java b/third-party/openflowj/src/main/java/org/openflow/protocol/factory/BasicFactory.java
new file mode 100644 (file)
index 0000000..cd7c8de
--- /dev/null
@@ -0,0 +1,241 @@
+package org.openflow.protocol.factory;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openflow.protocol.OFMessage;
+import org.openflow.protocol.OFType;
+import org.openflow.protocol.action.OFAction;
+import org.openflow.protocol.action.OFActionType;
+import org.openflow.protocol.queue.OFQueueProperty;
+import org.openflow.protocol.queue.OFQueuePropertyType;
+import org.openflow.protocol.statistics.OFStatistics;
+import org.openflow.protocol.statistics.OFStatisticsType;
+import org.openflow.protocol.statistics.OFVendorStatistics;
+
+
+/**
+ * A basic OpenFlow factory that supports naive creation of both Messages and
+ * Actions.
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ *
+ */
+public class BasicFactory implements OFMessageFactory, OFActionFactory,
+        OFQueuePropertyFactory, OFStatisticsFactory {
+    @Override
+    public OFMessage getMessage(OFType t) {
+        return t.newInstance();
+    }
+
+    @Override
+    public List<OFMessage> parseMessages(ByteBuffer data) {
+        return parseMessages(data, 0);
+    }
+
+    @Override
+    public List<OFMessage> parseMessages(ByteBuffer data, int limit) {
+        List<OFMessage> results = new ArrayList<OFMessage>();
+        OFMessage demux = new OFMessage();
+        OFMessage ofm;
+
+        while (limit == 0 || results.size() <= limit) {
+            if (data.remaining() < OFMessage.MINIMUM_LENGTH)
+                return results;
+
+            data.mark();
+            demux.readFrom(data);
+            data.reset();
+
+            if (demux.getLengthU() > data.remaining())
+                return results;
+
+            ofm = getMessage(demux.getType());
+            if (ofm instanceof OFActionFactoryAware) {
+                ((OFActionFactoryAware)ofm).setActionFactory(this);
+            }
+            if (ofm instanceof OFMessageFactoryAware) {
+                ((OFMessageFactoryAware)ofm).setMessageFactory(this);
+            }
+            if (ofm instanceof OFQueuePropertyFactoryAware) {
+                ((OFQueuePropertyFactoryAware)ofm).setQueuePropertyFactory(this);
+            }
+            if (ofm instanceof OFStatisticsFactoryAware) {
+                ((OFStatisticsFactoryAware)ofm).setStatisticsFactory(this);
+            }
+            ofm.readFrom(data);
+            if (OFMessage.class.equals(ofm.getClass())) {
+                // advance the position for un-implemented messages
+                data.position(data.position()+(ofm.getLengthU() -
+                        OFMessage.MINIMUM_LENGTH));
+            }
+            results.add(ofm);
+        }
+
+        return results;
+    }
+
+    @Override
+    public OFAction getAction(OFActionType t) {
+        return t.newInstance();
+    }
+
+    @Override
+    public List<OFAction> parseActions(ByteBuffer data, int length) {
+        return parseActions(data, length, 0);
+    }
+
+    @Override
+    public List<OFAction> parseActions(ByteBuffer data, int length, int limit) {
+        List<OFAction> results = new ArrayList<OFAction>();
+        OFAction demux = new OFAction();
+        OFAction ofa;
+        int end = data.position() + length;
+
+        while (limit == 0 || results.size() <= limit) {
+            if (data.remaining() < OFAction.MINIMUM_LENGTH ||
+                    (data.position() + OFAction.MINIMUM_LENGTH) > end)
+                return results;
+
+            data.mark();
+            demux.readFrom(data);
+            data.reset();
+
+            if (demux.getLengthU() > data.remaining() ||
+                    (data.position() + demux.getLengthU()) > end)
+                return results;
+
+            ofa = getAction(demux.getType());
+            ofa.readFrom(data);
+            if (OFAction.class.equals(ofa.getClass())) {
+                // advance the position for un-implemented messages
+                data.position(data.position()+(ofa.getLengthU() -
+                        OFAction.MINIMUM_LENGTH));
+            }
+            results.add(ofa);
+        }
+
+        return results;
+    }
+
+    @Override
+    public OFActionFactory getActionFactory() {
+        return this;
+    }
+
+    @Override
+    public OFStatistics getStatistics(OFType t, OFStatisticsType st) {
+        return st.newInstance(t);
+    }
+
+    @Override
+    public List<OFStatistics> parseStatistics(OFType t, OFStatisticsType st,
+            ByteBuffer data, int length) {
+        return parseStatistics(t, st, data, length, 0);
+    }
+
+    /**
+     * @param t
+     *            OFMessage type: should be one of stats_request or stats_reply
+     * @param st
+     *            statistics type of this message, e.g., DESC, TABLE
+     * @param data
+     *            buffer to read from
+     * @param length
+     *            length of statistics
+     * @param limit
+     *            number of statistics to grab; 0 == all
+     * 
+     * @return list of statistics
+     */
+
+    @Override
+    public List<OFStatistics> parseStatistics(OFType t, OFStatisticsType st,
+            ByteBuffer data, int length, int limit) {
+        List<OFStatistics> results = new ArrayList<OFStatistics>();
+        OFStatistics statistics = getStatistics(t, st);
+
+        int start = data.position();
+        int count = 0;
+
+        while (limit == 0 || results.size() <= limit) {
+            // TODO Create a separate MUX/DEMUX path for vendor stats
+            if (statistics instanceof OFVendorStatistics)
+                ((OFVendorStatistics)statistics).setLength(length);
+
+            /**
+             * can't use data.remaining() here, b/c there could be other data
+             * buffered past this message
+             */
+            if ((length - count) >= statistics.getLength()) {
+                if (statistics instanceof OFActionFactoryAware)
+                    ((OFActionFactoryAware)statistics).setActionFactory(this);
+                statistics.readFrom(data);
+                results.add(statistics);
+                count += statistics.getLength();
+                statistics = getStatistics(t, st);
+            } else {
+                if (count < length) {
+                    /**
+                     * Nasty case: partial/incomplete statistic found even
+                     * though we have a full message. Found when NOX sent
+                     * agg_stats request with wrong agg statistics length (52
+                     * instead of 56)
+                     * 
+                     * just throw the rest away, or we will break framing
+                     */
+                    data.position(start + length);
+                }
+                return results;
+            }
+        }
+        return results; // empty; no statistics at all
+    }
+
+    @Override
+    public OFQueueProperty getQueueProperty(OFQueuePropertyType t) {
+        return t.newInstance();
+    }
+
+    @Override
+    public List<OFQueueProperty> parseQueueProperties(ByteBuffer data,
+            int length) {
+        return parseQueueProperties(data, length, 0);
+    }
+
+    @Override
+    public List<OFQueueProperty> parseQueueProperties(ByteBuffer data,
+            int length, int limit) {
+        List<OFQueueProperty> results = new ArrayList<OFQueueProperty>();
+        OFQueueProperty demux = new OFQueueProperty();
+        OFQueueProperty ofqp;
+        int end = data.position() + length;
+
+        while (limit == 0 || results.size() <= limit) {
+            if (data.remaining() < OFQueueProperty.MINIMUM_LENGTH ||
+                    (data.position() + OFQueueProperty.MINIMUM_LENGTH) > end)
+                return results;
+
+            data.mark();
+            demux.readFrom(data);
+            data.reset();
+
+            if (demux.getLengthU() > data.remaining() ||
+                    (data.position() + demux.getLengthU()) > end)
+                return results;
+
+            ofqp = getQueueProperty(demux.getType());
+            ofqp.readFrom(data);
+            if (OFQueueProperty.class.equals(ofqp.getClass())) {
+                // advance the position for un-implemented messages
+                data.position(data.position()+(ofqp.getLengthU() -
+                        OFQueueProperty.MINIMUM_LENGTH));
+            }
+            results.add(ofqp);
+        }
+
+        return results;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFActionFactory.java b/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFActionFactory.java
new file mode 100644 (file)
index 0000000..5d0949b
--- /dev/null
@@ -0,0 +1,44 @@
+package org.openflow.protocol.factory;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.openflow.protocol.action.OFAction;
+import org.openflow.protocol.action.OFActionType;
+
+
+/**
+ * The interface to factories used for retrieving OFAction instances. All
+ * methods are expected to be thread-safe.
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public interface OFActionFactory {
+    /**
+     * Retrieves an OFAction instance corresponding to the specified
+     * OFActionType
+     * @param t the type of the OFAction to be retrieved
+     * @return an OFAction instance
+     */
+    public OFAction getAction(OFActionType t);
+
+    /**
+     * Attempts to parse and return all OFActions contained in the given
+     * ByteBuffer, beginning at the ByteBuffer's position, and ending at
+     * position+length.
+     * @param data the ByteBuffer to parse for OpenFlow actions
+     * @param length the number of Bytes to examine for OpenFlow actions
+     * @return a list of OFAction instances
+     */
+    public List<OFAction> parseActions(ByteBuffer data, int length);
+
+    /**
+     * Attempts to parse and return all OFActions contained in the given
+     * ByteBuffer, beginning at the ByteBuffer's position, and ending at
+     * position+length.
+     * @param data the ByteBuffer to parse for OpenFlow actions
+     * @param length the number of Bytes to examine for OpenFlow actions
+     * @param limit the maximum number of messages to return, 0 means no limit
+     * @return a list of OFAction instances
+     */
+    public List<OFAction> parseActions(ByteBuffer data, int length, int limit);
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFActionFactoryAware.java b/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFActionFactoryAware.java
new file mode 100644 (file)
index 0000000..7bf34b0
--- /dev/null
@@ -0,0 +1,14 @@
+package org.openflow.protocol.factory;
+
+/**
+ * Objects implementing this interface are expected to be instantiated with an
+ * instance of an OFActionFactory
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public interface OFActionFactoryAware {
+    /**
+     * Sets the OFActionFactory
+     * @param actionFactory
+     */
+    public void setActionFactory(OFActionFactory actionFactory);
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFMessageFactory.java b/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFMessageFactory.java
new file mode 100644 (file)
index 0000000..56ced52
--- /dev/null
@@ -0,0 +1,47 @@
+package org.openflow.protocol.factory;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.openflow.protocol.OFMessage;
+import org.openflow.protocol.OFType;
+
+
+/**
+ * The interface to factories used for retrieving OFMessage instances. All
+ * methods are expected to be thread-safe.
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public interface OFMessageFactory {
+    /**
+     * Retrieves an OFMessage instance corresponding to the specified OFType
+     * @param t the type of the OFMessage to be retrieved
+     * @return an OFMessage instance
+     */
+    public OFMessage getMessage(OFType t);
+
+    /**
+     * Attempts to parse and return all OFMessages contained in the given
+     * ByteBuffer, beginning at the ByteBuffer's position, and ending at the
+     * ByteBuffer's limit.
+     * @param data the ByteBuffer to parse for an OpenFlow message
+     * @return a list of OFMessage instances
+     */
+    public List<OFMessage> parseMessages(ByteBuffer data);
+
+    /**
+     * Attempts to parse and return all OFMessages contained in the given
+     * ByteBuffer, beginning at the ByteBuffer's position, and ending at the
+     * ByteBuffer's limit.
+     * @param data the ByteBuffer to parse for an OpenFlow message
+     * @param limit the maximum number of messages to return, 0 means no limit
+     * @return a list of OFMessage instances
+     */
+    public List<OFMessage> parseMessages(ByteBuffer data, int limit);
+
+    /**
+     * Retrieves an OFActionFactory
+     * @return an OFActionFactory
+     */
+    public OFActionFactory getActionFactory();
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFMessageFactoryAware.java b/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFMessageFactoryAware.java
new file mode 100644 (file)
index 0000000..28b56d3
--- /dev/null
@@ -0,0 +1,18 @@
+/**
+ * 
+ */
+package org.openflow.protocol.factory;
+
+/**
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ *
+ */
+public interface OFMessageFactoryAware {
+
+       /**
+        * Sets the message factory for this object
+        * 
+        * @param factory
+        */
+       void setMessageFactory(OFMessageFactory factory);
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFQueuePropertyFactory.java b/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFQueuePropertyFactory.java
new file mode 100644 (file)
index 0000000..69569a9
--- /dev/null
@@ -0,0 +1,44 @@
+package org.openflow.protocol.factory;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.openflow.protocol.queue.OFQueueProperty;
+import org.openflow.protocol.queue.OFQueuePropertyType;
+
+
+/**
+ * The interface to factories used for retrieving OFQueueProperty instances. All
+ * methods are expected to be thread-safe.
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public interface OFQueuePropertyFactory {
+    /**
+     * Retrieves an OFQueueProperty instance corresponding to the specified
+     * OFQueuePropertyType
+     * @param t the type of the OFQueueProperty to be retrieved
+     * @return an OFQueueProperty instance
+     */
+    public OFQueueProperty getQueueProperty(OFQueuePropertyType t);
+
+    /**
+     * Attempts to parse and return all OFQueueProperties contained in the given
+     * ByteBuffer, beginning at the ByteBuffer's position, and ending at
+     * position+length.
+     * @param data the ByteBuffer to parse for OpenFlow OFQueueProperties
+     * @param length the number of Bytes to examine for OpenFlow OFQueueProperties
+     * @return a list of OFQueueProperty instances
+     */
+    public List<OFQueueProperty> parseQueueProperties(ByteBuffer data, int length);
+
+    /**
+     * Attempts to parse and return all OFQueueProperties contained in the given
+     * ByteBuffer, beginning at the ByteBuffer's position, and ending at
+     * position+length.
+     * @param data the ByteBuffer to parse for OpenFlow OFQueueProperties
+     * @param length the number of Bytes to examine for OpenFlow OFQueueProperties
+     * @param limit the maximum number of OFQueueProperties to return, 0 means no limit
+     * @return a list of OFQueueProperty instances
+     */
+    public List<OFQueueProperty> parseQueueProperties(ByteBuffer data, int length, int limit);
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFQueuePropertyFactoryAware.java b/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFQueuePropertyFactoryAware.java
new file mode 100644 (file)
index 0000000..9f1b61f
--- /dev/null
@@ -0,0 +1,14 @@
+package org.openflow.protocol.factory;
+
+/**
+ * Objects implementing this interface are expected to be instantiated with an
+ * instance of an OFQueuePropertyFactory
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public interface OFQueuePropertyFactoryAware {
+    /**
+     * Sets the OFQueuePropertyFactory
+     * @param queuePropertyFactory
+     */
+    public void setQueuePropertyFactory(OFQueuePropertyFactory queuePropertyFactory);
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFStatisticsFactory.java b/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFStatisticsFactory.java
new file mode 100644 (file)
index 0000000..d11fa54
--- /dev/null
@@ -0,0 +1,55 @@
+package org.openflow.protocol.factory;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.openflow.protocol.OFType;
+import org.openflow.protocol.statistics.OFStatistics;
+import org.openflow.protocol.statistics.OFStatisticsType;
+
+
+/**
+ * The interface to factories used for retrieving OFStatistics instances. All
+ * methods are expected to be thread-safe.
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public interface OFStatisticsFactory {
+    /**
+     * Retrieves an OFStatistics instance corresponding to the specified
+     * OFStatisticsType
+     * @param t the type of the containing OFMessage, only accepts statistics
+     *           request or reply
+     * @param st the type of the OFStatistics to be retrieved
+     * @return an OFStatistics instance
+     */
+    public OFStatistics getStatistics(OFType t, OFStatisticsType st);
+
+    /**
+     * Attempts to parse and return all OFStatistics contained in the given
+     * ByteBuffer, beginning at the ByteBuffer's position, and ending at
+     * position+length.
+     * @param t the type of the containing OFMessage, only accepts statistics
+     *           request or reply
+     * @param st the type of the OFStatistics to be retrieved
+     * @param data the ByteBuffer to parse for OpenFlow Statistics
+     * @param length the number of Bytes to examine for OpenFlow Statistics
+     * @return a list of OFStatistics instances
+     */
+    public List<OFStatistics> parseStatistics(OFType t,
+            OFStatisticsType st, ByteBuffer data, int length);
+
+    /**
+     * Attempts to parse and return all OFStatistics contained in the given
+     * ByteBuffer, beginning at the ByteBuffer's position, and ending at
+     * position+length.
+     * @param t the type of the containing OFMessage, only accepts statistics
+     *           request or reply
+     * @param st the type of the OFStatistics to be retrieved
+     * @param data the ByteBuffer to parse for OpenFlow Statistics
+     * @param length the number of Bytes to examine for OpenFlow Statistics
+     * @param limit the maximum number of messages to return, 0 means no limit
+     * @return a list of OFStatistics instances
+     */
+    public List<OFStatistics> parseStatistics(OFType t,
+            OFStatisticsType st, ByteBuffer data, int length, int limit);
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFStatisticsFactoryAware.java b/third-party/openflowj/src/main/java/org/openflow/protocol/factory/OFStatisticsFactoryAware.java
new file mode 100644 (file)
index 0000000..17ab5f7
--- /dev/null
@@ -0,0 +1,14 @@
+package org.openflow.protocol.factory;
+
+/**
+ * Objects implementing this interface are expected to be instantiated with an
+ * instance of an OFStatisticsFactory
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public interface OFStatisticsFactoryAware {
+    /**
+     * Sets the OFStatisticsFactory
+     * @param statisticsFactory
+     */
+    public void setStatisticsFactory(OFStatisticsFactory statisticsFactory);
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/queue/OFPacketQueue.java b/third-party/openflowj/src/main/java/org/openflow/protocol/queue/OFPacketQueue.java
new file mode 100644 (file)
index 0000000..eb90ed5
--- /dev/null
@@ -0,0 +1,153 @@
+package org.openflow.protocol.queue;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openflow.protocol.factory.OFQueuePropertyFactory;
+import org.openflow.protocol.factory.OFQueuePropertyFactoryAware;
+import org.openflow.util.U16;
+
+/**
+ * Corresponds to the struct ofp_packet_queue OpenFlow structure
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFPacketQueue implements Cloneable, OFQueuePropertyFactoryAware {
+    public static int MINIMUM_LENGTH = 8;
+
+    protected OFQueuePropertyFactory queuePropertyFactory;
+
+    protected int queueId;
+    protected short length;
+    protected List<OFQueueProperty> properties;
+
+    /**
+     * @return the queueId
+     */
+    public int getQueueId() {
+        return queueId;
+    }
+
+    /**
+     * @param queueId the queueId to set
+     */
+    public OFPacketQueue setQueueId(int queueId) {
+        this.queueId = queueId;
+        return this;
+    }
+
+    /**
+     * @return the length
+     */
+    public short getLength() {
+        return length;
+    }
+
+    /**
+     * @param length the length to set
+     */
+    public void setLength(short length) {
+        this.length = length;
+    }
+
+    /**
+     * @return the properties
+     */
+    public List<OFQueueProperty> getProperties() {
+        return properties;
+    }
+
+    /**
+     * @param properties the properties to set
+     */
+    public OFPacketQueue setProperties(List<OFQueueProperty> properties) {
+        this.properties = properties;
+        return this;
+    }
+
+    public void readFrom(ByteBuffer data) {
+        this.queueId = data.getInt();
+        this.length = data.getShort();
+        data.getShort(); // pad
+        if (this.queuePropertyFactory == null)
+            throw new RuntimeException("OFQueuePropertyFactory not set");
+        this.properties = queuePropertyFactory.parseQueueProperties(data,
+                U16.f(this.length) - MINIMUM_LENGTH);
+    }
+
+    public void writeTo(ByteBuffer data) {
+        data.putInt(this.queueId);
+        data.putShort(this.length);
+        data.putShort((short) 0); // pad
+        if (this.properties != null) {
+            for (OFQueueProperty queueProperty : this.properties) {
+                queueProperty.writeTo(data);
+            }
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 6367;
+        int result = 1;
+        result = prime * result + length;
+        result = prime * result
+                + ((properties == null) ? 0 : properties.hashCode());
+        result = prime * result + queueId;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (!(obj instanceof OFPacketQueue))
+            return false;
+        OFPacketQueue other = (OFPacketQueue) obj;
+        if (length != other.length)
+            return false;
+        if (properties == null) {
+            if (other.properties != null)
+                return false;
+        } else if (!properties.equals(other.properties))
+            return false;
+        if (queueId != other.queueId)
+            return false;
+        return true;
+    }
+
+    @Override
+    public OFPacketQueue clone() {
+        try {
+            OFPacketQueue clone = (OFPacketQueue) super.clone();
+            if (this.properties != null) {
+                List<OFQueueProperty> queueProps = new ArrayList<OFQueueProperty>();
+                for (OFQueueProperty prop : this.properties) {
+                    queueProps.add(prop.clone());
+                }
+                clone.setProperties(queueProps);
+            }
+            return clone;
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void setQueuePropertyFactory(
+            OFQueuePropertyFactory queuePropertyFactory) {
+        this.queuePropertyFactory = queuePropertyFactory;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "OFPacketQueue [queueId=" + queueId + ", properties="
+                + properties + "]";
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/queue/OFQueueProperty.java b/third-party/openflowj/src/main/java/org/openflow/protocol/queue/OFQueueProperty.java
new file mode 100644 (file)
index 0000000..d9e8785
--- /dev/null
@@ -0,0 +1,100 @@
+package org.openflow.protocol.queue;
+
+import java.nio.ByteBuffer;
+
+import org.openflow.util.U16;
+
+/**
+ * Corresponds to the struct ofp_queue_prop_header OpenFlow structure
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFQueueProperty implements Cloneable {
+    public static int MINIMUM_LENGTH = 8;
+
+    protected OFQueuePropertyType type;
+    protected short length;
+
+    /**
+     * @return the type
+     */
+    public OFQueuePropertyType getType() {
+        return type;
+    }
+
+    /**
+     * @param type the type to set
+     */
+    public void setType(OFQueuePropertyType type) {
+        this.type = type;
+    }
+
+    /**
+     * @return the length
+     */
+    public short getLength() {
+        return length;
+    }
+
+    /**
+     * Returns the unsigned length
+     *
+     * @return the length
+     */
+    public int getLengthU() {
+        return U16.f(length);
+    }
+
+    /**
+     * @param length the length to set
+     */
+    public void setLength(short length) {
+        this.length = length;
+    }
+
+    public void readFrom(ByteBuffer data) {
+        this.type = OFQueuePropertyType.valueOf(data.getShort());
+        this.length = data.getShort();
+        data.getInt(); // pad
+    }
+
+    public void writeTo(ByteBuffer data) {
+        data.putShort(this.type.getTypeValue());
+        data.putShort(this.length);
+        data.putInt(0); // pad
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 2777;
+        int result = 1;
+        result = prime * result + length;
+        result = prime * result + ((type == null) ? 0 : type.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (!(obj instanceof OFQueueProperty))
+            return false;
+        OFQueueProperty other = (OFQueueProperty) obj;
+        if (length != other.length)
+            return false;
+        if (type != other.type)
+            return false;
+        return true;
+    }
+
+    @Override
+    protected OFQueueProperty clone() {
+        try {
+            return (OFQueueProperty) super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/queue/OFQueuePropertyMinRate.java b/third-party/openflowj/src/main/java/org/openflow/protocol/queue/OFQueuePropertyMinRate.java
new file mode 100644 (file)
index 0000000..dd8e2a9
--- /dev/null
@@ -0,0 +1,87 @@
+package org.openflow.protocol.queue;
+
+import java.nio.ByteBuffer;
+
+import org.openflow.util.U16;
+
+/**
+ * Corresponds to the struct struct ofp_queue_prop_min_rate OpenFlow structure
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFQueuePropertyMinRate extends OFQueueProperty {
+    public static int MINIMUM_LENGTH = 16;
+
+    protected short rate;
+
+    /**
+     * 
+     */
+    public OFQueuePropertyMinRate() {
+        super();
+        this.type = OFQueuePropertyType.MIN_RATE;
+        this.length = U16.t(MINIMUM_LENGTH);
+    }
+
+    /**
+     * @return the rate
+     */
+    public short getRate() {
+        return rate;
+    }
+
+    /**
+     * @param rate the rate to set
+     */
+    public OFQueuePropertyMinRate setRate(short rate) {
+        this.rate = rate;
+        return this;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        super.readFrom(data);
+        this.rate = data.getShort();
+        data.getInt(); // pad
+        data.getShort(); // pad
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        super.writeTo(data);
+        data.putShort(this.rate);
+        data.putInt(0); // pad
+        data.putShort((short) 0); // pad
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 3259;
+        int result = super.hashCode();
+        result = prime * result + rate;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!super.equals(obj))
+            return false;
+        if (!(obj instanceof OFQueuePropertyMinRate))
+            return false;
+        OFQueuePropertyMinRate other = (OFQueuePropertyMinRate) obj;
+        if (rate != other.rate)
+            return false;
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "OFQueuePropertyMinRate [type=" + type + ", rate=" + U16.f(rate) + "]";
+    }
+
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/queue/OFQueuePropertyType.java b/third-party/openflowj/src/main/java/org/openflow/protocol/queue/OFQueuePropertyType.java
new file mode 100644 (file)
index 0000000..3174033
--- /dev/null
@@ -0,0 +1,143 @@
+/**
+ *
+ */
+package org.openflow.protocol.queue;
+
+import java.lang.reflect.Constructor;
+
+import org.openflow.protocol.Instantiable;
+
+/**
+ * List of OpenFlow Queue Property types and mappings to wire protocol value and
+ * derived classes
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFQueuePropertyType {
+    public static OFQueuePropertyType NONE = new OFQueuePropertyType(0, "NONE",
+            OFQueueProperty.class, new Instantiable<OFQueueProperty>() {
+                @Override
+                public OFQueueProperty instantiate() {
+                    return new OFQueueProperty();
+                }
+            });
+
+    public static OFQueuePropertyType MIN_RATE = new OFQueuePropertyType(1, "MIN_RATE",
+            OFQueuePropertyMinRate.class, new Instantiable<OFQueueProperty>() {
+                @Override
+                public OFQueueProperty instantiate() {
+                    return new OFQueuePropertyMinRate();
+                }
+            });
+
+    protected static OFQueuePropertyType[] mapping;
+
+    protected Class<? extends OFQueueProperty> clazz;
+    protected Constructor<? extends OFQueueProperty> constructor;
+    protected Instantiable<OFQueueProperty> instantiable;
+    protected int minLen;
+    protected String name;
+    protected short type;
+
+    /**
+     * Store some information about the OpenFlow Queue Property type, including wire
+     * protocol type number, length, and derived class
+     *
+     * @param type Wire protocol number associated with this OFQueuePropertyType
+     * @param name The name of this type
+     * @param clazz The Java class corresponding to this type of OpenFlow Queue Property
+     * @param instantiable the instantiable for the OFQueueProperty this type represents
+     */
+    OFQueuePropertyType(int type, String name, Class<? extends OFQueueProperty> clazz, Instantiable<OFQueueProperty> instantiable) {
+        this.type = (short) type;
+        this.name = name;
+        this.clazz = clazz;
+        this.instantiable = instantiable;
+        try {
+            this.constructor = clazz.getConstructor(new Class[]{});
+        } catch (Exception e) {
+            throw new RuntimeException(
+                    "Failure getting constructor for class: " + clazz, e);
+        }
+        OFQueuePropertyType.addMapping(this.type, this);
+    }
+
+    /**
+     * Adds a mapping from type value to OFQueuePropertyType enum
+     *
+     * @param i OpenFlow wire protocol Action type value
+     * @param t type
+     */
+    static public void addMapping(short i, OFQueuePropertyType t) {
+        if (mapping == null)
+            mapping = new OFQueuePropertyType[16];
+        OFQueuePropertyType.mapping[i] = t;
+    }
+
+    /**
+     * Given a wire protocol OpenFlow type number, return the OFType associated
+     * with it
+     *
+     * @param i wire protocol number
+     * @return OFType enum type
+     */
+
+    static public OFQueuePropertyType valueOf(short i) {
+        return OFQueuePropertyType.mapping[i];
+    }
+
+    /**
+     * @return Returns the wire protocol value corresponding to this
+     *         OFQueuePropertyType
+     */
+    public short getTypeValue() {
+        return this.type;
+    }
+
+    /**
+     * @return return the OFQueueProperty subclass corresponding to this OFQueuePropertyType
+     */
+    public Class<? extends OFQueueProperty> toClass() {
+        return clazz;
+    }
+
+    /**
+     * Returns the no-argument Constructor of the implementation class for
+     * this OFQueuePropertyType
+     * @return the constructor
+     */
+    public Constructor<? extends OFQueueProperty> getConstructor() {
+        return constructor;
+    }
+
+    /**
+     * Returns a new instance of the OFQueueProperty represented by this OFQueuePropertyType
+     * @return the new object
+     */
+    public OFQueueProperty newInstance() {
+        return instantiable.instantiate();
+    }
+
+    /**
+     * @return the instantiable
+     */
+    public Instantiable<OFQueueProperty> getInstantiable() {
+        return instantiable;
+    }
+
+    /**
+     * @param instantiable the instantiable to set
+     */
+    public void setInstantiable(Instantiable<OFQueueProperty> instantiable) {
+        this.instantiable = instantiable;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFAggregateStatisticsReply.java b/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFAggregateStatisticsReply.java
new file mode 100644 (file)
index 0000000..50ecf9d
--- /dev/null
@@ -0,0 +1,110 @@
+package org.openflow.protocol.statistics;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Represents an ofp_aggregate_stats_reply structure
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFAggregateStatisticsReply implements OFStatistics {
+    protected long packetCount;
+    protected long byteCount;
+    protected int flowCount;
+
+    /**
+     * @return the packetCount
+     */
+    public long getPacketCount() {
+        return packetCount;
+    }
+
+    /**
+     * @param packetCount the packetCount to set
+     */
+    public void setPacketCount(long packetCount) {
+        this.packetCount = packetCount;
+    }
+
+    /**
+     * @return the byteCount
+     */
+    public long getByteCount() {
+        return byteCount;
+    }
+
+    /**
+     * @param byteCount the byteCount to set
+     */
+    public void setByteCount(long byteCount) {
+        this.byteCount = byteCount;
+    }
+
+    /**
+     * @return the flowCount
+     */
+    public int getFlowCount() {
+        return flowCount;
+    }
+
+    /**
+     * @param flowCount the flowCount to set
+     */
+    public void setFlowCount(int flowCount) {
+        this.flowCount = flowCount;
+    }
+
+    @Override
+    public int getLength() {
+        return 24;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        this.packetCount = data.getLong();
+        this.byteCount = data.getLong();
+        this.flowCount = data.getInt();
+        data.getInt(); // pad
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        data.putLong(this.packetCount);
+        data.putLong(this.byteCount);
+        data.putInt(this.flowCount);
+        data.putInt(0); // pad
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 397;
+        int result = 1;
+        result = prime * result + (int) (byteCount ^ (byteCount >>> 32));
+        result = prime * result + flowCount;
+        result = prime * result + (int) (packetCount ^ (packetCount >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFAggregateStatisticsReply)) {
+            return false;
+        }
+        OFAggregateStatisticsReply other = (OFAggregateStatisticsReply) obj;
+        if (byteCount != other.byteCount) {
+            return false;
+        }
+        if (flowCount != other.flowCount) {
+            return false;
+        }
+        if (packetCount != other.packetCount) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFAggregateStatisticsRequest.java b/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFAggregateStatisticsRequest.java
new file mode 100644 (file)
index 0000000..4b23254
--- /dev/null
@@ -0,0 +1,118 @@
+package org.openflow.protocol.statistics;
+
+import java.nio.ByteBuffer;
+
+import org.openflow.protocol.OFMatch;
+
+/**
+ * Represents an ofp_aggregate_stats_request structure
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFAggregateStatisticsRequest implements OFStatistics {
+    protected OFMatch match;
+    protected byte tableId;
+    protected short outPort;
+
+    /**
+     * @return the match
+     */
+    public OFMatch getMatch() {
+        return match;
+    }
+
+    /**
+     * @param match the match to set
+     */
+    public void setMatch(OFMatch match) {
+        this.match = match;
+    }
+
+    /**
+     * @return the tableId
+     */
+    public byte getTableId() {
+        return tableId;
+    }
+
+    /**
+     * @param tableId the tableId to set
+     */
+    public void setTableId(byte tableId) {
+        this.tableId = tableId;
+    }
+
+    /**
+     * @return the outPort
+     */
+    public short getOutPort() {
+        return outPort;
+    }
+
+    /**
+     * @param outPort the outPort to set
+     */
+    public void setOutPort(short outPort) {
+        this.outPort = outPort;
+    }
+
+    @Override
+    public int getLength() {
+        return 44;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        if (this.match == null)
+            this.match = new OFMatch();
+        this.match.readFrom(data);
+        this.tableId = data.get();
+        data.get(); // pad
+        this.outPort = data.getShort();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        this.match.writeTo(data);
+        data.put(this.tableId);
+        data.put((byte) 0);
+        data.putShort(this.outPort);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 401;
+        int result = 1;
+        result = prime * result + ((match == null) ? 0 : match.hashCode());
+        result = prime * result + outPort;
+        result = prime * result + tableId;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFAggregateStatisticsRequest)) {
+            return false;
+        }
+        OFAggregateStatisticsRequest other = (OFAggregateStatisticsRequest) obj;
+        if (match == null) {
+            if (other.match != null) {
+                return false;
+            }
+        } else if (!match.equals(other.match)) {
+            return false;
+        }
+        if (outPort != other.outPort) {
+            return false;
+        }
+        if (tableId != other.tableId) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFDescriptionStatistics.java b/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFDescriptionStatistics.java
new file mode 100644 (file)
index 0000000..7e52c75
--- /dev/null
@@ -0,0 +1,202 @@
+package org.openflow.protocol.statistics;
+
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+
+import org.openflow.util.StringByteSerializer;
+
+/**
+ * Represents an ofp_desc_stats structure
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFDescriptionStatistics implements OFStatistics, Serializable {
+    public static int DESCRIPTION_STRING_LENGTH = 256;
+    public static int SERIAL_NUMBER_LENGTH = 32;
+
+    protected String manufacturerDescription;
+    protected String hardwareDescription;
+    protected String softwareDescription;
+    protected String serialNumber;
+    protected String datapathDescription;
+
+    /**
+     * @return the manufacturerDescription
+     */
+    public String getManufacturerDescription() {
+        return manufacturerDescription;
+    }
+
+    /**
+     * @param manufacturerDescription the manufacturerDescription to set
+     */
+    public void setManufacturerDescription(String manufacturerDescription) {
+        this.manufacturerDescription = manufacturerDescription;
+    }
+
+    /**
+     * @return the hardwareDescription
+     */
+    public String getHardwareDescription() {
+        return hardwareDescription;
+    }
+
+    /**
+     * @param hardwareDescription the hardwareDescription to set
+     */
+    public void setHardwareDescription(String hardwareDescription) {
+        this.hardwareDescription = hardwareDescription;
+    }
+
+    /**
+     * @return the softwareDescription
+     */
+    public String getSoftwareDescription() {
+        return softwareDescription;
+    }
+
+    /**
+     * @param softwareDescription the softwareDescription to set
+     */
+    public void setSoftwareDescription(String softwareDescription) {
+        this.softwareDescription = softwareDescription;
+    }
+
+    /**
+     * @return the serialNumber
+     */
+    public String getSerialNumber() {
+       if (serialNumber.equals("None"))
+               return "";
+        return serialNumber;
+    }
+
+    /**
+     * @param serialNumber the serialNumber to set
+     */
+    public void setSerialNumber(String serialNumber) {
+        this.serialNumber = serialNumber;
+    }
+
+    /**
+     * @return the datapathDescription
+     */
+    public String getDatapathDescription() {
+        return datapathDescription;
+    }
+
+    /**
+     * @param datapathDescription the datapathDescription to set
+     */
+    public void setDatapathDescription(String datapathDescription) {
+        this.datapathDescription = datapathDescription;
+    }
+
+    @Override
+    public int getLength() {
+        return 1056;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        this.manufacturerDescription = StringByteSerializer.readFrom(data,
+                DESCRIPTION_STRING_LENGTH);
+        this.hardwareDescription = StringByteSerializer.readFrom(data,
+                DESCRIPTION_STRING_LENGTH);
+        this.softwareDescription = StringByteSerializer.readFrom(data,
+                DESCRIPTION_STRING_LENGTH);
+        this.serialNumber = StringByteSerializer.readFrom(data,
+                SERIAL_NUMBER_LENGTH);
+        this.datapathDescription = StringByteSerializer.readFrom(data,
+                DESCRIPTION_STRING_LENGTH);
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        StringByteSerializer.writeTo(data, DESCRIPTION_STRING_LENGTH,
+                this.manufacturerDescription);
+        StringByteSerializer.writeTo(data, DESCRIPTION_STRING_LENGTH,
+                this.hardwareDescription);
+        StringByteSerializer.writeTo(data, DESCRIPTION_STRING_LENGTH,
+                this.softwareDescription);
+        StringByteSerializer.writeTo(data, SERIAL_NUMBER_LENGTH,
+                this.serialNumber);
+        StringByteSerializer.writeTo(data, DESCRIPTION_STRING_LENGTH,
+                this.datapathDescription);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 409;
+        int result = 1;
+        result = prime
+                * result
+                + ((datapathDescription == null) ? 0 : datapathDescription
+                        .hashCode());
+        result = prime
+                * result
+                + ((hardwareDescription == null) ? 0 : hardwareDescription
+                        .hashCode());
+        result = prime
+                * result
+                + ((manufacturerDescription == null) ? 0
+                        : manufacturerDescription.hashCode());
+        result = prime * result
+                + ((serialNumber == null) ? 0 : serialNumber.hashCode());
+        result = prime
+                * result
+                + ((softwareDescription == null) ? 0 : softwareDescription
+                        .hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFDescriptionStatistics)) {
+            return false;
+        }
+        OFDescriptionStatistics other = (OFDescriptionStatistics) obj;
+        if (datapathDescription == null) {
+            if (other.datapathDescription != null) {
+                return false;
+            }
+        } else if (!datapathDescription.equals(other.datapathDescription)) {
+            return false;
+        }
+        if (hardwareDescription == null) {
+            if (other.hardwareDescription != null) {
+                return false;
+            }
+        } else if (!hardwareDescription.equals(other.hardwareDescription)) {
+            return false;
+        }
+        if (manufacturerDescription == null) {
+            if (other.manufacturerDescription != null) {
+                return false;
+            }
+        } else if (!manufacturerDescription
+                .equals(other.manufacturerDescription)) {
+            return false;
+        }
+        if (serialNumber == null) {
+            if (other.serialNumber != null) {
+                return false;
+            }
+        } else if (!serialNumber.equals(other.serialNumber)) {
+            return false;
+        }
+        if (softwareDescription == null) {
+            if (other.softwareDescription != null) {
+                return false;
+            }
+        } else if (!softwareDescription.equals(other.softwareDescription)) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFFlowStatisticsReply.java b/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFFlowStatisticsReply.java
new file mode 100644 (file)
index 0000000..ed6f4e6
--- /dev/null
@@ -0,0 +1,324 @@
+package org.openflow.protocol.statistics;
+
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.openflow.protocol.OFMatch;
+import org.openflow.protocol.action.OFAction;
+import org.openflow.protocol.factory.OFActionFactory;
+import org.openflow.protocol.factory.OFActionFactoryAware;
+import org.openflow.util.U16;
+
+/**
+ * Represents an ofp_flow_stats structure
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFFlowStatisticsReply implements OFStatistics, OFActionFactoryAware, Serializable {
+    public static int MINIMUM_LENGTH = 88;
+
+    protected transient OFActionFactory actionFactory;
+    protected short length = (short) MINIMUM_LENGTH;
+    protected byte tableId;
+    protected OFMatch match;
+    protected int durationSeconds;
+    protected int durationNanoseconds;
+    protected short priority;
+    protected short idleTimeout;
+    protected short hardTimeout;
+    protected long cookie;
+    protected long packetCount;
+    protected long byteCount;
+    protected List<OFAction> actions;
+
+    /**
+     * @return the tableId
+     */
+    public byte getTableId() {
+        return tableId;
+    }
+
+    /**
+     * @param tableId the tableId to set
+     */
+    public void setTableId(byte tableId) {
+        this.tableId = tableId;
+    }
+
+    /**
+     * @return the match
+     */
+    public OFMatch getMatch() {
+        return match;
+    }
+
+    /**
+     * @param match the match to set
+     */
+    public void setMatch(OFMatch match) {
+        this.match = match;
+    }
+
+    /**
+     * @return the durationSeconds
+     */
+    public int getDurationSeconds() {
+        return durationSeconds;
+    }
+
+    /**
+     * @param durationSeconds the durationSeconds to set
+     */
+    public void setDurationSeconds(int durationSeconds) {
+        this.durationSeconds = durationSeconds;
+    }
+
+    /**
+     * @return the durationNanoseconds
+     */
+    public int getDurationNanoseconds() {
+        return durationNanoseconds;
+    }
+
+    /**
+     * @param durationNanoseconds the durationNanoseconds to set
+     */
+    public void setDurationNanoseconds(int durationNanoseconds) {
+        this.durationNanoseconds = durationNanoseconds;
+    }
+
+    /**
+     * @return the priority
+     */
+    public short getPriority() {
+        return priority;
+    }
+
+    /**
+     * @param priority the priority to set
+     */
+    public void setPriority(short priority) {
+        this.priority = priority;
+    }
+
+    /**
+     * @return the idleTimeout
+     */
+    public short getIdleTimeout() {
+        return idleTimeout;
+    }
+
+    /**
+     * @param idleTimeout the idleTimeout to set
+     */
+    public void setIdleTimeout(short idleTimeout) {
+        this.idleTimeout = idleTimeout;
+    }
+
+    /**
+     * @return the hardTimeout
+     */
+    public short getHardTimeout() {
+        return hardTimeout;
+    }
+
+    /**
+     * @param hardTimeout the hardTimeout to set
+     */
+    public void setHardTimeout(short hardTimeout) {
+        this.hardTimeout = hardTimeout;
+    }
+
+    /**
+     * @return the cookie
+     */
+    public long getCookie() {
+        return cookie;
+    }
+
+    /**
+     * @param cookie the cookie to set
+     */
+    public void setCookie(long cookie) {
+        this.cookie = cookie;
+    }
+
+    /**
+     * @return the packetCount
+     */
+    public long getPacketCount() {
+        return packetCount;
+    }
+
+    /**
+     * @param packetCount the packetCount to set
+     */
+    public void setPacketCount(long packetCount) {
+        this.packetCount = packetCount;
+    }
+
+    /**
+     * @return the byteCount
+     */
+    public long getByteCount() {
+        return byteCount;
+    }
+
+    /**
+     * @param byteCount the byteCount to set
+     */
+    public void setByteCount(long byteCount) {
+        this.byteCount = byteCount;
+    }
+
+    /**
+     * @param length the length to set
+     */
+    public void setLength(short length) {
+        this.length = length;
+    }
+
+    @Override
+    public int getLength() {
+        return U16.f(length);
+    }
+
+    /**
+     * @param actionFactory the actionFactory to set
+     */
+    @Override
+    public void setActionFactory(OFActionFactory actionFactory) {
+        this.actionFactory = actionFactory;
+    }
+
+    /**
+     * @return the actions
+     */
+    public List<OFAction> getActions() {
+        return actions;
+    }
+
+    /**
+     * @param actions the actions to set
+     */
+    public void setActions(List<OFAction> actions) {
+        this.actions = actions;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        this.length = data.getShort();
+        this.tableId = data.get();
+        data.get(); // pad
+        if (this.match == null)
+            this.match = new OFMatch();
+        this.match.readFrom(data);
+        this.durationSeconds = data.getInt();
+        this.durationNanoseconds = data.getInt();
+        this.priority = data.getShort();
+        this.idleTimeout = data.getShort();
+        this.hardTimeout = data.getShort();
+        data.getInt(); // pad
+        data.getShort(); // pad
+        this.cookie = data.getLong();
+        this.packetCount = data.getLong();
+        this.byteCount = data.getLong();
+        if (this.actionFactory == null)
+            throw new RuntimeException("OFActionFactory not set");
+        this.actions = this.actionFactory.parseActions(data, getLength() -
+                MINIMUM_LENGTH);
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        data.putShort(this.length);
+        data.put(this.tableId);
+        data.put((byte) 0);
+        this.match.writeTo(data);
+        data.putInt(this.durationSeconds);
+        data.putInt(this.durationNanoseconds);
+        data.putShort(this.priority);
+        data.putShort(this.idleTimeout);
+        data.putShort(this.hardTimeout);
+        data.getInt(); // pad
+        data.getShort(); // pad
+        data.putLong(this.cookie);
+        data.putLong(this.packetCount);
+        data.putLong(this.byteCount);
+        if (actions != null) {
+            for (OFAction action : actions) {
+                action.writeTo(data);
+            }
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 419;
+        int result = 1;
+        result = prime * result + (int) (byteCount ^ (byteCount >>> 32));
+        result = prime * result + (int) (cookie ^ (cookie >>> 32));
+        result = prime * result + durationNanoseconds;
+        result = prime * result + durationSeconds;
+        result = prime * result + hardTimeout;
+        result = prime * result + idleTimeout;
+        result = prime * result + length;
+        result = prime * result + ((match == null) ? 0 : match.hashCode());
+        result = prime * result + (int) (packetCount ^ (packetCount >>> 32));
+        result = prime * result + priority;
+        result = prime * result + tableId;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFFlowStatisticsReply)) {
+            return false;
+        }
+        OFFlowStatisticsReply other = (OFFlowStatisticsReply) obj;
+        if (byteCount != other.byteCount) {
+            return false;
+        }
+        if (cookie != other.cookie) {
+            return false;
+        }
+        if (durationNanoseconds != other.durationNanoseconds) {
+            return false;
+        }
+        if (durationSeconds != other.durationSeconds) {
+            return false;
+        }
+        if (hardTimeout != other.hardTimeout) {
+            return false;
+        }
+        if (idleTimeout != other.idleTimeout) {
+            return false;
+        }
+        if (length != other.length) {
+            return false;
+        }
+        if (match == null) {
+            if (other.match != null) {
+                return false;
+            }
+        } else if (!match.equals(other.match)) {
+            return false;
+        }
+        if (packetCount != other.packetCount) {
+            return false;
+        }
+        if (priority != other.priority) {
+            return false;
+        }
+        if (tableId != other.tableId) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFFlowStatisticsRequest.java b/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFFlowStatisticsRequest.java
new file mode 100644 (file)
index 0000000..fd70ed5
--- /dev/null
@@ -0,0 +1,119 @@
+package org.openflow.protocol.statistics;
+
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+
+import org.openflow.protocol.OFMatch;
+
+/**
+ * Represents an ofp_flow_stats_request structure
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFFlowStatisticsRequest implements OFStatistics, Serializable {
+    protected OFMatch match;
+    protected byte tableId;
+    protected short outPort;
+
+    /**
+     * @return the match
+     */
+    public OFMatch getMatch() {
+        return match;
+    }
+
+    /**
+     * @param match the match to set
+     */
+    public void setMatch(OFMatch match) {
+        this.match = match;
+    }
+
+    /**
+     * @return the tableId
+     */
+    public byte getTableId() {
+        return tableId;
+    }
+
+    /**
+     * @param tableId the tableId to set
+     */
+    public void setTableId(byte tableId) {
+        this.tableId = tableId;
+    }
+
+    /**
+     * @return the outPort
+     */
+    public short getOutPort() {
+        return outPort;
+    }
+
+    /**
+     * @param outPort the outPort to set
+     */
+    public void setOutPort(short outPort) {
+        this.outPort = outPort;
+    }
+
+    @Override
+    public int getLength() {
+        return 44;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        if (this.match == null)
+            this.match = new OFMatch();
+        this.match.readFrom(data);
+        this.tableId = data.get();
+        data.get(); // pad
+        this.outPort = data.getShort();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        this.match.writeTo(data);
+        data.put(this.tableId);
+        data.put((byte) 0);
+        data.putShort(this.outPort);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 421;
+        int result = 1;
+        result = prime * result + ((match == null) ? 0 : match.hashCode());
+        result = prime * result + outPort;
+        result = prime * result + tableId;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFFlowStatisticsRequest)) {
+            return false;
+        }
+        OFFlowStatisticsRequest other = (OFFlowStatisticsRequest) obj;
+        if (match == null) {
+            if (other.match != null) {
+                return false;
+            }
+        } else if (!match.equals(other.match)) {
+            return false;
+        }
+        if (outPort != other.outPort) {
+            return false;
+        }
+        if (tableId != other.tableId) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java b/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java
new file mode 100644 (file)
index 0000000..fa45814
--- /dev/null
@@ -0,0 +1,332 @@
+package org.openflow.protocol.statistics;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Represents an ofp_port_stats structure
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFPortStatisticsReply implements OFStatistics {
+    protected short portNumber;
+    protected long receivePackets;
+    protected long transmitPackets;
+    protected long receiveBytes;
+    protected long transmitBytes;
+    protected long receiveDropped;
+    protected long transmitDropped;
+    protected long receiveErrors;
+    protected long transmitErrors;
+    protected long receiveFrameErrors;
+    protected long receiveOverrunErrors;
+    protected long receiveCRCErrors;
+    protected long collisions;
+
+    /**
+     * @return the portNumber
+     */
+    public short getPortNumber() {
+        return portNumber;
+    }
+
+    /**
+     * @param portNumber the portNumber to set
+     */
+    public void setPortNumber(short portNumber) {
+        this.portNumber = portNumber;
+    }
+
+    /**
+     * @return the receivePackets
+     */
+    public long getreceivePackets() {
+        return receivePackets;
+    }
+
+    /**
+     * @param receivePackets the receivePackets to set
+     */
+    public void setreceivePackets(long receivePackets) {
+        this.receivePackets = receivePackets;
+    }
+
+    /**
+     * @return the transmitPackets
+     */
+    public long getTransmitPackets() {
+        return transmitPackets;
+    }
+
+    /**
+     * @param transmitPackets the transmitPackets to set
+     */
+    public void setTransmitPackets(long transmitPackets) {
+        this.transmitPackets = transmitPackets;
+    }
+
+    /**
+     * @return the receiveBytes
+     */
+    public long getReceiveBytes() {
+        return receiveBytes;
+    }
+
+    /**
+     * @param receiveBytes the receiveBytes to set
+     */
+    public void setReceiveBytes(long receiveBytes) {
+        this.receiveBytes = receiveBytes;
+    }
+
+    /**
+     * @return the transmitBytes
+     */
+    public long getTransmitBytes() {
+        return transmitBytes;
+    }
+
+    /**
+     * @param transmitBytes the transmitBytes to set
+     */
+    public void setTransmitBytes(long transmitBytes) {
+        this.transmitBytes = transmitBytes;
+    }
+
+    /**
+     * @return the receiveDropped
+     */
+    public long getReceiveDropped() {
+        return receiveDropped;
+    }
+
+    /**
+     * @param receiveDropped the receiveDropped to set
+     */
+    public void setReceiveDropped(long receiveDropped) {
+        this.receiveDropped = receiveDropped;
+    }
+
+    /**
+     * @return the transmitDropped
+     */
+    public long getTransmitDropped() {
+        return transmitDropped;
+    }
+
+    /**
+     * @param transmitDropped the transmitDropped to set
+     */
+    public void setTransmitDropped(long transmitDropped) {
+        this.transmitDropped = transmitDropped;
+    }
+
+    /**
+     * @return the receiveErrors
+     */
+    public long getreceiveErrors() {
+        return receiveErrors;
+    }
+
+    /**
+     * @param receiveErrors the receiveErrors to set
+     */
+    public void setreceiveErrors(long receiveErrors) {
+        this.receiveErrors = receiveErrors;
+    }
+
+    /**
+     * @return the transmitErrors
+     */
+    public long getTransmitErrors() {
+        return transmitErrors;
+    }
+
+    /**
+     * @param transmitErrors the transmitErrors to set
+     */
+    public void setTransmitErrors(long transmitErrors) {
+        this.transmitErrors = transmitErrors;
+    }
+
+    /**
+     * @return the receiveFrameErrors
+     */
+    public long getReceiveFrameErrors() {
+        return receiveFrameErrors;
+    }
+
+    /**
+     * @param receiveFrameErrors the receiveFrameErrors to set
+     */
+    public void setReceiveFrameErrors(long receiveFrameErrors) {
+        this.receiveFrameErrors = receiveFrameErrors;
+    }
+
+    /**
+     * @return the receiveOverrunErrors
+     */
+    public long getReceiveOverrunErrors() {
+        return receiveOverrunErrors;
+    }
+
+    /**
+     * @param receiveOverrunErrors the receiveOverrunErrors to set
+     */
+    public void setReceiveOverrunErrors(long receiveOverrunErrors) {
+        this.receiveOverrunErrors = receiveOverrunErrors;
+    }
+
+    /**
+     * @return the receiveCRCErrors
+     */
+    public long getReceiveCRCErrors() {
+        return receiveCRCErrors;
+    }
+
+    /**
+     * @param receiveCRCErrors the receiveCRCErrors to set
+     */
+    public void setReceiveCRCErrors(long receiveCRCErrors) {
+        this.receiveCRCErrors = receiveCRCErrors;
+    }
+
+    /**
+     * @return the collisions
+     */
+    public long getCollisions() {
+        return collisions;
+    }
+
+    /**
+     * @param collisions the collisions to set
+     */
+    public void setCollisions(long collisions) {
+        this.collisions = collisions;
+    }
+
+    @Override
+    public int getLength() {
+        return 104;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        this.portNumber = data.getShort();
+        data.getShort(); // pad
+        data.getInt(); // pad
+        this.receivePackets = data.getLong();
+        this.transmitPackets = data.getLong();
+        this.receiveBytes = data.getLong();
+        this.transmitBytes = data.getLong();
+        this.receiveDropped = data.getLong();
+        this.transmitDropped = data.getLong();
+        this.receiveErrors = data.getLong();
+        this.transmitErrors = data.getLong();
+        this.receiveFrameErrors = data.getLong();
+        this.receiveOverrunErrors = data.getLong();
+        this.receiveCRCErrors = data.getLong();
+        this.collisions = data.getLong();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        data.putShort(this.portNumber);
+        data.putShort((short) 0); // pad
+        data.putInt(0); // pad
+        data.putLong(this.receivePackets);
+        data.putLong(this.transmitPackets);
+        data.putLong(this.receiveBytes);
+        data.putLong(this.transmitBytes);
+        data.putLong(this.receiveDropped);
+        data.putLong(this.transmitDropped);
+        data.putLong(this.receiveErrors);
+        data.putLong(this.transmitErrors);
+        data.putLong(this.receiveFrameErrors);
+        data.putLong(this.receiveOverrunErrors);
+        data.putLong(this.receiveCRCErrors);
+        data.putLong(this.collisions);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 431;
+        int result = 1;
+        result = prime * result + (int) (collisions ^ (collisions >>> 32));
+        result = prime * result + portNumber;
+        result = prime * result
+                + (int) (receivePackets ^ (receivePackets >>> 32));
+        result = prime * result + (int) (receiveBytes ^ (receiveBytes >>> 32));
+        result = prime * result
+                + (int) (receiveCRCErrors ^ (receiveCRCErrors >>> 32));
+        result = prime * result
+                + (int) (receiveDropped ^ (receiveDropped >>> 32));
+        result = prime * result
+                + (int) (receiveFrameErrors ^ (receiveFrameErrors >>> 32));
+        result = prime * result
+                + (int) (receiveOverrunErrors ^ (receiveOverrunErrors >>> 32));
+        result = prime * result
+                + (int) (receiveErrors ^ (receiveErrors >>> 32));
+        result = prime * result
+                + (int) (transmitBytes ^ (transmitBytes >>> 32));
+        result = prime * result
+                + (int) (transmitDropped ^ (transmitDropped >>> 32));
+        result = prime * result
+                + (int) (transmitErrors ^ (transmitErrors >>> 32));
+        result = prime * result
+                + (int) (transmitPackets ^ (transmitPackets >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFPortStatisticsReply)) {
+            return false;
+        }
+        OFPortStatisticsReply other = (OFPortStatisticsReply) obj;
+        if (collisions != other.collisions) {
+            return false;
+        }
+        if (portNumber != other.portNumber) {
+            return false;
+        }
+        if (receivePackets != other.receivePackets) {
+            return false;
+        }
+        if (receiveBytes != other.receiveBytes) {
+            return false;
+        }
+        if (receiveCRCErrors != other.receiveCRCErrors) {
+            return false;
+        }
+        if (receiveDropped != other.receiveDropped) {
+            return false;
+        }
+        if (receiveFrameErrors != other.receiveFrameErrors) {
+            return false;
+        }
+        if (receiveOverrunErrors != other.receiveOverrunErrors) {
+            return false;
+        }
+        if (receiveErrors != other.receiveErrors) {
+            return false;
+        }
+        if (transmitBytes != other.transmitBytes) {
+            return false;
+        }
+        if (transmitDropped != other.transmitDropped) {
+            return false;
+        }
+        if (transmitErrors != other.transmitErrors) {
+            return false;
+        }
+        if (transmitPackets != other.transmitPackets) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsRequest.java b/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsRequest.java
new file mode 100644 (file)
index 0000000..f3de700
--- /dev/null
@@ -0,0 +1,70 @@
+package org.openflow.protocol.statistics;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Represents an ofp_port_stats_request structure
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFPortStatisticsRequest implements OFStatistics {
+    protected short portNumber;
+
+    /**
+     * @return the portNumber
+     */
+    public short getPortNumber() {
+        return portNumber;
+    }
+
+    /**
+     * @param portNumber the portNumber to set
+     */
+    public void setPortNumber(short portNumber) {
+        this.portNumber = portNumber;
+    }
+
+    @Override
+    public int getLength() {
+        return 8;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        this.portNumber = data.getShort();
+        data.getShort(); // pad
+        data.getInt(); // pad
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        data.putShort(this.portNumber);
+        data.putShort((short) 0); // pad
+        data.putInt(0); // pad
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 433;
+        int result = 1;
+        result = prime * result + portNumber;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFPortStatisticsRequest)) {
+            return false;
+        }
+        OFPortStatisticsRequest other = (OFPortStatisticsRequest) obj;
+        if (portNumber != other.portNumber) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFQueueStatisticsReply.java b/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFQueueStatisticsReply.java
new file mode 100644 (file)
index 0000000..5b1a339
--- /dev/null
@@ -0,0 +1,155 @@
+package org.openflow.protocol.statistics;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Represents an ofp_queue_stats structure
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFQueueStatisticsReply implements OFStatistics {
+    protected short portNumber;
+    protected int queueId;
+    protected long transmitBytes;
+    protected long transmitPackets;
+    protected long transmitErrors;
+
+    /**
+     * @return the portNumber
+     */
+    public short getPortNumber() {
+        return portNumber;
+    }
+
+    /**
+     * @param portNumber the portNumber to set
+     */
+    public void setPortNumber(short portNumber) {
+        this.portNumber = portNumber;
+    }
+
+    /**
+     * @return the queueId
+     */
+    public int getQueueId() {
+        return queueId;
+    }
+
+    /**
+     * @param queueId the queueId to set
+     */
+    public void setQueueId(int queueId) {
+        this.queueId = queueId;
+    }
+
+    /**
+     * @return the transmitBytes
+     */
+    public long getTransmitBytes() {
+        return transmitBytes;
+    }
+
+    /**
+     * @param transmitBytes the transmitBytes to set
+     */
+    public void setTransmitBytes(long transmitBytes) {
+        this.transmitBytes = transmitBytes;
+    }
+
+    /**
+     * @return the transmitPackets
+     */
+    public long getTransmitPackets() {
+        return transmitPackets;
+    }
+
+    /**
+     * @param transmitPackets the transmitPackets to set
+     */
+    public void setTransmitPackets(long transmitPackets) {
+        this.transmitPackets = transmitPackets;
+    }
+
+    /**
+     * @return the transmitErrors
+     */
+    public long getTransmitErrors() {
+        return transmitErrors;
+    }
+
+    /**
+     * @param transmitErrors the transmitErrors to set
+     */
+    public void setTransmitErrors(long transmitErrors) {
+        this.transmitErrors = transmitErrors;
+    }
+
+    @Override
+    public int getLength() {
+        return 32;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        this.portNumber = data.getShort();
+        data.getShort(); // pad
+        this.queueId = data.getInt();
+        this.transmitBytes = data.getLong();
+        this.transmitPackets = data.getLong();
+        this.transmitErrors = data.getLong();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        data.putShort(this.portNumber);
+        data.putShort((short) 0); // pad
+        data.putInt(this.queueId);
+        data.putLong(this.transmitBytes);
+        data.putLong(this.transmitPackets);
+        data.putLong(this.transmitErrors);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 439;
+        int result = 1;
+        result = prime * result + portNumber;
+        result = prime * result + queueId;
+        result = prime * result
+                + (int) (transmitBytes ^ (transmitBytes >>> 32));
+        result = prime * result
+                + (int) (transmitErrors ^ (transmitErrors >>> 32));
+        result = prime * result
+                + (int) (transmitPackets ^ (transmitPackets >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFQueueStatisticsReply)) {
+            return false;
+        }
+        OFQueueStatisticsReply other = (OFQueueStatisticsReply) obj;
+        if (portNumber != other.portNumber) {
+            return false;
+        }
+        if (queueId != other.queueId) {
+            return false;
+        }
+        if (transmitBytes != other.transmitBytes) {
+            return false;
+        }
+        if (transmitErrors != other.transmitErrors) {
+            return false;
+        }
+        if (transmitPackets != other.transmitPackets) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFQueueStatisticsRequest.java b/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFQueueStatisticsRequest.java
new file mode 100644 (file)
index 0000000..4317f3f
--- /dev/null
@@ -0,0 +1,89 @@
+package org.openflow.protocol.statistics;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Represents an ofp_queue_stats_request structure
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFQueueStatisticsRequest implements OFStatistics {
+    protected short portNumber;
+    protected int queueId;
+
+    /**
+     * @return the portNumber
+     */
+    public short getPortNumber() {
+        return portNumber;
+    }
+
+    /**
+     * @param portNumber the portNumber to set
+     */
+    public void setPortNumber(short portNumber) {
+        this.portNumber = portNumber;
+    }
+
+    /**
+     * @return the queueId
+     */
+    public int getQueueId() {
+        return queueId;
+    }
+
+    /**
+     * @param queueId the queueId to set
+     */
+    public void setQueueId(int queueId) {
+        this.queueId = queueId;
+    }
+
+    @Override
+    public int getLength() {
+        return 8;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        this.portNumber = data.getShort();
+        data.getShort(); // pad
+        this.queueId = data.getInt();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        data.putShort(this.portNumber);
+        data.putShort((short) 0); // pad
+        data.putInt(this.queueId);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 443;
+        int result = 1;
+        result = prime * result + portNumber;
+        result = prime * result + queueId;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFQueueStatisticsRequest)) {
+            return false;
+        }
+        OFQueueStatisticsRequest other = (OFQueueStatisticsRequest) obj;
+        if (portNumber != other.portNumber) {
+            return false;
+        }
+        if (queueId != other.queueId) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFStatistics.java b/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFStatistics.java
new file mode 100644 (file)
index 0000000..0893e17
--- /dev/null
@@ -0,0 +1,28 @@
+package org.openflow.protocol.statistics;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The base class for all OpenFlow statistics.
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
+ */
+public interface OFStatistics {
+    /**
+     * Returns the wire length of this message in bytes
+     * @return the length
+     */
+    public int getLength();
+
+    /**
+     * Read this message off the wire from the specified ByteBuffer
+     * @param data
+     */
+    public void readFrom(ByteBuffer data);
+
+    /**
+     * Write this message's binary format to the specified ByteBuffer
+     * @param data
+     */
+    public void writeTo(ByteBuffer data);
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFStatisticsType.java b/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFStatisticsType.java
new file mode 100644 (file)
index 0000000..d9e7030
--- /dev/null
@@ -0,0 +1,300 @@
+package org.openflow.protocol.statistics;
+
+import java.lang.reflect.Constructor;
+
+import org.openflow.protocol.Instantiable;
+import org.openflow.protocol.OFType;
+
+public enum OFStatisticsType {
+    DESC        (0, OFDescriptionStatistics.class, OFDescriptionStatistics.class,
+                    new Instantiable<OFStatistics>() {
+                        @Override
+                        public OFStatistics instantiate() {
+                            return new OFDescriptionStatistics();
+                        }
+                    },
+                    new Instantiable<OFStatistics>() {
+                        @Override
+                        public OFStatistics instantiate() {
+                            return new OFDescriptionStatistics();
+                        }
+                    }),
+    FLOW       (1, OFFlowStatisticsRequest.class, OFFlowStatisticsReply.class,
+                    new Instantiable<OFStatistics>() {
+                        @Override
+                        public OFStatistics instantiate() {
+                            return new OFFlowStatisticsRequest();
+                        }
+                    },
+                    new Instantiable<OFStatistics>() {
+                        @Override
+                        public OFStatistics instantiate() {
+                            return new OFFlowStatisticsReply();
+                        }
+                    }),
+    AGGREGATE  (2, OFAggregateStatisticsRequest.class, OFAggregateStatisticsReply.class,
+                    new Instantiable<OFStatistics>() {
+                        @Override
+                        public OFStatistics instantiate() {
+                            return new OFAggregateStatisticsRequest();
+                        }
+                    },
+                    new Instantiable<OFStatistics>() {
+                        @Override
+                        public OFStatistics instantiate() {
+                            return new OFAggregateStatisticsReply();
+                        }
+                    }),
+    TABLE      (3, OFTableStatistics.class, OFTableStatistics.class,
+                    new Instantiable<OFStatistics>() {
+                        @Override
+                        public OFStatistics instantiate() {
+                            return new OFTableStatistics();
+                        }
+                    },
+                    new Instantiable<OFStatistics>() {
+                        @Override
+                        public OFStatistics instantiate() {
+                            return new OFTableStatistics();
+                        }
+                    }),
+    PORT       (4, OFPortStatisticsRequest.class, OFPortStatisticsReply.class,
+                    new Instantiable<OFStatistics>() {
+                        @Override
+                        public OFStatistics instantiate() {
+                            return new OFPortStatisticsRequest();
+                        }
+                    },
+                    new Instantiable<OFStatistics>() {
+                        @Override
+                        public OFStatistics instantiate() {
+                            return new OFPortStatisticsReply();
+                        }
+                    }),
+    QUEUE      (5, OFQueueStatisticsRequest.class, OFQueueStatisticsReply.class,
+                    new Instantiable<OFStatistics>() {
+                        @Override
+                        public OFStatistics instantiate() {
+                            return new OFQueueStatisticsRequest();
+                        }
+                    },
+                    new Instantiable<OFStatistics>() {
+                        @Override
+                        public OFStatistics instantiate() {
+                            return new OFQueueStatisticsReply();
+                        }
+                    }),
+    VENDOR     (0xffff, OFVendorStatistics.class, OFVendorStatistics.class,
+                    new Instantiable<OFStatistics>() {
+                        @Override
+                        public OFStatistics instantiate() {
+                            return new OFVendorStatistics();
+                        }
+                    },
+                    new Instantiable<OFStatistics>() {
+                        @Override
+                        public OFStatistics instantiate() {
+                            return new OFVendorStatistics();
+                        }
+                    });
+
+    static OFStatisticsType[] requestMapping;
+    static OFStatisticsType[] replyMapping;
+
+    protected Class<? extends OFStatistics> requestClass;
+    protected Constructor<? extends OFStatistics> requestConstructor;
+    protected Instantiable<OFStatistics> requestInstantiable;
+    protected Class<? extends OFStatistics> replyClass;
+    protected Constructor<? extends OFStatistics> replyConstructor;
+    protected Instantiable<OFStatistics> replyInstantiable;
+    protected short type;
+
+    /**
+     * Store some information about the OpenFlow Statistic type, including wire
+     * protocol type number, and derived class
+     *
+     * @param type Wire protocol number associated with this OFStatisticsType
+     * @param requestClass The Statistics Java class to return when the
+     *                     containing OFType is STATS_REQUEST
+     * @param replyClass   The Statistics Java class to return when the
+     *                     containing OFType is STATS_REPLY
+     */
+    OFStatisticsType(int type, Class<? extends OFStatistics> requestClass,
+            Class<? extends OFStatistics> replyClass,
+            Instantiable<OFStatistics> requestInstantiable,
+            Instantiable<OFStatistics> replyInstantiable) {
+        this.type = (short) type;
+        this.requestClass = requestClass;
+        try {
+            this.requestConstructor = requestClass.getConstructor(new Class[]{});
+        } catch (Exception e) {
+            throw new RuntimeException(
+                    "Failure getting constructor for class: " + requestClass, e);
+        }
+
+        this.replyClass = replyClass;
+        try {
+            this.replyConstructor = replyClass.getConstructor(new Class[]{});
+        } catch (Exception e) {
+            throw new RuntimeException(
+                    "Failure getting constructor for class: " + replyClass, e);
+        }
+        this.requestInstantiable = requestInstantiable;
+        this.replyInstantiable = replyInstantiable;
+        OFStatisticsType.addMapping(this.type, OFType.STATS_REQUEST, this);
+        OFStatisticsType.addMapping(this.type, OFType.STATS_REPLY, this);
+    }
+
+    /**
+     * Adds a mapping from type value to OFStatisticsType enum
+     *
+     * @param i OpenFlow wire protocol type
+     * @param t type of containing OFMessage, only accepts STATS_REQUEST or
+     *          STATS_REPLY
+     * @param st type
+     */
+    static public void addMapping(short i, OFType t, OFStatisticsType st) {
+        if (i < 0)
+            i = (short) (16+i);
+        if (t == OFType.STATS_REQUEST) {
+            if (requestMapping == null)
+                requestMapping = new OFStatisticsType[16];
+            OFStatisticsType.requestMapping[i] = st;
+        } else if (t == OFType.STATS_REPLY){
+            if (replyMapping == null)
+                replyMapping = new OFStatisticsType[16];
+            OFStatisticsType.replyMapping[i] = st;
+        } else {
+            throw new RuntimeException(t.toString() + " is an invalid OFType");
+        }
+    }
+
+    /**
+     * Remove a mapping from type value to OFStatisticsType enum
+     *
+     * @param i OpenFlow wire protocol type
+     * @param t type of containing OFMessage, only accepts STATS_REQUEST or
+     *          STATS_REPLY
+     */
+    static public void removeMapping(short i, OFType t) {
+        if (i < 0)
+            i = (short) (16+i);
+        if (t == OFType.STATS_REQUEST) {
+            requestMapping[i] = null;
+        } else if (t == OFType.STATS_REPLY){
+            replyMapping[i] = null;
+        } else {
+            throw new RuntimeException(t.toString() + " is an invalid OFType");
+        }
+    }
+
+    /**
+     * Given a wire protocol OpenFlow type number, return the OFStatisticsType
+     * associated with it
+     *
+     * @param i wire protocol number
+     * @param t type of containing OFMessage, only accepts STATS_REQUEST or
+     *          STATS_REPLY
+     * @return OFStatisticsType enum type
+     */
+    static public OFStatisticsType valueOf(short i, OFType t) {
+        if (i < 0)
+            i = (short) (16+i);
+        if (t == OFType.STATS_REQUEST) {
+            return requestMapping[i];
+        } else if (t == OFType.STATS_REPLY){
+            return replyMapping[i];
+        } else {
+            throw new RuntimeException(t.toString() + " is an invalid OFType");
+        }
+    }
+
+    /**
+     * @return Returns the wire protocol value corresponding to this
+     * OFStatisticsType
+     */
+    public short getTypeValue() {
+        return this.type;
+    }
+
+    /**
+     * @param t type of containing OFMessage, only accepts STATS_REQUEST or
+     *          STATS_REPLY
+     * @return return the OFMessage subclass corresponding to this
+     *                OFStatisticsType
+     */
+    public Class<? extends OFStatistics> toClass(OFType t) {
+        if (t == OFType.STATS_REQUEST) {
+            return requestClass;
+        } else if (t == OFType.STATS_REPLY){
+            return replyClass;
+        } else {
+            throw new RuntimeException(t.toString() + " is an invalid OFType");
+        }
+    }
+
+    /**
+     * Returns the no-argument Constructor of the implementation class for
+     * this OFStatisticsType, either request or reply based on the supplied
+     * OFType
+     *
+     * @param t
+     * @return
+     */
+    public Constructor<? extends OFStatistics> getConstructor(OFType t) {
+        if (t == OFType.STATS_REQUEST) {
+            return requestConstructor;
+        } else if (t == OFType.STATS_REPLY) {
+            return replyConstructor;
+        } else {
+            throw new RuntimeException(t.toString() + " is an invalid OFType");
+        }
+    }
+
+    /**
+     * @return the requestInstantiable
+     */
+    public Instantiable<OFStatistics> getRequestInstantiable() {
+        return requestInstantiable;
+    }
+
+    /**
+     * @param requestInstantiable the requestInstantiable to set
+     */
+    public void setRequestInstantiable(
+            Instantiable<OFStatistics> requestInstantiable) {
+        this.requestInstantiable = requestInstantiable;
+    }
+
+    /**
+     * @return the replyInstantiable
+     */
+    public Instantiable<OFStatistics> getReplyInstantiable() {
+        return replyInstantiable;
+    }
+
+    /**
+     * @param replyInstantiable the replyInstantiable to set
+     */
+    public void setReplyInstantiable(Instantiable<OFStatistics> replyInstantiable) {
+        this.replyInstantiable = replyInstantiable;
+    }
+
+    /**
+     * Returns a new instance of the implementation class for
+     * this OFStatisticsType, either request or reply based on the supplied
+     * OFType
+     *
+     * @param t
+     * @return
+     */
+    public OFStatistics newInstance(OFType t) {
+        if (t == OFType.STATS_REQUEST) {
+            return requestInstantiable.instantiate();
+        } else if (t == OFType.STATS_REPLY) {
+            return replyInstantiable.instantiate();
+        } else {
+            throw new RuntimeException(t.toString() + " is an invalid OFType");
+        }
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFTableStatistics.java b/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFTableStatistics.java
new file mode 100644 (file)
index 0000000..478fdbf
--- /dev/null
@@ -0,0 +1,207 @@
+package org.openflow.protocol.statistics;
+
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+
+import org.openflow.util.StringByteSerializer;
+
+/**
+ * Represents an ofp_table_stats structure
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFTableStatistics implements OFStatistics, Serializable {
+    public static int MAX_TABLE_NAME_LEN = 32;
+
+    protected byte tableId;
+    protected String name;
+    protected int wildcards;
+    protected int maximumEntries;
+    protected int activeCount;
+    protected long lookupCount;
+    protected long matchedCount;
+
+    /**
+     * @return the tableId
+     */
+    public byte getTableId() {
+        return tableId;
+    }
+
+    /**
+     * @param tableId the tableId to set
+     */
+    public void setTableId(byte tableId) {
+        this.tableId = tableId;
+    }
+
+    /**
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name the name to set
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return the wildcards
+     */
+    public int getWildcards() {
+        return wildcards;
+    }
+
+    /**
+     * @param wildcards the wildcards to set
+     */
+    public void setWildcards(int wildcards) {
+        this.wildcards = wildcards;
+    }
+
+    /**
+     * @return the maximumEntries
+     */
+    public int getMaximumEntries() {
+        return maximumEntries;
+    }
+
+    /**
+     * @param maximumEntries the maximumEntries to set
+     */
+    public void setMaximumEntries(int maximumEntries) {
+        this.maximumEntries = maximumEntries;
+    }
+
+    /**
+     * @return the activeCount
+     */
+    public int getActiveCount() {
+        return activeCount;
+    }
+
+    /**
+     * @param activeCount the activeCount to set
+     */
+    public void setActiveCount(int activeCount) {
+        this.activeCount = activeCount;
+    }
+
+    /**
+     * @return the lookupCount
+     */
+    public long getLookupCount() {
+        return lookupCount;
+    }
+
+    /**
+     * @param lookupCount the lookupCount to set
+     */
+    public void setLookupCount(long lookupCount) {
+        this.lookupCount = lookupCount;
+    }
+
+    /**
+     * @return the matchedCount
+     */
+    public long getMatchedCount() {
+        return matchedCount;
+    }
+
+    /**
+     * @param matchedCount the matchedCount to set
+     */
+    public void setMatchedCount(long matchedCount) {
+        this.matchedCount = matchedCount;
+    }
+
+    @Override
+    public int getLength() {
+        return 64;
+    }
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        this.tableId = data.get();
+        data.get(); // pad
+        data.get(); // pad
+        data.get(); // pad
+        this.name = StringByteSerializer.readFrom(data, MAX_TABLE_NAME_LEN);
+        this.wildcards = data.getInt();
+        this.maximumEntries = data.getInt();
+        this.activeCount = data.getInt();
+        this.lookupCount = data.getLong();
+        this.matchedCount = data.getLong();
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        data.put(this.tableId);
+        data.put((byte) 0); // pad
+        data.put((byte) 0); // pad
+        data.put((byte) 0); // pad
+        StringByteSerializer.writeTo(data, MAX_TABLE_NAME_LEN, this.name);
+        data.putInt(this.wildcards);
+        data.putInt(this.maximumEntries);
+        data.putInt(this.activeCount);
+        data.putLong(this.lookupCount);
+        data.putLong(this.matchedCount);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 449;
+        int result = 1;
+        result = prime * result + activeCount;
+        result = prime * result + (int) (lookupCount ^ (lookupCount >>> 32));
+        result = prime * result + (int) (matchedCount ^ (matchedCount >>> 32));
+        result = prime * result + maximumEntries;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + tableId;
+        result = prime * result + wildcards;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFTableStatistics)) {
+            return false;
+        }
+        OFTableStatistics other = (OFTableStatistics) obj;
+        if (activeCount != other.activeCount) {
+            return false;
+        }
+        if (lookupCount != other.lookupCount) {
+            return false;
+        }
+        if (matchedCount != other.matchedCount) {
+            return false;
+        }
+        if (maximumEntries != other.maximumEntries) {
+            return false;
+        }
+        if (name == null) {
+            if (other.name != null) {
+                return false;
+            }
+        } else if (!name.equals(other.name)) {
+            return false;
+        }
+        if (tableId != other.tableId) {
+            return false;
+        }
+        if (wildcards != other.wildcards) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFVendorStatistics.java b/third-party/openflowj/src/main/java/org/openflow/protocol/statistics/OFVendorStatistics.java
new file mode 100644 (file)
index 0000000..28839d2
--- /dev/null
@@ -0,0 +1,83 @@
+package org.openflow.protocol.statistics;
+
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+
+import org.openflow.protocol.factory.OFActionFactory;
+import org.openflow.protocol.factory.OFActionFactoryAware;
+
+/**
+ * The base class for vendor implemented statistics
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class OFVendorStatistics implements OFStatistics, OFActionFactoryAware, Serializable {
+    protected transient OFActionFactory actionFactory;
+    protected int vendor;
+    protected byte[] body;
+
+    // non-message fields
+    protected int length = 0;
+
+    @Override
+    public void readFrom(ByteBuffer data) {
+        this.vendor = data.getInt();
+        if (body == null)
+            body = new byte[length - 4];
+        data.get(body);
+    }
+
+    @Override
+    public void writeTo(ByteBuffer data) {
+        data.putInt(this.vendor);
+        if (body != null)
+            data.put(body);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 457;
+        int result = 1;
+        result = prime * result + vendor;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof OFVendorStatistics)) {
+            return false;
+        }
+        OFVendorStatistics other = (OFVendorStatistics) obj;
+        if (vendor != other.vendor) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int getLength() {
+        return length;
+    }
+
+    public void setLength(int length) {
+        this.length = length;
+    }
+
+    /**
+     * @param actionFactory the actionFactory to set
+     */
+    @Override
+    public void setActionFactory(OFActionFactory actionFactory) {
+        this.actionFactory = actionFactory;
+    }
+
+    public OFActionFactory getActionFactory() {
+        return this.actionFactory;
+    }
+
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/util/HexString.java b/third-party/openflowj/src/main/java/org/openflow/util/HexString.java
new file mode 100644 (file)
index 0000000..489e5a6
--- /dev/null
@@ -0,0 +1,65 @@
+package org.openflow.util;
+
+import java.math.BigInteger;
+
+public class HexString {
+    /**
+     * Convert a string of bytes to a ':' separated hex string
+     * @param bytes
+     * @return "0f:ca:fe:de:ad:be:ef"
+     */
+    public static String toHexString(byte[] bytes) {
+        int i;
+        String ret = "";
+        String tmp;
+        for(i=0; i< bytes.length; i++) {
+            if(i> 0)
+                ret += ":";
+            tmp = Integer.toHexString(U8.f(bytes[i]));
+            if (tmp.length() == 1)
+                ret += "0";
+            ret += tmp; 
+        }
+        return ret;
+    }
+    
+    public static String toHexString(long val) {
+        char arr[] = Long.toHexString(val).toCharArray();
+        String ret = "";
+        // prepend the right number of leading zeros
+        int i = 0;
+        for (; i < (16 - arr.length); i++) {
+            ret += "0";
+            if ((i % 2) == 1)
+                ret += ":";
+        }
+        for (int j = 0; j < arr.length; j++) {
+            ret += arr[j];
+            if ((((i + j) % 2) == 1) && (j < (arr.length - 1)))
+                ret += ":";
+        }
+        return ret;
+    }
+    
+    
+    /**
+     * Convert a string of hex values into a string of bytes
+     * @param values "0f:ca:fe:de:ad:be:ef"
+     * @return [15, 5 ,2, 5, 17] 
+     */
+    
+    public static byte[] fromHexString(String values) {
+        String[] octets = values.split(":");
+        byte[] ret = new byte[octets.length];
+        int i;
+        
+        for(i=0;i<octets.length; i++)
+            ret[i] = Integer.valueOf(octets[i], 16).byteValue();
+        return ret;
+    }
+    
+    public static long toLong(String values) {
+               long value = new BigInteger(values.replaceAll(":", ""), 16).longValue();
+        return value;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/util/LRULinkedHashMap.java b/third-party/openflowj/src/main/java/org/openflow/util/LRULinkedHashMap.java
new file mode 100644 (file)
index 0000000..239ef38
--- /dev/null
@@ -0,0 +1,25 @@
+package org.openflow.util;
+
+import java.util.LinkedHashMap;
+
+public class LRULinkedHashMap<K, V> extends LinkedHashMap<K, V> {
+    private static final long serialVersionUID = -2964986094089626647L;
+    protected int maximumCapacity;
+
+    public LRULinkedHashMap(int initialCapacity, int maximumCapacity) {
+        super(initialCapacity, 0.75f, true);
+        this.maximumCapacity = maximumCapacity;
+    }
+
+    public LRULinkedHashMap(int maximumCapacity) {
+        super(16, 0.75f, true);
+        this.maximumCapacity = maximumCapacity;
+    }
+
+    @Override
+    protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
+        if (this.size() > maximumCapacity)
+            return true;
+        return false;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/util/StringByteSerializer.java b/third-party/openflowj/src/main/java/org/openflow/util/StringByteSerializer.java
new file mode 100644 (file)
index 0000000..80e3721
--- /dev/null
@@ -0,0 +1,40 @@
+package org.openflow.util;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+public class StringByteSerializer {
+    public static String readFrom(ByteBuffer data, int length) {
+        byte[] stringBytes = new byte[length];
+        data.get(stringBytes);
+        // find the first index of 0
+        int index = 0;
+        for (byte b : stringBytes) {
+            if (0 == b)
+                break;
+            ++index;
+        }
+        return new String(Arrays.copyOf(stringBytes, index),
+                Charset.forName("ascii"));
+    }
+
+    public static void writeTo(ByteBuffer data, int length, String value) {
+        try {
+            byte[] name = value.getBytes("ASCII");
+            if (name.length < length) {
+                data.put(name);
+                for (int i = name.length; i < length; ++i) {
+                    data.put((byte) 0);
+                }
+            } else {
+                data.put(name, 0, length-1);
+                data.put((byte) 0);
+            }
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/util/U16.java b/third-party/openflowj/src/main/java/org/openflow/util/U16.java
new file mode 100644 (file)
index 0000000..866e983
--- /dev/null
@@ -0,0 +1,11 @@
+package org.openflow.util;
+
+public class U16 {
+    public static int f(short i) {
+        return (int)i & 0xffff;
+    }
+
+    public static short t(int l) {
+        return (short) l;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/util/U32.java b/third-party/openflowj/src/main/java/org/openflow/util/U32.java
new file mode 100644 (file)
index 0000000..64c324d
--- /dev/null
@@ -0,0 +1,11 @@
+package org.openflow.util;
+
+public class U32 {
+    public static long f(int i) {
+        return (long)i & 0xffffffffL;
+    }
+
+    public static int t(long l) {
+        return (int) l;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/util/U64.java b/third-party/openflowj/src/main/java/org/openflow/util/U64.java
new file mode 100644 (file)
index 0000000..2b3137e
--- /dev/null
@@ -0,0 +1,13 @@
+package org.openflow.util;
+
+import java.math.BigInteger;
+
+public class U64 {
+    public static BigInteger f(long i) {
+        return new BigInteger(Long.toBinaryString(i), 2);
+    }
+
+    public static long t(BigInteger l) {
+        return l.longValue();
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/util/U8.java b/third-party/openflowj/src/main/java/org/openflow/util/U8.java
new file mode 100644 (file)
index 0000000..59ace48
--- /dev/null
@@ -0,0 +1,11 @@
+package org.openflow.util;
+
+public class U8 {
+    public static short f(byte i) {
+        return (short) ((short)i & 0xff);
+    }
+
+    public static byte t(short l) {
+        return (byte) l;
+    }
+}
diff --git a/third-party/openflowj/src/main/java/org/openflow/util/Unsigned.java b/third-party/openflowj/src/main/java/org/openflow/util/Unsigned.java
new file mode 100644 (file)
index 0000000..f2e40e6
--- /dev/null
@@ -0,0 +1,195 @@
+package org.openflow.util;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+
+/*****
+ * A util library class for dealing with the lack of unsigned datatypes in Java
+ *
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+
+public class Unsigned {
+    /**
+     * Get an unsigned byte from the current position of the ByteBuffer
+     *
+     * @param bb ByteBuffer to get the byte from
+     * @return an unsigned byte contained in a short
+     */
+    public static short getUnsignedByte(ByteBuffer bb) {
+        return ((short) (bb.get() & (short) 0xff));
+    }
+
+    /**
+     * Get an unsigned byte from the specified offset in the ByteBuffer
+     *
+     * @param bb ByteBuffer to get the byte from
+     * @param offset the offset to get the byte from
+     * @return an unsigned byte contained in a short
+     */
+    public static short getUnsignedByte(ByteBuffer bb, int offset) {
+        return ((short) (bb.get(offset) & (short) 0xff));
+    }
+
+    /**
+     * Put an unsigned byte into the specified ByteBuffer at the current
+     * position
+     *
+     * @param bb ByteBuffer to put the byte into
+     * @param v the short containing the unsigned byte
+     */
+    public static void putUnsignedByte(ByteBuffer bb, short v) {
+        bb.put((byte) (v & 0xff));
+    }
+
+    /**
+     * Put an unsigned byte into the specified ByteBuffer at the specified
+     * offset
+     *
+     * @param bb ByteBuffer to put the byte into
+     * @param v the short containing the unsigned byte
+     * @param offset the offset to insert the unsigned byte at
+     */
+    public static void putUnsignedByte(ByteBuffer bb, short v, int offset) {
+        bb.put(offset, (byte) (v & 0xff));
+    }
+
+    /**
+     * Get an unsigned short from the current position of the ByteBuffer
+     *
+     * @param bb ByteBuffer to get the byte from
+     * @return an unsigned short contained in a int
+     */
+    public static int getUnsignedShort(ByteBuffer bb) {
+        return (bb.getShort() & 0xffff);
+    }
+
+    /**
+     * Get an unsigned short from the specified offset in the ByteBuffer
+     *
+     * @param bb ByteBuffer to get the short from
+     * @param offset the offset to get the short from
+     * @return an unsigned short contained in a int
+     */
+    public static int getUnsignedShort(ByteBuffer bb, int offset) {
+        return (bb.getShort(offset) & 0xffff);
+    }
+
+    /**
+     * Put an unsigned short into the specified ByteBuffer at the current
+     * position
+     *
+     * @param bb ByteBuffer to put the short into
+     * @param v the int containing the unsigned short
+     */
+    public static void putUnsignedShort(ByteBuffer bb, int v) {
+        bb.putShort((short) (v & 0xffff));
+    }
+
+    /**
+     * Put an unsigned short into the specified ByteBuffer at the specified
+     * offset
+     *
+     * @param bb ByteBuffer to put the short into
+     * @param v the int containing the unsigned short
+     * @param offset the offset to insert the unsigned short at
+     */
+    public static void putUnsignedShort(ByteBuffer bb, int v, int offset) {
+        bb.putShort(offset, (short) (v & 0xffff));
+    }
+
+    /**
+     * Get an unsigned int from the current position of the ByteBuffer
+     *
+     * @param bb ByteBuffer to get the int from
+     * @return an unsigned int contained in a long
+     */
+    public static long getUnsignedInt(ByteBuffer bb) {
+        return ((long) bb.getInt() & 0xffffffffL);
+    }
+
+    /**
+     * Get an unsigned int from the specified offset in the ByteBuffer
+     *
+     * @param bb ByteBuffer to get the int from
+     * @param offset the offset to get the int from
+     * @return an unsigned int contained in a long
+     */
+    public static long getUnsignedInt(ByteBuffer bb, int offset) {
+        return ((long) bb.getInt(offset) & 0xffffffffL);
+    }
+
+    /**
+     * Put an unsigned int into the specified ByteBuffer at the current position
+     *
+     * @param bb ByteBuffer to put the int into
+     * @param v the long containing the unsigned int
+     */
+    public static void putUnsignedInt(ByteBuffer bb, long v) {
+        bb.putInt((int) (v & 0xffffffffL));
+    }
+
+    /**
+     * Put an unsigned int into the specified ByteBuffer at the specified offset
+     *
+     * @param bb ByteBuffer to put the int into
+     * @param v the long containing the unsigned int
+     * @param offset the offset to insert the unsigned int at
+     */
+    public static void putUnsignedInt(ByteBuffer bb, long v, int offset) {
+        bb.putInt(offset, (int) (v & 0xffffffffL));
+    }
+
+    /**
+     * Get an unsigned long from the current position of the ByteBuffer
+     *
+     * @param bb ByteBuffer to get the long from
+     * @return an unsigned long contained in a BigInteger
+     */
+    public static BigInteger getUnsignedLong(ByteBuffer bb) {
+        byte[] v = new byte[8];
+        for (int i = 0; i < 8; ++i) {
+            v[i] = bb.get(i);
+        }
+        return new BigInteger(1, v);
+    }
+
+    /**
+     * Get an unsigned long from the specified offset in the ByteBuffer
+     *
+     * @param bb ByteBuffer to get the long from
+     * @param offset the offset to get the long from
+     * @return an unsigned long contained in a BigInteger
+     */
+    public static BigInteger getUnsignedLong(ByteBuffer bb, int offset) {
+        byte[] v = new byte[8];
+        for (int i = 0; i < 8; ++i) {
+            v[i] = bb.get(offset+i);
+        }
+        return new BigInteger(1, v);
+    }
+
+    /**
+     * Put an unsigned long into the specified ByteBuffer at the current
+     * position
+     *
+     * @param bb ByteBuffer to put the long into
+     * @param v the BigInteger containing the unsigned long
+     */
+    public static void putUnsignedLong(ByteBuffer bb, BigInteger v) {
+        bb.putLong(v.longValue());
+    }
+
+    /**
+     * Put an unsigned long into the specified ByteBuffer at the specified
+     * offset
+     *
+     * @param bb  ByteBuffer to put the long into
+     * @param v the BigInteger containing the unsigned long
+     * @param offset the offset to insert the unsigned long at
+     */
+    public static void putUnsignedLong(ByteBuffer bb, BigInteger v, int offset) {
+        bb.putLong(offset, v.longValue());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/io/OFMessageAsyncStreamTest.java b/third-party/openflowj/src/test/java/org/openflow/io/OFMessageAsyncStreamTest.java
new file mode 100644 (file)
index 0000000..7021367
--- /dev/null
@@ -0,0 +1,57 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.io;
+
+import org.openflow.protocol.*;
+import org.openflow.protocol.factory.BasicFactory;
+
+import java.util.*;
+import java.nio.channels.*;
+import java.net.InetSocketAddress;
+
+import org.junit.Assert;
+
+import org.junit.Test;
+
+
+/**
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ *
+ */
+public class OFMessageAsyncStreamTest {
+    @Test
+    public void testMarshalling() throws Exception {
+        OFMessage h = new OFHello();
+        
+        ServerSocketChannel serverSC = ServerSocketChannel.open();
+        serverSC.socket().bind(new java.net.InetSocketAddress(0));
+        serverSC.configureBlocking(false);
+        
+        SocketChannel client = SocketChannel.open(
+                new InetSocketAddress("localhost",
+                        serverSC.socket().getLocalPort())
+                );
+        SocketChannel server = serverSC.accept();
+        OFMessageAsyncStream clientStream = new OFMessageAsyncStream(client, new BasicFactory());
+        OFMessageAsyncStream serverStream = new OFMessageAsyncStream(server, new BasicFactory());
+        
+        clientStream.write(h);
+        while(clientStream.needsFlush()) {
+            clientStream.flush();
+        }
+        List<OFMessage> l = serverStream.read();
+        Assert.assertEquals(l.size(), 1);
+        OFMessage m = l.get(0);
+        Assert.assertEquals(m.getLength(),h.getLength());
+        Assert.assertEquals(m.getVersion(), h.getVersion());
+        Assert.assertEquals(m.getType(), h.getType());
+        Assert.assertEquals(m.getType(), h.getType());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/BasicFactoryTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/BasicFactoryTest.java
new file mode 100644 (file)
index 0000000..54a9dd0
--- /dev/null
@@ -0,0 +1,40 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.openflow.protocol.factory.BasicFactory;
+import org.openflow.util.U16;
+
+import junit.framework.TestCase;
+
+
+
+public class BasicFactoryTest extends TestCase {
+    public void testCreateAndParse() {
+        BasicFactory factory = new BasicFactory();
+        OFMessage m = factory.getMessage(OFType.HELLO);
+        m.setVersion((byte) 1);
+        m.setType(OFType.ECHO_REQUEST);
+        m.setLength(U16.t(8));
+        m.setXid(0xdeadbeef);
+        ByteBuffer bb = ByteBuffer.allocate(1024);
+        m.writeTo(bb);
+        bb.flip();
+        bb.limit(bb.limit()-1);
+        TestCase.assertEquals(0, factory.parseMessages(bb).size());
+        bb.limit(bb.limit()+1);
+        List<OFMessage> messages = factory.parseMessages(bb);
+        TestCase.assertEquals(1, messages.size());
+        TestCase.assertTrue(messages.get(0).getType() == OFType.ECHO_REQUEST);
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFActionTypeTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFActionTypeTest.java
new file mode 100644 (file)
index 0000000..102eeb8
--- /dev/null
@@ -0,0 +1,29 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+
+import org.junit.Test;
+import org.openflow.protocol.action.OFActionType;
+
+import junit.framework.TestCase;
+
+
+public class OFActionTypeTest extends TestCase {
+    @Test
+    public void testMapping() throws Exception {
+        TestCase.assertEquals(OFActionType.OUTPUT,
+                OFActionType.valueOf((short) 0));
+        TestCase.assertEquals(OFActionType.OPAQUE_ENQUEUE,
+                OFActionType.valueOf((short) 11));
+        TestCase.assertEquals(OFActionType.VENDOR,
+                OFActionType.valueOf((short) 0xffff));
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFBarrierReplyTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFBarrierReplyTest.java
new file mode 100644 (file)
index 0000000..f92d45a
--- /dev/null
@@ -0,0 +1,29 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+
+import junit.framework.TestCase;
+
+import org.openflow.util.OFTestCase;
+
+public class OFBarrierReplyTest extends OFTestCase {
+    public void testWriteRead() throws Exception {
+        OFBarrierReply msg = (OFBarrierReply) messageFactory
+                .getMessage(OFType.BARRIER_REPLY);
+        ByteBuffer bb = ByteBuffer.allocate(1024);
+        bb.clear();
+        msg.writeTo(bb);
+        bb.flip();
+        msg.readFrom(bb);
+        TestCase.assertEquals(OFType.BARRIER_REPLY, msg.getType());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFBarrierRequestTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFBarrierRequestTest.java
new file mode 100644 (file)
index 0000000..cca4d64
--- /dev/null
@@ -0,0 +1,29 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+
+import junit.framework.TestCase;
+
+import org.openflow.util.OFTestCase;
+
+public class OFBarrierRequestTest extends OFTestCase {
+    public void testWriteRead() throws Exception {
+        OFBarrierRequest msg = (OFBarrierRequest) messageFactory
+                .getMessage(OFType.BARRIER_REQUEST);
+        ByteBuffer bb = ByteBuffer.allocate(1024);
+        bb.clear();
+        msg.writeTo(bb);
+        bb.flip();
+        msg.readFrom(bb);
+        TestCase.assertEquals(OFType.BARRIER_REQUEST, msg.getType());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFErrorTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFErrorTest.java
new file mode 100644 (file)
index 0000000..4ed08bf
--- /dev/null
@@ -0,0 +1,80 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.openflow.protocol.OFError.OFErrorType;
+import org.openflow.protocol.OFError.OFHelloFailedCode;
+import org.openflow.protocol.factory.BasicFactory;
+import org.openflow.protocol.factory.OFMessageFactory;
+import org.openflow.util.OFTestCase;
+
+public class OFErrorTest extends OFTestCase {
+    public void testWriteRead() throws Exception {
+        OFError msg = (OFError) messageFactory.getMessage(OFType.ERROR);
+        msg.setMessageFactory(messageFactory);
+        msg.setErrorType((short) OFErrorType.OFPET_HELLO_FAILED.ordinal());
+        msg.setErrorCode((short) OFHelloFailedCode.OFPHFC_INCOMPATIBLE
+                .ordinal());
+        ByteBuffer bb = ByteBuffer.allocate(1024);
+        bb.clear();
+        msg.writeTo(bb);
+        bb.flip();
+        msg.readFrom(bb);
+        TestCase.assertEquals((short) OFErrorType.OFPET_HELLO_FAILED.ordinal(),
+                msg.getErrorType());
+        TestCase.assertEquals((short) OFHelloFailedCode.OFPHFC_INCOMPATIBLE
+                .ordinal(), msg.getErrorType());
+        TestCase.assertNull(msg.getOffendingMsg());
+
+        msg.setOffendingMsg(new OFHello());
+        bb.clear();
+        msg.writeTo(bb);
+        bb.flip();
+        msg.readFrom(bb);
+        TestCase.assertEquals((short) OFErrorType.OFPET_HELLO_FAILED.ordinal(),
+                msg.getErrorType());
+        TestCase.assertEquals((short) OFHelloFailedCode.OFPHFC_INCOMPATIBLE
+                .ordinal(), msg.getErrorType());
+        TestCase.assertNotNull(msg.getOffendingMsg());
+        TestCase.assertEquals(OFHello.MINIMUM_LENGTH,
+                msg.getOffendingMsg().length);
+    }
+
+    public void testGarbageAtEnd() {
+        // This is a OFError msg (12 bytes), that encaps a OFVendor msg (24
+        // bytes)
+        // AND some zeros at the end (40 bytes) for a total of 76 bytes
+        // THIS is what an NEC sends in reply to Nox's VENDOR request
+        byte[] oferrorRaw = { 0x01, 0x01, 0x00, 0x4c, 0x00, 0x00, 0x10,
+                (byte) 0xcc, 0x00, 0x01, 0x00, 0x01, 0x01, 0x04, 0x00, 0x18,
+                0x00, 0x00, 0x10, (byte) 0xcc, 0x00, 0x00, 0x23, 0x20, 0x00,
+                0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00 };
+        OFMessageFactory factory = new BasicFactory();
+        ByteBuffer oferrorBuf = ByteBuffer.wrap(oferrorRaw);
+        List<OFMessage> msgs = factory.parseMessages(oferrorBuf,
+                oferrorRaw.length);
+        TestCase.assertEquals(1, msgs.size());
+        OFMessage msg = msgs.get(0);
+        TestCase.assertEquals(76, msg.getLengthU());
+        ByteBuffer out = ByteBuffer.allocate(1024);
+        msg.writeTo(out);
+        TestCase.assertEquals(76, out.position());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFFeaturesReplyTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFFeaturesReplyTest.java
new file mode 100644 (file)
index 0000000..97ff59b
--- /dev/null
@@ -0,0 +1,56 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.openflow.util.OFTestCase;
+
+
+public class OFFeaturesReplyTest extends OFTestCase {
+    public void testWriteRead() throws Exception {
+        OFFeaturesReply ofr = (OFFeaturesReply) messageFactory
+                .getMessage(OFType.FEATURES_REPLY);
+        List<OFPhysicalPort> ports = new ArrayList<OFPhysicalPort>();
+        OFPhysicalPort port = new OFPhysicalPort();
+        port.setHardwareAddress(new byte[6]);
+        port.setName("eth0");
+        ports.add(port);
+        ofr.setPorts(ports);
+        ByteBuffer bb = ByteBuffer.allocate(1024);
+        bb.clear();
+        ofr.writeTo(bb);
+        bb.flip();
+        ofr.readFrom(bb);
+        TestCase.assertEquals(1, ofr.getPorts().size());
+        TestCase.assertEquals("eth0", ofr.getPorts().get(0).getName());
+
+        // test a 15 character name
+        ofr.getPorts().get(0).setName("012345678901234");
+        bb.clear();
+        ofr.writeTo(bb);
+        bb.flip();
+        ofr.readFrom(bb);
+        TestCase.assertEquals("012345678901234", ofr.getPorts().get(0).getName());
+
+        // test a 16 character name getting truncated
+        ofr.getPorts().get(0).setName("0123456789012345");
+        bb.clear();
+        ofr.writeTo(bb);
+        bb.flip();
+        ofr.readFrom(bb);
+        TestCase.assertEquals("012345678901234", ofr.getPorts().get(0).getName());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFFlowRemovedTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFFlowRemovedTest.java
new file mode 100644 (file)
index 0000000..4da9fe9
--- /dev/null
@@ -0,0 +1,36 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+
+import junit.framework.TestCase;
+
+import org.openflow.protocol.OFFlowRemoved.OFFlowRemovedReason;
+import org.openflow.util.OFTestCase;
+
+public class OFFlowRemovedTest extends OFTestCase {
+    public void testWriteRead() throws Exception {
+        OFFlowRemoved msg = (OFFlowRemoved) messageFactory
+                .getMessage(OFType.FLOW_REMOVED);
+        msg.setMatch(new OFMatch());
+        byte[] hwAddr = new byte[6];
+        msg.getMatch().setDataLayerDestination(hwAddr);
+        msg.getMatch().setDataLayerSource(hwAddr);
+        msg.setReason(OFFlowRemovedReason.OFPRR_DELETE);
+        ByteBuffer bb = ByteBuffer.allocate(1024);
+        bb.clear();
+        msg.writeTo(bb);
+        bb.flip();
+        msg.readFrom(bb);
+        TestCase.assertEquals(OFType.FLOW_REMOVED, msg.getType());
+        TestCase.assertEquals(OFFlowRemovedReason.OFPRR_DELETE, msg.getReason());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFGetConfigReplyTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFGetConfigReplyTest.java
new file mode 100644 (file)
index 0000000..941f6c9
--- /dev/null
@@ -0,0 +1,31 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+
+import junit.framework.TestCase;
+
+import org.openflow.util.OFTestCase;
+
+public class OFGetConfigReplyTest extends OFTestCase {
+    public void testWriteRead() throws Exception {
+        OFSetConfig msg = (OFSetConfig) messageFactory
+                .getMessage(OFType.SET_CONFIG);
+        msg.setFlags((short) 1);
+        ByteBuffer bb = ByteBuffer.allocate(1024);
+        bb.clear();
+        msg.writeTo(bb);
+        bb.flip();
+        msg.readFrom(bb);
+        TestCase.assertEquals(OFType.SET_CONFIG, msg.getType());
+        TestCase.assertEquals((short)1, msg.getFlags());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFGetConfigRequestTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFGetConfigRequestTest.java
new file mode 100644 (file)
index 0000000..863b20d
--- /dev/null
@@ -0,0 +1,29 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+
+import junit.framework.TestCase;
+
+import org.openflow.util.OFTestCase;
+
+public class OFGetConfigRequestTest extends OFTestCase {
+    public void testWriteRead() throws Exception {
+        OFGetConfigRequest msg = (OFGetConfigRequest) messageFactory
+                .getMessage(OFType.GET_CONFIG_REQUEST);
+        ByteBuffer bb = ByteBuffer.allocate(1024);
+        bb.clear();
+        msg.writeTo(bb);
+        bb.flip();
+        msg.readFrom(bb);
+        TestCase.assertEquals(OFType.GET_CONFIG_REQUEST, msg.getType());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFMatchTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFMatchTest.java
new file mode 100644 (file)
index 0000000..8465598
--- /dev/null
@@ -0,0 +1,111 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import junit.framework.TestCase;
+
+public class OFMatchTest extends TestCase {
+    public void testFromString() {
+        OFMatch correct = new OFMatch();
+        OFMatch tester = new OFMatch();
+
+        // Various combinations of "all"/"any"
+        tester.fromString("OFMatch[]");
+        // correct is already wildcarded
+        TestCase.assertEquals(correct, tester);
+        tester.fromString("all");
+        TestCase.assertEquals(correct, tester);
+        tester.fromString("ANY");
+        TestCase.assertEquals(correct, tester);
+        tester.fromString("");
+        TestCase.assertEquals(correct, tester);
+        tester.fromString("[]");
+        TestCase.assertEquals(correct, tester);
+
+        // ip_src
+        correct.setWildcards(~OFMatch.OFPFW_NW_SRC_MASK);
+        correct.setNetworkSource(0x01010203);
+        tester.fromString("nw_src=1.1.2.3");
+        TestCase.assertEquals(correct.getNetworkSourceMaskLen(), tester
+                .getNetworkSourceMaskLen());
+        TestCase.assertEquals(correct, tester);
+        tester.fromString("IP_sRc=1.1.2.3");
+        TestCase.assertEquals(correct.getNetworkSourceMaskLen(), tester
+                .getNetworkSourceMaskLen());
+        TestCase.assertEquals(correct, tester);
+    }
+
+    public void testToString() {
+        OFMatch match = new OFMatch();
+        match.fromString("nw_dst=3.4.5.6/8");
+        TestCase.assertEquals(8, match.getNetworkDestinationMaskLen());
+        String correct = "OFMatch[nw_dst=3.0.0.0/8]";
+        String tester = match.toString();
+
+        TestCase.assertEquals(correct, tester);
+        tester = "OFMatch[dl_type=35020]";
+        correct = "OFMatch[dl_type=0x88cc]";
+        match = new OFMatch();
+        match.fromString(tester);
+        TestCase.assertEquals(correct, match.toString());
+        OFMatch match2 = new OFMatch();
+        match2.fromString(correct);
+        TestCase.assertEquals(match, match2);
+    }
+
+    public void testClone() {
+        OFMatch match1 = new OFMatch();
+        OFMatch match2 = match1.clone();
+        TestCase.assertEquals(match1, match2);
+        match2.setNetworkProtocol((byte) 4);
+        match2.setWildcards(match2.getWildcards() & ~OFMatch.OFPFW_NW_PROTO);
+        TestCase.assertNotSame(match1, match2);
+    }
+
+    public void testIpToString() {
+        String test = OFMatch.ipToString(-1);
+        TestCase.assertEquals("255.255.255.255", test);
+    }
+
+    public void testReverse() {
+        OFMatch match1 = new OFMatch();
+        OFMatch match2 = match1.reverse((short)0, true);
+        TestCase.assertEquals(match1, match2);
+
+        match1.fromString("dl_dst=00:11:22:33:44:55");
+        match2 = match1.reverse((short)0, true);
+        OFMatch match3 = new OFMatch();
+        match3.fromString("dl_src=00:11:22:33:44:55");
+        TestCase.assertEquals(match2, match3);
+
+        match1.fromString("nw_dst=192.168.0.0/24");
+        match2 = match1.reverse((short)0, true);
+        match3.fromString("nw_src=192.168.0.0/24");
+        TestCase.assertEquals(match2, match3);
+
+        match1.fromString("in_port=1");
+        match2 = match1.reverse((short)2, false);
+        match3.fromString("in_port=2");
+        TestCase.assertEquals(match2, match3);
+    }
+
+    public void testSubsumes() {
+        OFMatch match1 = new OFMatch();
+        OFMatch match2 = new OFMatch();
+        match2.fromString("dl_dst=00:11:22:33:44:55");
+        TestCase.assertTrue(match1.subsumes(match2));
+        TestCase.assertFalse(match2.subsumes(match1));
+
+        match1.fromString("nw_dst=192.168.0.0/16");
+        match2.fromString("nw_dst=192.168.0.0/24");
+        TestCase.assertTrue(match1.subsumes(match2));
+        TestCase.assertFalse(match2.subsumes(match1));
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFPortConfigTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFPortConfigTest.java
new file mode 100644 (file)
index 0000000..25c6e02
--- /dev/null
@@ -0,0 +1,32 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+
+import junit.framework.TestCase;
+
+import org.openflow.util.OFTestCase;
+
+public class OFPortConfigTest extends OFTestCase {
+    public void testWriteRead() throws Exception {
+        OFPortMod msg = (OFPortMod) messageFactory
+                .getMessage(OFType.PORT_MOD);
+        msg.setHardwareAddress(new byte[6]);
+        msg.portNumber = 1;
+        ByteBuffer bb = ByteBuffer.allocate(1024);
+        bb.clear();
+        msg.writeTo(bb);
+        bb.flip();
+        msg.readFrom(bb);
+        TestCase.assertEquals(OFType.PORT_MOD, msg.getType());
+        TestCase.assertEquals(1, msg.getPortNumber());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFPortStatusTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFPortStatusTest.java
new file mode 100644 (file)
index 0000000..9e47260
--- /dev/null
@@ -0,0 +1,37 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+
+import junit.framework.TestCase;
+
+import org.openflow.protocol.OFPortStatus.OFPortReason;
+import org.openflow.util.OFTestCase;
+
+public class OFPortStatusTest extends OFTestCase {
+    public void testWriteRead() throws Exception {
+        OFPortStatus msg = (OFPortStatus) messageFactory
+                .getMessage(OFType.PORT_STATUS);
+        msg.setDesc(new OFPhysicalPort());
+        msg.getDesc().setHardwareAddress(new byte[6]);
+        msg.getDesc().setName("eth0");
+        msg.setReason((byte) OFPortReason.OFPPR_ADD.ordinal());
+        ByteBuffer bb = ByteBuffer.allocate(1024);
+        bb.clear();
+        msg.writeTo(bb);
+        bb.flip();
+        msg.readFrom(bb);
+        TestCase.assertEquals(OFType.PORT_STATUS, msg.getType());
+        TestCase.assertEquals((byte) OFPortReason.OFPPR_ADD.ordinal(), msg
+                .getReason());
+        TestCase.assertNotNull(msg.getDesc());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFQueueConfigTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFQueueConfigTest.java
new file mode 100644 (file)
index 0000000..467b1da
--- /dev/null
@@ -0,0 +1,93 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.openflow.protocol.factory.BasicFactory;
+import org.openflow.protocol.queue.OFPacketQueue;
+import org.openflow.protocol.queue.OFQueueProperty;
+import org.openflow.protocol.queue.OFQueuePropertyMinRate;
+import org.openflow.protocol.queue.OFQueuePropertyType;
+import org.openflow.util.OFTestCase;
+
+public class OFQueueConfigTest extends OFTestCase {
+    public void testRequest() throws Exception {
+        OFQueueConfigRequest req = new OFQueueConfigRequest();
+        req.setPort((short) 5);
+        ByteBuffer bb = ByteBuffer.allocate(1024);
+        bb.clear();
+        req.writeTo(bb);
+        bb.flip();
+
+        OFQueueConfigRequest req2 = new OFQueueConfigRequest();
+        req2.readFrom(bb);
+        TestCase.assertEquals(req, req2);
+    }
+
+    public void testReply() throws Exception {
+        OFQueueConfigReply reply = new OFQueueConfigReply();
+        reply.setPort((short) 5);
+
+        OFPacketQueue queue = new OFPacketQueue();
+        queue.setQueueId(1);
+        List<OFQueueProperty> properties = new ArrayList<OFQueueProperty>();
+        properties.add(new OFQueuePropertyMinRate().setRate((short) 1));
+        queue.setProperties(properties);
+        queue.setLength((short) (OFPacketQueue.MINIMUM_LENGTH + OFQueuePropertyMinRate.MINIMUM_LENGTH));
+
+        List<OFPacketQueue> queues = new ArrayList<OFPacketQueue>();
+        queues.add(queue);
+        reply.setQueues(queues);
+        reply.setLengthU(OFQueueConfigReply.MINIMUM_LENGTH + queue.getLength());
+
+        ByteBuffer bb = ByteBuffer.allocate(1024);
+        bb.clear();
+        reply.writeTo(bb);
+        bb.flip();
+
+        OFQueueConfigReply reply2 = new OFQueueConfigReply();
+        reply2.setQueuePropertyFactory(new BasicFactory());
+        reply2.readFrom(bb);
+        TestCase.assertEquals(reply, reply2);
+        TestCase.assertEquals(1, reply2.getQueues().size());
+        TestCase.assertEquals(1, reply2.getQueues().get(0).getProperties().size());
+        TestCase.assertTrue(reply2.getQueues().get(0).getProperties().get(0) instanceof OFQueuePropertyMinRate);
+        TestCase.assertEquals(OFQueuePropertyType.MIN_RATE, reply2.getQueues().get(0).getProperties().get(0).getType());
+
+        reply.getQueues().add(queue.clone());
+        reply.setLengthU(reply.getLengthU() + queue.getLength());
+        bb.clear();
+        reply.writeTo(bb);
+        bb.flip();
+        reply2 = new OFQueueConfigReply();
+        reply2.setQueuePropertyFactory(new BasicFactory());
+        reply2.readFrom(bb);
+        TestCase.assertEquals(reply, reply2);
+        TestCase.assertEquals(2, reply2.getQueues().size());
+
+        queue.getProperties().add(new OFQueuePropertyMinRate().setRate((short) 2));
+        queue.setLength((short) (queue.getLength() + OFQueuePropertyMinRate.MINIMUM_LENGTH));
+        reply.setLengthU(reply.getLengthU() + OFQueuePropertyMinRate.MINIMUM_LENGTH);
+        bb.clear();
+        reply.writeTo(bb);
+        bb.flip();
+        reply2 = new OFQueueConfigReply();
+        reply2.setQueuePropertyFactory(new BasicFactory());
+        reply2.readFrom(bb);
+        TestCase.assertEquals(reply, reply2);
+        TestCase.assertEquals(2, reply2.getQueues().size());
+        TestCase.assertEquals(2, reply2.getQueues().get(0).getProperties().size());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFSetConfigTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFSetConfigTest.java
new file mode 100644 (file)
index 0000000..c49afdf
--- /dev/null
@@ -0,0 +1,31 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+
+import junit.framework.TestCase;
+
+import org.openflow.util.OFTestCase;
+
+public class OFSetConfigTest extends OFTestCase {
+    public void testWriteRead() throws Exception {
+        OFGetConfigReply msg = (OFGetConfigReply) messageFactory
+                .getMessage(OFType.GET_CONFIG_REPLY);
+        msg.setFlags((short) 1);
+        ByteBuffer bb = ByteBuffer.allocate(1024);
+        bb.clear();
+        msg.writeTo(bb);
+        bb.flip();
+        msg.readFrom(bb);
+        TestCase.assertEquals(OFType.GET_CONFIG_REPLY, msg.getType());
+        TestCase.assertEquals((short)1, msg.getFlags());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFStatisticsReplyTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFStatisticsReplyTest.java
new file mode 100644 (file)
index 0000000..21e4605
--- /dev/null
@@ -0,0 +1,67 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.openflow.protocol.factory.BasicFactory;
+import org.openflow.protocol.factory.OFMessageFactory;
+import org.openflow.protocol.statistics.OFStatisticsType;
+import org.openflow.util.OFTestCase;
+
+public class OFStatisticsReplyTest extends OFTestCase {
+    public void testOFFlowStatisticsReply() throws Exception {
+        byte[] packet = new byte[] { 0x01, 0x11, 0x01, 0x2c, 0x00, 0x00, 0x00,
+                0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, (byte) 0xff,
+                (byte) 0xff, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00,
+                0x0a, 0x00, 0x00, 0x03, 0x0a, 0x00, 0x00, 0x02, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, (byte) 0xa6,
+                (byte) 0xa6, 0x00, (byte) 0xff, (byte) 0xff, 0x00, 0x05, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                (byte) 0xc4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00,
+                0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x02, (byte) 0xff, (byte) 0xff, 0x00, 0x00, 0x08, 0x06,
+                0x00, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x03, 0x0a, 0x00,
+                0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x3b, 0x2f, (byte) 0xfa, 0x40, (byte) 0xff, (byte) 0xff, 0x00,
+                0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
+                0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x03, (byte) 0xff, (byte) 0xff, 0x00, 0x62, 0x08,
+                0x00, 0x00, 0x01, 0x62, 0x37, 0x0a, 0x00, 0x00, 0x02, 0x0a,
+                0x00, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x3a, (byte) 0xc5, 0x2a, (byte) 0x80, (byte) 0xff,
+                (byte) 0xff, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0xc4, 0x00, 0x00, 0x00,
+                0x08, 0x00, 0x02, 0x00, 0x00 };
+
+        OFMessageFactory factory = new BasicFactory();
+        ByteBuffer packetBuf = ByteBuffer.wrap(packet);
+        List<OFMessage> msgs = factory.parseMessages(packetBuf, packet.length);
+        TestCase.assertEquals(1, msgs.size());
+        TestCase.assertTrue(msgs.get(0) instanceof OFStatisticsReply);
+        OFStatisticsReply sr = (OFStatisticsReply) msgs.get(0);
+        TestCase.assertEquals(OFStatisticsType.FLOW, sr.getStatisticType());
+        TestCase.assertEquals(3, sr.getStatistics().size());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFStatisticsRequestTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFStatisticsRequestTest.java
new file mode 100644 (file)
index 0000000..d7e05c8
--- /dev/null
@@ -0,0 +1,68 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.openflow.protocol.factory.BasicFactory;
+import org.openflow.protocol.factory.OFMessageFactory;
+import org.openflow.protocol.statistics.OFFlowStatisticsRequest;
+import org.openflow.protocol.statistics.OFStatisticsType;
+import org.openflow.protocol.statistics.OFVendorStatistics;
+import org.openflow.util.OFTestCase;
+
+public class OFStatisticsRequestTest extends OFTestCase {
+    public void testOFFlowStatisticsRequest() throws Exception {
+        byte[] packet = new byte[] { 0x01, 0x10, 0x00, 0x38, 0x00, 0x00, 0x00,
+                0x16, 0x00, 0x01, 0x00, 0x00, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                (byte) 0xff, 0x00, (byte) 0xff, (byte) 0xff };
+
+        OFMessageFactory factory = new BasicFactory();
+        ByteBuffer packetBuf = ByteBuffer.wrap(packet);
+        List<OFMessage> msgs = factory.parseMessages(packetBuf, packet.length);
+        TestCase.assertEquals(1, msgs.size());
+        TestCase.assertTrue(msgs.get(0) instanceof OFStatisticsRequest);
+        OFStatisticsRequest sr = (OFStatisticsRequest) msgs.get(0);
+        TestCase.assertEquals(OFStatisticsType.FLOW, sr.getStatisticType());
+        TestCase.assertEquals(1, sr.getStatistics().size());
+        TestCase.assertTrue(sr.getStatistics().get(0) instanceof OFFlowStatisticsRequest);
+    }
+
+    public void testOFStatisticsRequestVendor() throws Exception {
+        byte[] packet = new byte[] { 0x01, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00,
+                0x63, (byte) 0xff, (byte) 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x4c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x01, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x20,
+                (byte) 0xe0, 0x00, 0x11, 0x00, 0x0c, 0x29, (byte) 0xc5,
+                (byte) 0x95, 0x57, 0x02, 0x25, 0x5c, (byte) 0xca, 0x00, 0x02,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x50, 0x04,
+                0x00, 0x00, 0x00, 0x00, (byte) 0xff, 0x00, 0x00, 0x00,
+                (byte) 0xff, (byte) 0xff, 0x4e, 0x20 };
+
+        OFMessageFactory factory = new BasicFactory();
+        ByteBuffer packetBuf = ByteBuffer.wrap(packet);
+        List<OFMessage> msgs = factory.parseMessages(packetBuf, packet.length);
+        TestCase.assertEquals(1, msgs.size());
+        TestCase.assertTrue(msgs.get(0) instanceof OFStatisticsRequest);
+        OFStatisticsRequest sr = (OFStatisticsRequest) msgs.get(0);
+        TestCase.assertEquals(OFStatisticsType.VENDOR, sr.getStatisticType());
+        TestCase.assertEquals(1, sr.getStatistics().size());
+        TestCase.assertTrue(sr.getStatistics().get(0) instanceof OFVendorStatistics);
+        TestCase.assertEquals(68, ((OFVendorStatistics)sr.getStatistics().get(0)).getLength());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFStatisticsTypeTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFStatisticsTypeTest.java
new file mode 100644 (file)
index 0000000..6efbf3d
--- /dev/null
@@ -0,0 +1,29 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+import org.openflow.protocol.statistics.OFStatisticsType;
+
+
+public class OFStatisticsTypeTest extends TestCase {
+    @Test
+    public void testMapping() throws Exception {
+        TestCase.assertEquals(OFStatisticsType.DESC,
+                OFStatisticsType.valueOf((short) 0, OFType.STATS_REQUEST));
+        TestCase.assertEquals(OFStatisticsType.QUEUE,
+                OFStatisticsType.valueOf((short) 5, OFType.STATS_REQUEST));
+        TestCase.assertEquals(OFStatisticsType.VENDOR,
+                OFStatisticsType.valueOf((short) 0xffff, OFType.STATS_REQUEST));
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFTypeTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFTypeTest.java
new file mode 100644 (file)
index 0000000..7c7275d
--- /dev/null
@@ -0,0 +1,31 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+
+public class OFTypeTest extends TestCase {
+
+    public void testOFTypeCreate() throws Exception {
+        OFType foo = OFType.HELLO;
+        Class<? extends OFMessage> c = foo.toClass();
+        TestCase.assertEquals(c, OFHello.class);
+    }
+
+    @Test
+    public void testMapping() throws Exception {
+        TestCase.assertEquals(OFType.HELLO, OFType.valueOf((byte) 0));
+        TestCase.assertEquals(OFType.BARRIER_REPLY, OFType.valueOf((byte) 19));
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/OFVendorTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/OFVendorTest.java
new file mode 100644 (file)
index 0000000..307b47f
--- /dev/null
@@ -0,0 +1,29 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol;
+
+import java.nio.ByteBuffer;
+
+import junit.framework.TestCase;
+
+import org.openflow.util.OFTestCase;
+
+public class OFVendorTest extends OFTestCase {
+    public void testWriteRead() throws Exception {
+        OFVendor msg = (OFVendor) messageFactory.getMessage(OFType.VENDOR);
+        msg.setVendor(1);
+        ByteBuffer bb = ByteBuffer.allocate(1024);
+        bb.clear();
+        msg.writeTo(bb);
+        bb.flip();
+        msg.readFrom(bb);
+        TestCase.assertEquals(1, msg.getVendor());
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/protocol/queue/OFQueuePropertyTypeTest.java b/third-party/openflowj/src/test/java/org/openflow/protocol/queue/OFQueuePropertyTypeTest.java
new file mode 100644 (file)
index 0000000..79b0fb2
--- /dev/null
@@ -0,0 +1,26 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.protocol.queue;
+
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+
+public class OFQueuePropertyTypeTest extends TestCase {
+    @Test
+    public void testMapping() throws Exception {
+        TestCase.assertEquals(OFQueuePropertyType.NONE,
+                OFQueuePropertyType.valueOf((short) 0));
+        TestCase.assertEquals(OFQueuePropertyType.MIN_RATE,
+                OFQueuePropertyType.valueOf((short) 1));
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/util/HexStringTest.java b/third-party/openflowj/src/test/java/org/openflow/util/HexStringTest.java
new file mode 100644 (file)
index 0000000..54c805a
--- /dev/null
@@ -0,0 +1,36 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.util;
+
+import junit.framework.TestCase;
+
+/**
+ * Does hexstring conversion work?
+ * 
+ * @author Rob Sherwood (rob.sherwood@stanford.edu)
+ * 
+ */
+
+public class HexStringTest extends TestCase {
+
+    public void testMarshalling() throws Exception {
+        String dpidStr = "00:00:00:23:20:2d:16:71";
+        long dpid = HexString.toLong(dpidStr);
+        String testStr = HexString.toHexString(dpid);
+        TestCase.assertEquals(dpidStr, testStr);
+    }
+
+    public void testToStringBytes() {
+        byte[] dpid = { 0, 0, 0, 0, 0, 0, 0, -1 };
+        String valid = "00:00:00:00:00:00:00:ff";
+        String testString = HexString.toHexString(dpid);
+        TestCase.assertEquals(valid, testString);
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/util/OFTestCase.java b/third-party/openflowj/src/test/java/org/openflow/util/OFTestCase.java
new file mode 100644 (file)
index 0000000..7ec2577
--- /dev/null
@@ -0,0 +1,28 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.util;
+
+import org.openflow.protocol.factory.BasicFactory;
+import org.openflow.protocol.factory.OFMessageFactory;
+
+import junit.framework.TestCase;
+
+public class OFTestCase extends TestCase {
+    public OFMessageFactory messageFactory;
+    
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        messageFactory = new BasicFactory();
+    }
+
+    public void test() throws Exception {
+    }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/util/U16Test.java b/third-party/openflowj/src/test/java/org/openflow/util/U16Test.java
new file mode 100644 (file)
index 0000000..8edd90a
--- /dev/null
@@ -0,0 +1,25 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.util;
+
+import junit.framework.TestCase;
+
+public class U16Test extends TestCase {
+  /**
+   * Tests that we correctly translate unsigned values in and out of a short
+   * @throws Exception
+   */
+  public void test() throws Exception {
+      int val = 0xffff;
+      TestCase.assertEquals((short)-1, U16.t(val));
+      TestCase.assertEquals((short)32767, U16.t(0x7fff));
+      TestCase.assertEquals(val, U16.f((short)-1));
+  }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/util/U32Test.java b/third-party/openflowj/src/test/java/org/openflow/util/U32Test.java
new file mode 100644 (file)
index 0000000..470ef69
--- /dev/null
@@ -0,0 +1,24 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.util;
+
+import junit.framework.TestCase;
+
+public class U32Test extends TestCase {
+  /**
+   * Tests that we correctly translate unsigned values in and out of an int
+   * @throws Exception
+   */
+  public void test() throws Exception {
+      long val = 0xffffffffL;
+      TestCase.assertEquals(-1, U32.t(val));
+      TestCase.assertEquals(val, U32.f(-1));
+  }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/util/U64Test.java b/third-party/openflowj/src/test/java/org/openflow/util/U64Test.java
new file mode 100644 (file)
index 0000000..c9e815c
--- /dev/null
@@ -0,0 +1,26 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.util;
+
+import java.math.BigInteger;
+
+import junit.framework.TestCase;
+
+public class U64Test extends TestCase {
+  /**
+   * Tests that we correctly translate unsigned values in and out of a long
+   * @throws Exception
+   */
+  public void test() throws Exception {
+      BigInteger val = new BigInteger("ffffffffffffffff", 16);
+      TestCase.assertEquals(-1, U64.t(val));
+      TestCase.assertEquals(val, U64.f(-1));
+  }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/util/U8Test.java b/third-party/openflowj/src/test/java/org/openflow/util/U8Test.java
new file mode 100644 (file)
index 0000000..1205dfc
--- /dev/null
@@ -0,0 +1,24 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.util;
+
+import junit.framework.TestCase;
+
+public class U8Test extends TestCase {
+  /**
+   * Tests that we correctly translate unsigned values in and out of a byte
+   * @throws Exception
+   */
+  public void test() throws Exception {
+      short val = 0xff;
+      TestCase.assertEquals(-1, U8.t(val));
+      TestCase.assertEquals(val, U8.f((byte)-1));
+  }
+}
diff --git a/third-party/openflowj/src/test/java/org/openflow/util/UnsignedTest.java b/third-party/openflowj/src/test/java/org/openflow/util/UnsignedTest.java
new file mode 100644 (file)
index 0000000..c65c5da
--- /dev/null
@@ -0,0 +1,75 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.openflow.util;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+
+import junit.framework.TestCase;
+
+public class UnsignedTest extends TestCase {
+    public static String ULONG_MAX = "18446744073709551615";
+
+  /**
+   * Tests that we correctly extract an unsigned long into a BigInteger
+   * @throws Exception
+   */
+  public void testGetUnsignedLong() throws Exception {
+    ByteBuffer bb = ByteBuffer.allocate(8);
+    bb.put((byte)0xff).put((byte)0xff).put((byte)0xff).put((byte)0xff);
+    bb.put((byte)0xff).put((byte)0xff).put((byte)0xff).put((byte)0xff);
+    bb.position(0);
+    bb.limit(8);
+    BigInteger bi = Unsigned.getUnsignedLong(bb);
+    BigInteger uLongMax = new BigInteger(ULONG_MAX);
+    for (int i = 0; i < uLongMax.bitCount(); ++i) {
+        TestCase.assertTrue("Bit: " + i + " should be: " + uLongMax.testBit(i),
+                uLongMax.testBit(i) == bi.testBit(i));
+    }
+    TestCase.assertEquals(ULONG_MAX, bi.toString());
+
+    bb = ByteBuffer.allocate(10);
+    bb.put((byte)0x00);
+    bb.put((byte)0xff).put((byte)0xff).put((byte)0xff).put((byte)0xff);
+    bb.put((byte)0xff).put((byte)0xff).put((byte)0xff).put((byte)0xff);
+    bb.put((byte)0x00);
+    bb.position(0);
+    bb.limit(10);
+    bi = Unsigned.getUnsignedLong(bb, 1);
+    uLongMax = new BigInteger(ULONG_MAX);
+    for (int i = 0; i < uLongMax.bitCount(); ++i) {
+        TestCase.assertTrue("Bit: " + i + " should be: " + uLongMax.testBit(i),
+                uLongMax.testBit(i) == bi.testBit(i));
+    }
+    TestCase.assertEquals(ULONG_MAX, bi.toString());
+  }
+
+  /**
+   * Tests that we correctly put an unsigned long into a ByteBuffer
+   * @throws Exception
+   */
+  public void testPutUnsignedLong() throws Exception {
+    ByteBuffer bb = ByteBuffer.allocate(8);
+    BigInteger uLongMax = new BigInteger(ULONG_MAX);
+    Unsigned.putUnsignedLong(bb, uLongMax);
+    for (int i = 0; i < 8; ++i) {
+        TestCase.assertTrue("Byte: " + i + " should be 0xff, was: " + bb.get(i),
+                (bb.get(i) & (short)0xff) == 0xff);
+    }
+
+    bb = ByteBuffer.allocate(10);
+    Unsigned.putUnsignedLong(bb, uLongMax, 1);
+    int offset = 1;
+    for (int i = 0; i < 8; ++i) {
+        TestCase.assertTrue("Byte: " + i + " should be 0xff, was: " +
+                bb.get(offset+i), (bb.get(offset+i) & (short)0xff) == 0xff);
+    }
+  }
+}