📄 readreportnotificationlistener.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
*/
/*
* Created on 12.02.2004
*
*/
package org.fosstrak.reader.rprm.core.msg;
import java.io.StringWriter;
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 javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.datatype.XMLGregorianCalendar;
import org.fosstrak.reader.rprm.core.DataSelector;
import org.fosstrak.reader.rprm.core.FieldName;
import org.fosstrak.reader.rprm.core.NotificationChannel;
import org.fosstrak.reader.rprm.core.ReaderDevice;
import org.fosstrak.reader.rprm.core.ReaderProtocolException;
import org.fosstrak.reader.rprm.core.Trigger;
import org.fosstrak.reader.rprm.core.msg.notification.EPC;
import org.fosstrak.reader.rprm.core.msg.notification.Notification;
import org.fosstrak.reader.rprm.core.msg.notification.ReadReportType;
import org.fosstrak.reader.rprm.core.msg.notification.ReaderType;
import org.fosstrak.reader.rprm.core.msg.notification.SourceInfoType;
import org.fosstrak.reader.rprm.core.msg.notification.TagFieldValueParamType;
import org.fosstrak.reader.rprm.core.msg.notification.TagType;
import org.fosstrak.reader.rprm.core.msg.notification.TagEventType.EventTriggers;
import org.fosstrak.reader.rprm.core.msg.util.CompareSet;
import org.fosstrak.reader.rprm.core.msg.util.HexUtil;
import org.fosstrak.reader.rprm.core.readreport.ReadReport;
import org.fosstrak.reader.rprm.core.readreport.ReaderInfoType;
import org.fosstrak.reader.rprm.core.readreport.SourceReport;
import org.apache.log4j.Logger;
import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;
/**
* Implementation of the interface <code>NotificationListener</code>. The
* reader notifies the <code>ReadReportNotificationListener</code> about a new
* ReadReport which has to be sent to the corresponding host.
*
* @author Andreas F黵er, ETH Zurich Switzerland, Winter 2005/06
*
*/
public class ReadReportNotificationListener implements NotificationListener {
//============================= fields ==========================================
/** The logger. */
private static Logger log ;
/** Instance of incoming message buffer. */
private static ReadReportNotificationListener messageBuffer;
/** The <code>OutgoingMessageDispatcher</code> which is used to deliver outgoing messages. */
private OutgoingMessageDispatcher outMsgDispatcher;
/** The singleton factory used to create empty replies. */
private static org.fosstrak.reader.rprm.core.msg.notification.ObjectFactory notificationFactory;
/** The message serializer. */
private MessageSerializer serializer = null;
/** Container for the notification channel connections. */
private NotificationChannelConnections notifyChannelConnections = null;
//================================= constructors =====================================
/**
* Constructs an <code>ReadReportNotificationListener</code> object.
*/
private ReadReportNotificationListener()
{
log = Logger.getLogger(getClass().getName());
notifyChannelConnections = NotificationChannelConnections.getInstance();
notificationFactory = new org.fosstrak.reader.rprm.core.msg.notification.ObjectFactory();
}
/**
* Creates the single instance of a
* <code>ReadReportNotificationListener</code>.
*/
public static ReadReportNotificationListener getInstance(){
if (messageBuffer == null){
Clients clients = Clients.getInstance();
OutgoingMessageDispatcher dispatcher = OutgoingMessageDispatcher.getInstance();
dispatcher.initialize(clients);
messageBuffer = getInstance(dispatcher);
}
return messageBuffer;
}
/**
* Creates the single instance of a
* <code>ReadReportNotificationListener</code>.
*
* @param outMsgDispatcher
* The <code>OutgoingMessageDispatcher</code> to use for
* sending the notifications to the host.
*/
public static ReadReportNotificationListener getInstance(OutgoingMessageDispatcher outMsgDispatcher){
if (messageBuffer == null){
messageBuffer = new ReadReportNotificationListener();
messageBuffer.initialize(outMsgDispatcher);
}
return messageBuffer;
}
//=================================== methods =======================================
public void initialize(OutgoingMessageDispatcher outMsgDispatcher) {
this.outMsgDispatcher = outMsgDispatcher;
}
/**
* @see NotificationListener#notifyHost(ReadReport, String, DataSelector)
*/
public synchronized void notifyHost(ReadReport report, String channelName, DataSelector dataSelector) {
try {
String outMsg = null;
Clients clients = Clients.getInstance();
Notification notification = createNotification(report, channelName, dataSelector);
// TODO IDs der notifications werden einfach raufgez鋒lt. Korrekt so??
notification.setId(Integer.toString(NotificationChannelConnections.nextMessageId()));
MessageFactory factory = MessageFactory.getInstance();
MessageFormat format = notifyChannelConnections.getChannelFormat(channelName);
serializer = factory.createSerializer(format, Context.NOTIFICATION);
outMsg = serializer.serialize(notification);
log.debug("Notification message: " + outMsg);
NotificationChannel notifChan = null;
try {
notifChan = ReaderDevice.getInstance().getNotificationChannel(channelName);
} catch (ReaderProtocolException rpe) {
log.error("Unknown NotificationChannel: " + channelName);
}
Date curTime = new Date();
if (notifChan != null) {
notifChan.setLastNotificationAttempt(curTime);
}
outMsgDispatcher.sendRequest(clients.getNotificationChannelClientID(channelName), outMsg);
if (notifChan != null) {
notifChan.setLastSuccessfulNotification(curTime);
}
} catch (MessageSerializingException e) {
log.error(e);
}
}
/**
* Creates a JAXB notification using the ReadReport from the ReaderDevice.
*
* @param report
* The <code>ReadReport</code> from the ReaderDevice
* @param channelName
* The name of the <code>NotificationChannel</code> to use to
* send the <code>ReadReport</code>.
* @param dataSelector
* The DataSelector to check, which information properties are
* expected.
* @return the JAXB notification to serialize in XML or Text format.
*/
private Notification createNotification(ReadReport report, String channelName, DataSelector dataSelector) {
try {
Notification notification = notificationFactory
.createNotification();
// create a set with all fields from the data selector
String[] fields = dataSelector.getAllFieldNames();
CompareSet dataSelectorFields = new CompareSet(fields.length);
for (int i = 0; i < fields.length; i++) {
dataSelectorFields.add(fields[i]);
}
log.debug("All data selector fields associated with this notification "
+ dataSelectorFields.toString());
//add the reader info
//FIXME: @Markus: Bug in report -> containsReaderInfo auch true, wenn alle Werte von ReaderInfo auf null sind
if (report.containsReaderInfo()) {
ReaderInfoType readerInfo = report.getReaderInfo();
ReaderType readerType = notificationFactory.createReaderType();
if (readerInfo.getEpc() != null) {
EPC epc = notificationFactory.createEPC();
epc.setValue(readerInfo.getEpc());
readerType.setReaderEPC(epc);
}
readerType.setReaderName(readerInfo.getName());
if (readerInfo.getHandle() != -1) {
readerType.setReaderHandle(readerInfo.getHandle());
}
readerType.setReaderRole(readerInfo.getRole());
org.fosstrak.reader.rprm.core.msg.notification.EventTimeType time = notificationFactory.createEventTimeType();
if (readerInfo.getNowTick() >= 0) {
time.setEventTimeTick(Long.toString(readerInfo.getNowTick()));
}
if (readerInfo.getNowUTC() != null) {
time.setEventTimeUTC(calendarToXMLGregorianCalendar(toCalendar(readerInfo.getNowUTC())));
}
notification.setReader(readerType);
}
//Name of the Trigger that caught the notification
if (report.containsNotificationInfo()) {
String triggerName = null;
Iterator it = report.getNotificationInfo().getChannelTriggers().keySet().iterator();
/* there should be only one entry in the hashtable, so take the first one */
if (it.hasNext()) {
triggerName = (String)it.next();
}
notification.setNotifyTriggerName(triggerName);
}
//Name of the NotificationChannel on which the Notification is sent on
notification.setNotifyChannelName(channelName);
//create and add ReadReport
ReadReportType reportItems = notificationFactory.createReadReportType();
List sourceList = reportItems.getSourceReport();
//add the source reports
Iterator sourceReportIt = report.getSourceReports().values().iterator();
while (sourceReportIt.hasNext()) {
org.fosstrak.reader.rprm.core.msg.notification.ReadReportType.SourceReport sourceReport = notificationFactory
.createReadReportTypeSourceReport();
SourceReport rdSourceReport = (SourceReport) sourceReportIt.next();
//set the source info
if (rdSourceReport.containsSourceInfo()) {
org.fosstrak.reader.rprm.core.msg.notification.SourceInfoType sourceInfo = notificationFactory
.createSourceInfoType();
org.fosstrak.reader.rprm.core.readreport.SourceInfoType rdSourceInfo = rdSourceReport.getSourceInfo();
if (rdSourceInfo.getSourceFrequency() != -1) {
sourceInfo.setSourceFrequency(Integer.toString(rdSourceInfo
.getSourceFrequency()));
}
if (dataSelectorFields != null
&& ((dataSelectorFields.contains(FieldName.SOURCE_NAME))
|| (dataSelectorFields.contains(FieldName.ALL_SOURCE))
|| (dataSelectorFields.contains(FieldName.ALL)) )) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -