[ONOS-4240, ONOS-4241] Support wide community optional path attribute

Change-Id: I59f9c4b69e8c26702ab955d58655497a394b9ec9
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/WideCommunityAttrHeader.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/WideCommunityAttrHeader.java
new file mode 100644
index 0000000..47e1014
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/WideCommunityAttrHeader.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed 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.
+ */
+package org.onosproject.bgpio.types;
+
+import com.google.common.base.MoreObjects;
+
+import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.util.Validation;
+import org.jboss.netty.buffer.ChannelBuffer;
+
+import java.util.Objects;
+
+/**
+ * Provides implementation of BGP wide community attribute header.
+ */
+public class WideCommunityAttrHeader implements BgpValueType {
+
+ /* 0                   1                   2                   3
+      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |             Type              |     Flags     |   Hop Count   |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |            Length             |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/
+
+    /*FLAG
+      +------+-------+----------------------------------------------------+
+      | Bit  | Value | Meaning                                            |
+      +------+-------+----------------------------------------------------+
+      |  0   |   0   | Local community value.                             |
+      |      |   1   | Registered community value.                        |
+      |  1   |   0   | Do not decrement Hop Count field across            |
+      |      |       | confederation boundaries.                          |
+      |      |   1   | Decrement Hop Count field across confederation     |
+      |      |       | boundaries.                                        |
+      | 2..7 |   -   | MUST be zero when sent and ignored upon receipt.   |
+      +------+-------+----------------------------------------------------+*/
+
+    public static final short TYPE = 1;
+    public static final short HEADER_LENGTH = 6;
+    private byte flag;
+    private byte hopCount;
+    private short length;
+
+    /**
+     * Wide community attribute header.
+     *
+     * @param flag to apply to all wide community container types
+     * @param hopCount represents the forwarding radius, in units of AS hops, for the given Wide BGP Community
+     * @param length field represents the total length of a given container
+     */
+    public WideCommunityAttrHeader(byte flag, byte hopCount, short length) {
+        this.flag = flag;
+        this.hopCount = hopCount;
+        this.length = length;
+    }
+
+    /**
+     * Returns object of this class with specified values.
+     *
+     * @param flag flag to apply to all wide community container types
+     * @param hopCount represents the forwarding radius, in units of AS hops, for the given Wide BGP Community
+     * @param length field represents the total length of a given container
+     * @return wide community attribute header
+     */
+    public static WideCommunityAttrHeader of(byte flag, byte hopCount, short length) {
+        return new WideCommunityAttrHeader(flag, hopCount, length);
+    }
+
+    /**
+     * Returns wide community flag.
+     *
+     * @return wide community flag
+     */
+    public byte flag() {
+        return flag;
+    }
+
+    /**
+     * Sets wide community flag.
+     *
+     * @param flag to apply to all wide community container types
+     */
+    public void setFlag(byte flag) {
+        this.flag = flag;
+    }
+
+    /**
+     * Returns hop count for wide community attribute.
+     *
+     * @return hop count from wide community
+     */
+    public byte hopCount() {
+        return hopCount;
+    }
+
+    /**
+     * Sets wide community hop count.
+     *
+     * @param hopCount represents the forwarding radius, in units of AS hops, for the given Wide BGP Community
+     */
+    public void setHopCount(byte hopCount) {
+        this.hopCount = hopCount;
+    }
+
+    /**
+     * Returns length of wide community attribute.
+     *
+     * @return length of wide community attribute
+     */
+    public short length() {
+        return length;
+    }
+
+    /**
+     * Sets wide community length.
+     *
+     * @param length total length of a given container
+     */
+    public void setLength(short length) {
+        this.length = length;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(flag, hopCount, length);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj == null) {
+            return false;
+        }
+
+        if (obj instanceof WideCommunityAttrHeader) {
+            WideCommunityAttrHeader other = (WideCommunityAttrHeader) obj;
+            return Objects.equals(flag, other.flag) && Objects.equals(hopCount, other.hopCount)
+                    && Objects.equals(length, other.length);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeByte(flag);
+        c.writeByte(hopCount);
+        c.writeShort(length);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of WideCommunityAttrHeader.
+     *
+     * @param c ChannelBuffer
+     * @return object of WideCommunityAttrHeader
+     */
+    public static WideCommunityAttrHeader read(ChannelBuffer c) throws BgpParseException {
+
+        if (c.readableBytes() < HEADER_LENGTH) {
+            Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR,
+                                   BgpErrorType.ATTRIBUTE_LENGTH_ERROR, c.readableBytes());
+        }
+
+        short type = c.readShort();
+        byte flag = c.readByte();
+        byte hopCount = c.readByte();
+        short length = c.readShort();
+        return WideCommunityAttrHeader.of(flag, hopCount, length);
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("Type", TYPE)
+                .add("flag", flag)
+                .add("hopCount", hopCount)
+                .add("length", length)
+                .toString();
+    }
+
+    @Override
+    public int compareTo(Object o) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+}
\ No newline at end of file