⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 session.java

📁 Short Message Peer to Peer
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
	private void safeGenericNack(int commandStatus, int sequenceNumber) throws IOException {
		try {
			genericNack(commandStatus, sequenceNumber);
		} catch (SmppException e) {
			debug.write("Ignoring unexpected SmppException caught sending generic nack.");
			event.write(e, "Ignoring unexpected exception caught sending generic nack.");
		}
	}

	/** 
	 * Sets the state of the session.
	 * It's private as it's only for use by the methods of the session.
	 * @param state the new state of the session
	 * @see #checkState(int)
	 * @see #checkState(PDU)
	 * @see WrongSessionStateException
	 */
	private void setState(int state) {
		this.state = state;
	}

	/**
	 * Returns the current state of the session.
	 * It's public to allow the user to check the state of the session if necessary.
	 * @return the current state of the session
	 * @see #checkState(int)
	 * @see #checkState(PDU)
	 * @see WrongSessionStateException
	 */
	public int getState() {
		return state;
	}

	/**
	 * Enables checking if the session allows certain operation in the current state.
	 */
	public void enableStateChecking() {
		this.stateChecking = true;
	}

	/**
	 * Disables checking if the session allows certain operation in the current state.
	 */
	public void disableStateChecking() {
		this.stateChecking = false;
	}

	/**
	 * Checks if the session is in the state which is required by the parameter.
	 * If not, then exception <code>WrongSessionStateException</code> is thrown.
	 * Note that the states are bit values in integer, so there can be a "set"
	 * of states required, the session must be in one of the states required.
	 * The checking can be turned off, see
	 * <a href="#disableStateChecking()">disableStateChecking</a>.
	 * @param requestedState the state(s) in which the session is expected to be; if it
	 *                       is not, then exception is thrown
	 * @throws WrongSessionStateException if the session is not in the state
	 *         required
	 * @see WrongSessionStateException
	 */
	public void checkState(int requestedState) throws WrongSessionStateException {
		if (stateChecking) {
			debug.write(
				DSESS,
				"checking state current=0x"
					+ Integer.toHexString(state)
					+ " requested esme=0x"
					+ Integer.toHexString(requestedState));
			if ((state & requestedState) == 0) {
				throw new WrongSessionStateException(type, requestedState, state);
			}
		}
	}

	/**
	 * Checks if the session's state allows sending the PDU provided.
	 * If not, then exception <code>WrongSessionStateException</code> is thrown.
	 * For each state there is only a subset of PDUs which can be sent over the
	 * session. For example, if the session is bound as a receiver, it cannot
	 * submit messages, but it can send enquire link, generic nack etc.
	 * This method checks the PDU type (command id) aganst matrix of allowed states.
	 * The checking can be turned off, see
	 * <a href="#disableStateChecking()">disableStateChecking</a>.
	 * @param pdu the pdu which has to be checked if it's allowed in the current
	 *            state
	 * @throws WrongSessionStateException if the session is not in the state
	 *         required
	 * @see #checkState(int)
	 * @see WrongSessionStateException
	 */
	public void checkState(PDU pdu) throws WrongSessionStateException {
		if (stateChecking) {
			Hashtable pduMatrix = getStateMatrix(type);
			Integer commandIdInteger = new Integer(pdu.getCommandId());
			Integer requestedStateInteger = pduMatrix == null ? null : (Integer) pduMatrix.get(commandIdInteger);
			if (requestedStateInteger != null) {
				checkState(requestedStateInteger.intValue());
			} else {
				if (disallowUnknownPDU) {
					throw new WrongSessionStateException();
				}
			}
		}
	}

	/**
	 * Checks if the session is in the state which is required by the parameter.
	 * Note that this method doesn't throw an exception rather it returns false
	 * if the session is not in one of the provided states.
	 * @param requestedState the state(s) which have to be checked
	 * @return if the session is in on of the provided states
	 * @see #checkState(int)
	 */
	public boolean isStateAllowed(int requestedState) {
		boolean stateAllowed = true;
		try {
			checkState(requestedState);
		} catch (WrongSessionStateException e) {
			stateAllowed = false;
		}
		return stateAllowed;
	}

	/**
	 * Checks if the pdu provided is allowed in the current session state.
	 * Note that this method doesn't throw an exception rather it returns false
	 * if the pdu is not alloewd in the current session state.
	 * @param pdu the pdu which has to be checked if it's allowed in the current
	 *            state
	 * @return if the pdu is allowed to be sent in the current session state
	 * @see #checkState(PDU)
	 */
	public boolean isPDUAllowed(PDU pdu) {
		boolean pduAllowed = true;
		try {
			checkState(pdu);
		} catch (WrongSessionStateException e) {
			pduAllowed = false;
		}
		return pduAllowed;
	}

	/**
	 * Initialises state matrices for checking if PDU is allowed in a certain session
	 * state.
	 */
	static {
		initialiseStateMatrix();
	}

	/**
	 * Initialise list containing which operations (PDUs) valid in which state.
	 * @see #checkState(PDU)
	 * @see #type
	 */
	private static void initialiseStateMatrix() {
		esmeStateMatrix = new Hashtable();
		addValidState(esmeStateMatrix, Data.BIND_TRANSMITTER, STATE_CLOSED);
		addValidState(esmeStateMatrix, Data.BIND_TRANSMITTER_RESP, STATE_NOT_ALLOWED);
		addValidState(esmeStateMatrix, Data.BIND_RECEIVER, STATE_CLOSED);
		addValidState(esmeStateMatrix, Data.BIND_RECEIVER_RESP, STATE_NOT_ALLOWED);
		addValidState(esmeStateMatrix, Data.BIND_TRANSCEIVER, STATE_CLOSED);
		addValidState(esmeStateMatrix, Data.BIND_TRANSCEIVER_RESP, STATE_NOT_ALLOWED);
		addValidState(esmeStateMatrix, Data.OUTBIND, STATE_NOT_ALLOWED);
		addValidState(esmeStateMatrix, Data.UNBIND, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
		addValidState(esmeStateMatrix, Data.UNBIND_RESP, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
		addValidState(esmeStateMatrix, Data.SUBMIT_SM, STATE_TRANSMITTER | STATE_TRANSCEIVER);
		addValidState(esmeStateMatrix, Data.SUBMIT_SM_RESP, STATE_NOT_ALLOWED);
		addValidState(esmeStateMatrix, Data.SUBMIT_MULTI, STATE_TRANSMITTER | STATE_TRANSCEIVER);
		addValidState(esmeStateMatrix, Data.SUBMIT_MULTI_RESP, STATE_NOT_ALLOWED);
		addValidState(esmeStateMatrix, Data.DATA_SM, STATE_TRANSMITTER | STATE_TRANSCEIVER);
		addValidState(esmeStateMatrix, Data.DATA_SM_RESP, STATE_RECEIVER | STATE_TRANSCEIVER);
		addValidState(esmeStateMatrix, Data.DELIVER_SM, STATE_NOT_ALLOWED);
		addValidState(esmeStateMatrix, Data.DELIVER_SM_RESP, STATE_RECEIVER | STATE_TRANSCEIVER);
		addValidState(esmeStateMatrix, Data.QUERY_SM, STATE_TRANSMITTER | STATE_TRANSCEIVER);
		addValidState(esmeStateMatrix, Data.QUERY_SM_RESP, STATE_NOT_ALLOWED);
		addValidState(esmeStateMatrix, Data.CANCEL_SM, STATE_TRANSMITTER | STATE_TRANSCEIVER);
		addValidState(esmeStateMatrix, Data.CANCEL_SM_RESP, STATE_NOT_ALLOWED);
		addValidState(esmeStateMatrix, Data.REPLACE_SM, STATE_TRANSMITTER | STATE_TRANSCEIVER);
		addValidState(esmeStateMatrix, Data.REPLACE_SM_RESP, STATE_NOT_ALLOWED);
		addValidState(esmeStateMatrix, Data.ENQUIRE_LINK, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
		// STATE_ALWAYS);
		addValidState(esmeStateMatrix, Data.ENQUIRE_LINK_RESP, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
		// STATE_ALWAYS);
		addValidState(esmeStateMatrix, Data.ALERT_NOTIFICATION, STATE_NOT_ALLOWED);
		addValidState(esmeStateMatrix, Data.GENERIC_NACK, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
		// STATE_ALWAYS);

		mcStateMatrix = new Hashtable();
		addValidState(mcStateMatrix, Data.BIND_TRANSMITTER, STATE_NOT_ALLOWED);
		addValidState(
			mcStateMatrix,
			Data.BIND_TRANSMITTER_RESP,
			STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
		// STATE_OPENED);
		addValidState(mcStateMatrix, Data.BIND_RECEIVER, STATE_NOT_ALLOWED);
		addValidState(mcStateMatrix, Data.BIND_RECEIVER_RESP, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
		// STATE_OPENED);
		addValidState(mcStateMatrix, Data.BIND_TRANSCEIVER, STATE_NOT_ALLOWED);
		addValidState(
			mcStateMatrix,
			Data.BIND_TRANSCEIVER_RESP,
			STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
		// STATE_OPENED);
		addValidState(mcStateMatrix, Data.OUTBIND, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
		// STATE_OPENED);
		addValidState(mcStateMatrix, Data.UNBIND, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
		addValidState(mcStateMatrix, Data.UNBIND_RESP, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
		addValidState(mcStateMatrix, Data.SUBMIT_SM, STATE_NOT_ALLOWED);
		addValidState(mcStateMatrix, Data.SUBMIT_SM_RESP, STATE_TRANSMITTER | STATE_TRANSCEIVER);
		addValidState(mcStateMatrix, Data.SUBMIT_MULTI, STATE_NOT_ALLOWED);
		addValidState(mcStateMatrix, Data.SUBMIT_MULTI_RESP, STATE_TRANSMITTER | STATE_TRANSCEIVER);
		addValidState(mcStateMatrix, Data.DATA_SM, STATE_RECEIVER | STATE_TRANSCEIVER);
		addValidState(mcStateMatrix, Data.DATA_SM_RESP, STATE_TRANSMITTER | STATE_TRANSCEIVER);
		addValidState(mcStateMatrix, Data.DELIVER_SM, STATE_RECEIVER | STATE_TRANSCEIVER);
		addValidState(mcStateMatrix, Data.DELIVER_SM_RESP, STATE_NOT_ALLOWED);
		addValidState(mcStateMatrix, Data.QUERY_SM, STATE_NOT_ALLOWED);
		addValidState(mcStateMatrix, Data.QUERY_SM_RESP, STATE_TRANSMITTER | STATE_TRANSCEIVER);
		addValidState(mcStateMatrix, Data.CANCEL_SM, STATE_NOT_ALLOWED);
		addValidState(mcStateMatrix, Data.CANCEL_SM_RESP, STATE_TRANSMITTER | STATE_TRANSCEIVER);
		addValidState(mcStateMatrix, Data.REPLACE_SM, STATE_NOT_ALLOWED);
		addValidState(mcStateMatrix, Data.REPLACE_SM_RESP, STATE_TRANSMITTER | STATE_TRANSCEIVER);
		addValidState(mcStateMatrix, Data.ENQUIRE_LINK, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
		// STATE_ALWAYS);
		addValidState(mcStateMatrix, Data.ENQUIRE_LINK_RESP, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
		// STATE_ALWAYS);
		addValidState(mcStateMatrix, Data.ALERT_NOTIFICATION, STATE_RECEIVER | STATE_TRANSCEIVER);
		addValidState(mcStateMatrix, Data.GENERIC_NACK, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
		// STATE_ALWAYS);
	}

	/**
	 * Adds to the matrix a set of states in which can be sent a PDU with the 
	 * provided command id.
	 * @param matrix the matrix to add the mapping to
	 * @param commandId the commandId of the PDU the mapping is created for
	 * @param state the state(s) in which is the PDU valid
	 * @see #checkState(PDU)
	 * @see #isStateAllowed(int)
	 */
	private static void addValidState(Hashtable matrix, int commandId, int state) {
		matrix.put(new Integer(commandId), new Integer(state));
	}

	/**
	 * Returns the state matrix for the requested session type.
	 * @see #type
	 * @see #TYPE_ESME
	 * @see #TYPE_MC
	 * @see #initialiseStateMatrix()
	 */
	private static Hashtable getStateMatrix(int type) {
		switch (type) {
			case TYPE_ESME :
				return esmeStateMatrix;
			case TYPE_MC :
				return mcStateMatrix;
			default :
				return null;
		}
	}

	/**
	 * God, I would never think that to keep unbind synchronous in
	 * an asynchronous enviroment would be so funny. Here is the replacement
	 * listener which encapsulates the original listener and hunts for the 
	 * unbind pdu. Good luck, you source code reader!<br>
	 * The problem is that we want to return a response from session's unbind()
	 * even if the session is asynchronous, i.e. all pdus from the smsc
	 * are passed to an implementation of <code>ServerPDUEventListener</code>
	 * event responses. We can't simply stop the asynchronicity
	 * as there can still be some responses expected, so we need a bridge
	 * which allows us to wait for the unbind response and still serve
	 * the other pdus from the smsc in asynchronous manner. Thus this
	 * encapsulating listener, which exactly does the thing.
	 */
	private class UnbindServerPDUEventListener extends SmppObject implements ServerPDUEventListener {
		Session session;
		ServerPDUEventListener origListener;
		Unbind unbindReq;
		UnbindResp expectedResp;
		UnbindResp unbindResp = null;

		public UnbindServerPDUEventListener(Session session, ServerPDUEventListener origListener, Unbind unbindReq) {
			this.session = session;
			this.origListener = origListener;
			this.unbindReq = unbindReq;
			expectedResp = (UnbindResp) unbindReq.getResponse();
		}

		public void handleEvent(ServerPDUEvent event) {
			PDU pdu = event.getPDU();
			if (pdu.getSequenceNumber() == unbindReq.getSequenceNumber()) {
				synchronized (this) {
					try {
						unbindResp = (UnbindResp) (session.checkResponse(pdu, expectedResp));
					} catch (Exception e) {
						debug.write(DSESS, "exception handling unbind " + e);
						SmppObject.event.write(e, "exception handling unbind");
					}
					// notify as session waits for the notification
					this.notify();
				}
			} else {
				// all other pdus are processed by the original handler,
				// if any
				if (origListener != null) {
					origListener.handleEvent(event);
				}
			}
		}

		public UnbindResp getUnbindResp() {
			return unbindResp;
		}
	}
}
/*
 * $Log: Session.java,v $
 * Revision 1.4  2006/03/09 16:24:14  sverkera
 * Removed compiler and javadoc warnings
 *
 * Revision 1.3  2006/02/22 16:45:01  paoloc
 * UnbindServerPDUEventListener: if (pdu.equals(unbindReq)): as reported by users, this is incompatible with the new improved PDU.equals(); fixed.
 *
 * Revision 1.2  2004/09/10 23:03:44  sverkera
 * Added isOpened method
 *
 * Revision 1.1  2003/07/23 00:28:39  sverkera
 * Imported
 *
 * 
 * Old changelog:
 * 08-08-01 ticp@logica.com added asynchronous processing capability
 * 02-10-01 ticp@logica.com tracing now belongs to DSESS group
 * 20-11-01 ticp@logica.com the receiver thread is now started even for
 *                          the transmitter session - before transmitter
 *                          sessions couldn't receive anything
 * 20-11-01 ticp@logica.com receiver thread is started after the bind request
 *                          is sent to the MC, before it was started before the bind
 *                          req was sent to MC, therefore the response could be processed
 *                          by the listener
 * 22-11-01 ticp@logica.com implemented session states with checking if certain
 *                          operation is allowed in the current session state
 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -