Refactor PCMM aspects of COPS message data objects.
[packetcable.git] / packetcable-driver / src / main / java / org / pcmm / gates / impl / DOCSISServiceClassNameTrafficProfile.java
index 382b08a3df81e764673cb06e8ec25a87028ad6cc..528bb2357aff19007a5268ead102f053528d3bd5 100644 (file)
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc.  All rights reserved.
  */
+
 package org.pcmm.gates.impl;
 
 import org.pcmm.base.impl.PCMMBaseObject;
 import org.pcmm.gates.ITrafficProfile;
 
+import java.util.Arrays;
+
 /**
+ * The DOCSIS Service Class Name object defines the preconfigured Service Class Name associated with a Gate.
  *
  */
-public class DOCSISServiceClassNameTrafficProfile extends PCMMBaseObject
-            implements ITrafficProfile {
+public class DOCSISServiceClassNameTrafficProfile extends PCMMBaseObject implements ITrafficProfile {
 
     public static final byte STYPE = 2;
-    public static final short LENGTH = 24;
+    public static final int SCN_MAX_LEN = 16;
 
     /**
-     *
+     * The Service Class Name. REQUIRED and length must be >= 2 and <= 16 characters
      */
-    public DOCSISServiceClassNameTrafficProfile() {
-        this(LENGTH, STYPE, SNUM);
-    }
+    private final String scnName;
 
     /**
-     * @param data - the data bytes to parse
+     * The envelope
      */
-    public DOCSISServiceClassNameTrafficProfile(byte[] data) {
-        super(data);
-    }
+    private final byte envelope;
 
     /**
-     * @param len - the classifier's length
-     * @param sType - the sType value
-     * @param sNum - the sNum value
+     * Constructor using the default envelope value
+     * @param scnName - the service class name (required characters >=2 && <=16
      */
-    public DOCSISServiceClassNameTrafficProfile(short len, byte sType, byte sNum) {
-        super(len, sType, sNum);
-        setEnvelop((byte) 0x7);
+    public DOCSISServiceClassNameTrafficProfile(final String scnName) {
+        this(DEFAULT_ENVELOP, scnName);
     }
 
     /**
-     * @return the serviceClassName
+     * Constructor to set all values
+     * @param envelope - the envelope value
+     * @param scnName - the service class name (required number of characters >=2 && <=16)
      */
-    public String getServiceClassName() {
-        return new String(getBytes((short) 4, (short) 4));
+    protected DOCSISServiceClassNameTrafficProfile(final byte envelope, final String scnName) {
+        super(SNum.TRAFFIC_PROFILE, STYPE);
+        if (scnName == null || scnName.length() < 2 || scnName.length() > SCN_MAX_LEN)
+            throw new IllegalArgumentException("Service class name must be between 2-16 characters");
+        this.scnName = scnName;
+        this.envelope = envelope;
+    }
+
+    @Override
+    public byte getEnvelop() {
+        return envelope;
     }
 
     /**
-     * @param serviceClassName
-     *            the serviceClassName to set
+     * Returns the service class name value
+     * @return - the SCN value
      */
-    public void setServiceClassName(String serviceClassName) {
-        setBytes(serviceClassName.getBytes(), (short) 4);
+    public String getScnName() {
+        return scnName;
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.pcmm.gates.ITrafficProfile#getEnvelop()
-     */
     @Override
-    public byte getEnvelop() {
-        return getBytes((short) 0, (short) 1)[0];
+    protected byte[] getBytes() {
+        final int padLen;
+        if ((scnName.length() % 4) != 0) padLen = 4 - (scnName.length() % 4);
+        else padLen = 0;
+
+        final byte[] data = new byte[4 + scnName.getBytes().length + padLen];
+        Arrays.fill(data, (byte) 0);
+        data[0] = envelope;
+
+        System.arraycopy(scnName.getBytes(), 0, data, 4, scnName.getBytes().length);
+        return data;
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof DOCSISServiceClassNameTrafficProfile)) {
+            return false;
+        }
+        if (!super.equals(o)) {
+            return false;
+        }
+        final DOCSISServiceClassNameTrafficProfile that = (DOCSISServiceClassNameTrafficProfile) o;
+        return envelope == that.envelope && scnName.equals(that.scnName);
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.pcmm.gates.ITrafficProfile#setEnvelop(byte)
-     */
     @Override
-    public void setEnvelop(byte en) {
-        setBytes(new byte[] { en }, (short) 0);
+    public int hashCode() {
+        int result = super.hashCode();
+        result = 31 * result + scnName.hashCode();
+        result = 31 * result + (int) envelope;
+        return result;
     }
+
+    /**
+     * Returns a DOCSISServiceClassNameTrafficProfile object from a byte array
+     * @param data - the data to parse
+     * @return - the object
+     * TODO - make me more robust as RuntimeExceptions can be thrown here.
+     */
+    public static DOCSISServiceClassNameTrafficProfile parse(final byte[] data) {
+        // variable i will denote the index where the data padding starts (if any) or the end of the array
+        int i = 4;
+        for (; i < data.length; i++) {
+            if (data[i] == 0) {
+                break;
+            }
+        }
+        final int nameLength = i - 4;
+
+        final byte[] scnNameBytes = new byte[nameLength];
+        System.arraycopy(data, 4, scnNameBytes, 0, nameLength);
+        final String scnName = new String(scnNameBytes);
+        return new DOCSISServiceClassNameTrafficProfile(data[0], scnName);
+    }
+
 }