📄 commanddispatcher.java
字号:
/*
* Copyright (C) 2007 ETH Zurich
*
* This file is part of Fosstrak (www.fosstrak.org).
*
* Fosstrak is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* Fosstrak 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 Fosstrak; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
package org.fosstrak.reader.rprm.core.msg;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.TimeZone;
import java.util.Vector;
import javax.xml.bind.JAXBException;
import javax.xml.datatype.XMLGregorianCalendar;
import org.fosstrak.reader.rprm.core.DataSelector;
import org.fosstrak.reader.rprm.core.EventType;
import org.fosstrak.reader.rprm.core.FieldName;
import org.fosstrak.reader.rprm.core.NotificationChannel;
import org.fosstrak.reader.rprm.core.ReadPoint;
import org.fosstrak.reader.rprm.core.ReaderDevice;
import org.fosstrak.reader.rprm.core.ReaderProtocolException;
import org.fosstrak.reader.rprm.core.Source;
import org.fosstrak.reader.rprm.core.TagField;
import org.fosstrak.reader.rprm.core.TagFieldValue;
import org.fosstrak.reader.rprm.core.TagSelector;
import org.fosstrak.reader.rprm.core.Trigger;
import org.fosstrak.reader.rprm.core.TriggerType;
import org.fosstrak.reader.rprm.core.msg.command.Command;
import org.fosstrak.reader.rprm.core.msg.command.DataSelectorCommand;
import org.fosstrak.reader.rprm.core.msg.command.EventTypeCommand;
import org.fosstrak.reader.rprm.core.msg.command.FieldNameCommand;
import org.fosstrak.reader.rprm.core.msg.command.HexStringListType;
import org.fosstrak.reader.rprm.core.msg.command.NotificationChannelCommand;
import org.fosstrak.reader.rprm.core.msg.command.ReadPointCommand;
import org.fosstrak.reader.rprm.core.msg.command.ReaderDeviceCommand;
import org.fosstrak.reader.rprm.core.msg.command.SourceCommand;
import org.fosstrak.reader.rprm.core.msg.command.TagFieldCommand;
import org.fosstrak.reader.rprm.core.msg.command.TagSelectorCommand;
import org.fosstrak.reader.rprm.core.msg.command.TriggerCommand;
import org.fosstrak.reader.rprm.core.msg.command.TriggerTypeCommand;
import org.fosstrak.reader.rprm.core.msg.command.SourceCommand.Kill;
import org.fosstrak.reader.rprm.core.msg.command.SourceCommand.Write;
import org.fosstrak.reader.rprm.core.msg.reply.AddressReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.BooleanReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.DataSelectorListParamType;
import org.fosstrak.reader.rprm.core.msg.reply.DataSelectorListReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.DataSelectorReply;
import org.fosstrak.reader.rprm.core.msg.reply.DataSelectorReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.EPC;
import org.fosstrak.reader.rprm.core.msg.reply.EpcReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.ErrorType;
import org.fosstrak.reader.rprm.core.msg.reply.EventTimeType;
import org.fosstrak.reader.rprm.core.msg.reply.EventTypeListParamType;
import org.fosstrak.reader.rprm.core.msg.reply.EventTypeListReturnValue;
import org.fosstrak.reader.rprm.core.msg.reply.EventTypeReply;
import org.fosstrak.reader.rprm.core.msg.reply.FieldNameListParamType;
import org.fosstrak.reader.rprm.core.msg.reply.FieldNameListReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.FieldNameReply;
import org.fosstrak.reader.rprm.core.msg.reply.HexStringReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.IntReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.NoParamType;
import org.fosstrak.reader.rprm.core.msg.reply.NotificationChannelListParamType;
import org.fosstrak.reader.rprm.core.msg.reply.NotificationChannelListReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.NotificationChannelReply;
import org.fosstrak.reader.rprm.core.msg.reply.NotificationChannelReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.ReadPointListParamType;
import org.fosstrak.reader.rprm.core.msg.reply.ReadPointListReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.ReadPointReply;
import org.fosstrak.reader.rprm.core.msg.reply.ReadPointReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.ReadReportType;
import org.fosstrak.reader.rprm.core.msg.reply.ReaderDeviceReply;
import org.fosstrak.reader.rprm.core.msg.reply.Reply;
import org.fosstrak.reader.rprm.core.msg.reply.SourceListParamType;
import org.fosstrak.reader.rprm.core.msg.reply.SourceListReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.SourceReply;
import org.fosstrak.reader.rprm.core.msg.reply.SourceReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.StringReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.TagFieldListParamType;
import org.fosstrak.reader.rprm.core.msg.reply.TagFieldListReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.TagFieldReply;
import org.fosstrak.reader.rprm.core.msg.reply.TagFieldReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.TagSelectorListParamType;
import org.fosstrak.reader.rprm.core.msg.reply.TagSelectorListReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.TagSelectorReply;
import org.fosstrak.reader.rprm.core.msg.reply.TagSelectorReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.TimeStampReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.TriggerListParamType;
import org.fosstrak.reader.rprm.core.msg.reply.TriggerListReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.TriggerReply;
import org.fosstrak.reader.rprm.core.msg.reply.TriggerReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.TriggerTypeListReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.TriggerTypeReply;
import org.fosstrak.reader.rprm.core.msg.reply.TriggerTypeReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.TriggerValueReturnType;
import org.fosstrak.reader.rprm.core.msg.reply.NotificationChannelReply.ReadQueuedData;
import org.fosstrak.reader.rprm.core.msg.reply.SourceReply.RawReadIDs;
import org.fosstrak.reader.rprm.core.msg.reply.SourceReply.ReadIDs;
import org.fosstrak.reader.rprm.core.msg.reply.TagEventType.EventTriggers;
import org.fosstrak.reader.rprm.core.msg.transport.Connection;
import org.fosstrak.reader.rprm.core.msg.transport.ServerConnection;
import org.fosstrak.reader.rprm.core.msg.util.CompareSet;
import org.fosstrak.reader.rprm.core.msg.util.HexUtil;
import org.fosstrak.reader.rprm.core.msg.util.SocketUtil;
import org.fosstrak.reader.rprm.core.readreport.ReadReport;
import org.fosstrak.reader.rprm.core.readreport.SourceInfoType;
import org.fosstrak.reader.rprm.core.readreport.SourceReport;
import org.fosstrak.reader.rprm.core.readreport.TagFieldValueParamType;
import org.apache.log4j.Logger;
import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;
/**
* The command dispatcher dispatches the commands by invoking the methods on the
* ReaderDevice and creates the response. The commands and replies don't depend
* on a specific message format the <code>CommandDispatcher</code> uses an
* intermediate representation (IR) of the commands and responses. As the IR
* tree we use the classes generated by JAXB. An XML message is mapped
* automatically into such an IR so get there the IR for free and don't need
* another level of indirection (which would deteriorate performance).<br>
* Other message formats (e.g., the text message format) are required to parse
* the message into the JAXB classes IR before invoking the command dispatcher.
* <br>
* <br>
* Because every EPC reader has only one instance of a
* <code>CommandDispatcher</code> this is a singleton class.
*
* @author Andreas F黵er, ETH Zurich Switzerland, Winter 2005/06
*
*/
public class CommandDispatcher {
// ====================================================================
// ---------------------------- Fields ------------------------------//
// ====================================================================
/** The logger. */
static private Logger log;
/** The singleton instance of the <code>CommandDipatcher</code>. */
private static CommandDispatcher dispatcher;
/** The singleton factory used to create empty replies. */
private static org.fosstrak.reader.rprm.core.msg.reply.ObjectFactory replyFactory;
/** The ReaderDevice we are working on. */
private static ReaderDevice readerDevice;
/** The <code>MessagLayer</code> holding this dispatcher. */
private MessageLayer msgLayer = null;
// ====================================================================
// ----------------------- Constructors -----------------------------//
// ====================================================================
private CommandDispatcher(final MessageLayer msgLayer) {
log = Logger.getLogger(getClass().getName());
replyFactory = new org.fosstrak.reader.rprm.core.msg.reply.ObjectFactory();
this.msgLayer = msgLayer;
try {
readerDevice = ReaderDevice.getInstance();
} catch (ReaderProtocolException e) {
log.error(e);
}
}
// ====================================================================
// ------------------------- Methods --------------------------------//
// ====================================================================
/**
* Returns the single Instance of a <code>ServiceDispatcher</code>.
*
* @param msgLayer
* The <code>MessageLayer</code> holding this
* <code>MessageDispatcher</code>.
* @return The <code>ServiceDispatcher</code>.
*/
public static CommandDispatcher getInstance(final MessageLayer msgLayer) {
if (dispatcher == null) {
dispatcher = new CommandDispatcher(msgLayer);
}
return dispatcher;
}
/**
* Dispatches a <code>Command</code>.
*
* @param command
* The <code>Command</code> to execute.
* @param im
* The <code>IncomingMessage</code> that caused this command
* invocation.
* @return The <code>Reply</code> of the command execution or a
* <code>null</code> reply if anything went wrong.
*/
public Reply dispatch(final Command command, final IncomingMessage im)
/* throws EventLayerException */{
try {
Reply reply = replyFactory.createReply();
log.debug("dispatch command");
if (command.getReaderDevice() != null) {
ReaderDeviceCommand rdCommand = command.getReaderDevice();
ReaderDeviceReply rdReply = executeCommand(rdCommand, command
.getTargetName(), im);
reply.setReaderDevice(rdReply);
}
else if (command.getSource() != null) {
SourceCommand srcCommand = command.getSource();
SourceReply srcReply = executeCommand(srcCommand, command
.getTargetName(), im);
reply.setSource(srcReply);
}
else if (command.getReadPoint() != null) {
ReadPointCommand rdpCommand = command.getReadPoint();
ReadPointReply rpReply = executeCommand(rdpCommand, command
.getTargetName(), im);
reply.setReadPoint(rpReply);
}
else if (command.getTrigger() != null) {
TriggerCommand tgCommand = command.getTrigger();
TriggerReply tgReply = executeCommand(tgCommand, command
.getTargetName(), im);
reply.setTrigger(tgReply);
}
else if (command.getTagSelector() != null) {
TagSelectorCommand tsCommand = command.getTagSelector();
TagSelectorReply tsReply = executeCommand(tsCommand, command
.getTargetName(), im);
reply.setTagSelector(tsReply);
}
else if (command.getNotificationChannel() != null) {
NotificationChannelCommand notificationCommand = command
.getNotificationChannel();
NotificationChannelReply notReply = executeCommand(
notificationCommand, command.getTargetName(), im);
reply.setNotificationChannel(notReply);
}
else if (command.getDataSelector() != null) {
DataSelectorCommand dsCommand = command.getDataSelector();
DataSelectorReply dsReply = executeCommand(dsCommand, command
.getTargetName(), im);
reply.setDataSelector(dsReply);
}
else if (command.getEventType() != null) {
EventTypeCommand etCommand = command.getEventType();
EventTypeReply etReply = executeCommand(etCommand, command
.getTargetName(), im);
reply.setEventType(etReply);
}
else if (command.getTriggerType() != null) {
TriggerTypeCommand ttCommand = command.getTriggerType();
TriggerTypeReply ttReply = executeCommand(ttCommand, command
.getTargetName(), im);
reply.setTriggerType(ttReply);
}
else if (command.getFieldName() != null) {
FieldNameCommand fnCommand = command.getFieldName();
FieldNameReply fnReply = executeCommand(fnCommand, command
.getTargetName(), im);
reply.setFieldName(fnReply);
}
else if (command.getTagField() != null) {
TagFieldCommand tfCommand = command.getTagField();
TagFieldReply tfReply = executeCommand(tfCommand, command
.getTargetName(), im);
reply.setTagField(tfReply);
}
// TODO: Exception werfen, wenn kein Kommando ausgef黨rt??
/* If no exception is thrown, everything went well :-) */
reply.setId(command.getId());
/* TODO: Typ in Schema 鋘dern auf HexStringReturn Type */
reply.setResultCode(MessagingConstants.NO_ERROR);
return reply;
} catch (ReaderProtocolException e) {
Reply errorReply = handleReaderProtocolException(e, command.getId());
return errorReply;
} catch (Exception e) {
log.error("Unexpected exception while dispatching commands: " + e);
Reply errorReply = handleReaderProtocolException(command.getId(),
MessagingConstants.ERROR_UNKNOWN,
MessagingConstants.ERROR_UNKNOWN_STR, e.getMessage());
return errorReply;
}
}
/**
* Executes a command on the ReaderDevice object.
*
* @param command
* The command to be executed.
* @param targetName
* The unique identifier (object name) of a
* <code>ReaderDevice</code> instance or <code>null</code> if
* it is a static method.
* @param im
* The <code>IncomingMessage</code> that caused this command.
* @return The reply of a command execution.
* @throws ReaderProtocolException
* Exceptions from the Trigger
*/
private ReaderDeviceReply executeCommand(final ReaderDeviceCommand command,
final String targetName, final IncomingMessage im)
throws ReaderProtocolException {
log.debug("Calling a ReaderDevice Command.");
ReaderDeviceReply reply = replyFactory.createReaderDeviceReply();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -