/*
* JBoss, Home of Professional Open Source
* Copyright 2011, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.mobicents.protocols.ss7.m3ua.impl.parameter;
import java.nio.ByteBuffer;
import javolution.text.TextBuilder;
import javolution.util.FastList;
import javolution.xml.XMLFormat;
import javolution.xml.XMLSerializable;
import javolution.xml.stream.XMLStreamException;
import org.mobicents.protocols.ss7.m3ua.parameter.DestinationPointCode;
import org.mobicents.protocols.ss7.m3ua.parameter.LocalRKIdentifier;
import org.mobicents.protocols.ss7.m3ua.parameter.NetworkAppearance;
import org.mobicents.protocols.ss7.m3ua.parameter.OPCList;
import org.mobicents.protocols.ss7.m3ua.parameter.Parameter;
import org.mobicents.protocols.ss7.m3ua.parameter.RoutingContext;
import org.mobicents.protocols.ss7.m3ua.parameter.RoutingKey;
import org.mobicents.protocols.ss7.m3ua.parameter.ServiceIndicators;
import org.mobicents.protocols.ss7.m3ua.parameter.TrafficModeType;
/**
*
* @author amit bhayani
*
*/
public class RoutingKeyImpl extends ParameterImpl implements RoutingKey, XMLSerializable {
private static final String LOCAL_RK_ID = "localRkId";
private static final String ROUTING_CONTEXT = "rc";
private static final String TRAFFIC_MODE = "trafficMode";
private static final String NETWORK_APPEARANCE = "netAppearance";
private static final String DPCS = "dpcs";
private static final String DPC_ARRAY_SIZE = "dpcsSize";
private static final String SIS = "sis";
private static final String SI_ARRAY_SIZE = "sisSize";
private static final String OPC_LIST = "opcList";
private static final String OPC_ARRAY_SIZE = "opcSize";
private LocalRKIdentifier localRkId;
private RoutingContext rc;
private TrafficModeType trafMdTy;
private NetworkAppearance netApp;
private DestinationPointCode[] dpc;
private ServiceIndicators[] servInds;
private OPCList[] opcList;
private ByteBuffer buffer = ByteBuffer.allocate(256);
private byte[] value;
public RoutingKeyImpl() {
this.tag = Parameter.Routing_Key;
}
protected RoutingKeyImpl(byte[] value) {
this.tag = Parameter.Routing_Key;
this.value = value;
this.decode(value);
this.value = value;
}
protected RoutingKeyImpl(LocalRKIdentifier localRkId, RoutingContext rc, TrafficModeType trafMdTy,
NetworkAppearance netApp, DestinationPointCode[] dpc, ServiceIndicators[] servInds, OPCList[] opcList) {
this.tag = Parameter.Routing_Key;
this.localRkId = localRkId;
this.rc = rc;
this.trafMdTy = trafMdTy;
this.netApp = netApp;
this.dpc = dpc;
this.servInds = servInds;
this.opcList = opcList;
this.encode();
}
private void decode(byte[] data) {
int pos = 0;
FastList<DestinationPointCode> dpcList = new FastList<DestinationPointCode>();
FastList<ServiceIndicators> serIndList = new FastList<ServiceIndicators>();
FastList<OPCList> opcListList = new FastList<OPCList>();
while (pos < data.length) {
short tag = (short) ((data[pos] & 0xff) << 8 | (data[pos + 1] & 0xff));
short len = (short) ((data[pos + 2] & 0xff) << 8 | (data[pos + 3] & 0xff));
byte[] value = new byte[len - 4];
System.arraycopy(data, pos + 4, value, 0, value.length);
pos += len;
// parameters.put(tag, factory.createParameter(tag, value));
switch (tag) {
case ParameterImpl.Local_Routing_Key_Identifier:
this.localRkId = new LocalRKIdentifierImpl(value);
break;
case ParameterImpl.Routing_Context:
this.rc = new RoutingContextImpl(value);
break;
case ParameterImpl.Traffic_Mode_Type:
this.trafMdTy = new TrafficModeTypeImpl(value);
break;
case ParameterImpl.Network_Appearance:
this.netApp = new NetworkAppearanceImpl(value);
break;
case ParameterImpl.Destination_Point_Code:
dpcList.add(new DestinationPointCodeImpl(value));
break;
case ParameterImpl.Service_Indicators:
serIndList.add(new ServiceIndicatorsImpl(value));
break;
case ParameterImpl.Originating_Point_Code_List:
opcListList.add(new OPCListImpl(value));
break;
}
// The Parameter Length does not include any padding octets. We have
// to consider padding here
pos += (pos % 4);
}// end of while
this.dpc = new DestinationPointCode[dpcList.size()];
this.dpc = dpcList.toArray(this.dpc);
if (serIndList.size() > 0) {
this.servInds = new ServiceIndicators[serIndList.size()];
this.servInds = serIndList.toArray(this.servInds);
}
if (opcListList.size() > 0) {
this.opcList = new OPCList[opcListList.size()];
this.opcList = opcListList.toArray(this.opcList);
}
}
private void encode() {
if (this.localRkId != null) {
((LocalRKIdentifierImpl) this.localRkId).write(buffer);
}
if (this.rc != null) {
((RoutingContextImpl) rc).write(buffer);
}
if (this.trafMdTy != null) {
((TrafficModeTypeImpl) trafMdTy).write(buffer);
}
if (this.netApp != null) {
((NetworkAppearanceImpl) this.netApp).write(buffer);
}
for (int i = 0; i < this.dpc.length; i++) {
((DestinationPointCodeImpl) this.dpc[i]).write(buffer);
if (this.servInds != null) {
((ServiceIndicatorsImpl) this.servInds[i]).write(buffer);
}
if (this.opcList != null) {
((OPCListImpl) this.opcList[i]).write(buffer);
}
}
this.value = new byte[buffer.position()];
buffer.flip();
buffer.get(this.value);
}
@Override
protected byte[] getValue() {
return this.value;
}
public DestinationPointCode[] getDestinationPointCodes() {
return this.dpc;
}
public LocalRKIdentifier getLocalRKIdentifier() {
return this.localRkId;
}
public NetworkAppearance getNetworkAppearance() {
return this.netApp;
}
public OPCList[] getOPCLists() {
return this.opcList;
}
public RoutingContext getRoutingContext() {
return this.rc;
}
public ServiceIndicators[] getServiceIndicators() {
return this.servInds;
}
public TrafficModeType getTrafficModeType() {
return this.trafMdTy;
}
@Override
public String toString() {
TextBuilder tb = TextBuilder.newInstance();
tb.append("RoutingKey(");
if (localRkId != null) {
tb.append(localRkId.toString());
}
if (rc != null) {
tb.append(rc.toString());
}
if (trafMdTy != null) {
tb.append(trafMdTy.toString());
}
if (netApp != null) {
tb.append(netApp.toString());
}
if (dpc != null) {
tb.append(dpc.toString());
}
if (servInds != null) {
tb.append(servInds.toString());
}
if (opcList != null) {
tb.append(opcList.toString());
}
tb.append(")");
return tb.toString();
}
/**
* XML Serialization/Deserialization
*/
protected static final XMLFormat<RoutingKeyImpl> RC_XML = new XMLFormat<RoutingKeyImpl>(RoutingKeyImpl.class) {
@Override
public void read(javolution.xml.XMLFormat.InputElement xml, RoutingKeyImpl routingKey) throws XMLStreamException {
int dpcArraySize = xml.getAttribute(DPC_ARRAY_SIZE).toInt();
int opcArraySize = xml.getAttribute(OPC_ARRAY_SIZE).toInt();
int siArraySize = xml.getAttribute(SI_ARRAY_SIZE).toInt();
routingKey.localRkId = xml.get(LOCAL_RK_ID);
routingKey.rc = xml.get(ROUTING_CONTEXT);
routingKey.trafMdTy = xml.get(TRAFFIC_MODE);
routingKey.netApp = xml.get(NETWORK_APPEARANCE);
if (dpcArraySize != -1) {
routingKey.dpc = new DestinationPointCodeImpl[dpcArraySize];
for (int i = 0; i < dpcArraySize; i++) {
routingKey.dpc[i] = xml.get(DPCS);
}
}
if (opcArraySize != -1) {
routingKey.opcList = new OPCList[opcArraySize];
for (int i = 0; i < opcArraySize; i++) {
routingKey.opcList[i] = xml.get(OPC_LIST);
}
}
if (siArraySize != -1) {
routingKey.servInds = new ServiceIndicators[siArraySize];
for (int i = 0; i < siArraySize; i++) {
routingKey.servInds[i] = xml.get(SIS);
}
}
routingKey.encode();
}
@Override
public void write(RoutingKeyImpl routingKey, javolution.xml.XMLFormat.OutputElement xml) throws XMLStreamException {
if (routingKey.dpc != null) {
xml.setAttribute(DPC_ARRAY_SIZE, routingKey.dpc.length);
} else {
xml.setAttribute(DPC_ARRAY_SIZE, -1);
}
if (routingKey.opcList != null) {
xml.setAttribute(OPC_ARRAY_SIZE, routingKey.opcList.length);
} else {
xml.setAttribute(OPC_ARRAY_SIZE, -1);
}
if (routingKey.servInds != null) {
xml.setAttribute(SI_ARRAY_SIZE, routingKey.servInds.length);
} else {
xml.setAttribute(SI_ARRAY_SIZE, -1);
}
xml.add(routingKey.localRkId, LOCAL_RK_ID);
xml.add(routingKey.rc, ROUTING_CONTEXT);
xml.add(routingKey.trafMdTy, TRAFFIC_MODE);
xml.add(routingKey.netApp, NETWORK_APPEARANCE);
if (routingKey.dpc != null) {
for (int i = 0; i < routingKey.dpc.length; i++) {
xml.add(routingKey.dpc[i], DPCS);
}
}
if (routingKey.opcList != null) {
for (int i = 0; i < routingKey.opcList.length; i++) {
xml.add(routingKey.opcList[i], OPC_LIST);
}
}
if (routingKey.servInds != null) {
for (int i = 0; i < routingKey.servInds.length; i++) {
xml.add(routingKey.servInds[i], SIS);
}
}
}
};
}