RoutingKey.java
/*
** Module : RoutingKey.java
** Abstract : contains routing information
**
** Copyright (c) 2005-2017, Golden Code Development Corporation.
**
** -#- -I- --Date-- -T- --JPRM-- ----------------Description-----------------
** 001 SIY 20050120 ADD @19506 Created initial version.
** 002 SIY 20050211 ADD @19773 Added copy-constructor and replacement for
** the standard object reading/writing methods.
** 003 SIY 20050315 CHG @20390 Organized imports and other minor cleanups.
** 004 SIY 20050329 CHG @20549 Fixed comments, added constant for shutdown()
** entry point.
** 005 NVS 20050418 CHG @20766 Added new public method getSpecial for
** creating special routing keys.
** 006 NVS 20060210 CHG @24509 Added another special system routing key:
** INTERRUPT_SESSION.
** 007 GES 20060801 CHG @28289 Converted to Externalizable to improve
** efficiency because Serializable has unneeded
** processing (for versioning...) that is
** executed on "inflation".
** 008 ECF 20071112 CHG @35888 Refactored net package. Renamed
** TERMINATE_SESSION to TERMINATE_REMOTE.
** Changed ID-related method names to match
** coding standards.
** 009 ES 20240619 Added another special system routing key:
** SERVER_INTERRUPT.
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program 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 Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.net;
import java.io.*;
/**
* RoutingKey holds all information related message routing, both external
* routing (source and destination node addresses) and internal routing
* (exported entry point IDs).
*
* @author SIY
*/
public final class RoutingKey
implements Externalizable
{
/** getRoutingKey() special entry point */
public static final int GET_ROUTING_KEY = -1;
/** authenticateRemote() special entry point */
public static final int AUTHENTICATE_REMOTE = -2;
/** terminateRemote() special entry point */
public static final int TERMINATE_REMOTE = -3;
/** shutdown() special entry point */
public static final int SHUTDOWN_PACKAGE = -4;
/** interruptSession() special entry point */
public static final int INTERRUPT_SESSION = -5;
/** serverInterrupt() special entry point */
public static final int SERVER_INTERRUPT = -6;
/** Security context ID */
private int contextID;
/** Destination node address */
private int destination;
/** Method group ID */
private int groupID;
/** Method in the group ID */
private int methodID;
/** Source node address */
private int source;
/**
* Construct a default <code>RoutingKey</code> instance. By convention it
* points to the getRoutingKey() special entry point (exported by
* <code>Dispatcher</code>).
*/
public RoutingKey()
{
this(GET_ROUTING_KEY);
}
/**
* Construct a <code>RoutingKey</code> instance for special entry point.
*
* @param special
* This is an ID which will be assigned to groupID and methodID.
*/
RoutingKey(int special)
{
this(special, special, 0, 0, 0);
}
/**
* Construct an instance with specified groupID and methodID. This
* constructor is used by <code>Dispatcher</code> for generation of valid
* RoutingKey instances for exported entry points created by the
* application (unlike special entry points which are created
* artificially).
*
* @param groupID
* Method group ID.
* @param methodID
* Method ID.
*/
RoutingKey(int groupID, int methodID)
{
this(groupID, methodID, 0, 0, 0);
}
/**
* Construct a key from other routing key.
*
* @param other
* Instance which is used as a source.
*/
RoutingKey(RoutingKey other)
{
if (other != null)
{
source = other.source;
destination = other.destination;
groupID = other.groupID;
methodID = other.methodID;
contextID = other.contextID;
}
}
/**
* Construct a complete instance. Used internally by other constructors.
*
* @param group
* Method group ID.
* @param method
* Method ID.
* @param context
* Security context ID.
* @param src
* Source node address.
* @param dst
* Destination node address.
*/
private RoutingKey(int group, int method, int context, int src, int dst)
{
source = src;
destination = dst;
groupID = group;
methodID = method;
contextID = context;
}
/**
* Creates a special routing key from "system" group.
*
* @param special
* This is an ID which will be assigned to groupID and methodID.
* Must be one of the following:
* <ul>
* <li>GET_ROUTING_KEY - equivalent of the default
* constructor;
* <li>SHUTDOWN_PACKAGE
* </ul>
*
* @return The newly created instance of RoutingKey or <code>null</code>
* if the parameter is invalid.
*/
public static RoutingKey getSpecial(int special)
{
if (special != GET_ROUTING_KEY && special != SHUTDOWN_PACKAGE)
return null;
return new RoutingKey(special, special, 0, 0, 0);
}
/**
* Compare two instances.
*
* @param obj
* An object to compare with.
*
* @return <code>true</code> if the two keys are identical.
*/
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj instanceof RoutingKey)
{
RoutingKey key = (RoutingKey) obj;
if (getGroupID() != key.getGroupID())
return false;
if (getMethodID() != key.getMethodID())
return false;
return true;
}
return false;
}
/**
* Provide access to the destination node address.
*
* @return The destination node address.
*/
public int getDestinationAddress()
{
return destination;
}
/**
* Provide access to the source node address.
*
* @return The source node address.
*/
public int getSourceAddress()
{
return source;
}
/**
* Generate a hash code for use by HashMap.
*
* @return The hash code.
*/
public int hashCode()
{
return ((groupID << 16) | methodID);
}
/**
* Assign new destination node address.
*
* @param dst
* The destination node address.
*/
public void setDestinationAddress(int dst)
{
destination = dst;
}
/**
* Assign new source node address.
*
* @param src
* The source node address.
*/
public void setSourceAddress(int src)
{
source = src;
}
/**
* Replacement for the default object reading method. It is meant to be
* be called by containing objects rather than by the J2SE infrastructure
* but the standard signature and name are used.
*
* @param in
* Input source from which fields will be restored.
*
* @throws IOException
* In case of I/O errors.
* @throws ClassNotFoundException
* If the payload can't be instantiated.
*/
public void readExternal(ObjectInput in)
throws IOException,
ClassNotFoundException
{
source = in.readInt();
destination = in.readInt();
groupID = in.readInt();
methodID = in.readInt();
contextID = in.readInt();
}
/**
* Replacement for the default object writing method. It is meant to be
* be called by containing objects rather than by the J2SE infrastructure
* but the standard signature and name are used.
*
* @param out
* The output destination to which fields will be saved.
*
* @throws IOException
* In case of I/O errors.
*/
public void writeExternal(ObjectOutput out)
throws IOException
{
out.writeInt(source);
out.writeInt(destination);
out.writeInt(groupID);
out.writeInt(methodID);
out.writeInt(contextID);
}
/**
* Provide access to the security context ID.
*
* @return The security context ID.
*/
int getContextID()
{
return contextID;
}
/**
* Provide access to the method's group ID.
*
* @return The group ID.
*/
int getGroupID()
{
return groupID;
}
/**
* Provide access to the method ID.
*
* @return The method ID.
*/
int getMethodID()
{
return methodID;
}
/**
* Assign new security context ID
*
* @param contextID
* New security context ID.
*/
void setContextID(int contextID)
{
this.contextID = contextID;
}
/**
* Swap source and destination addresses. Convenient method when request
* message instance is used to prepare an reply message.
*/
void swapAddresses()
{
int tmp = source;
source = destination;
destination = tmp;
}
}