Commit c015b7ff authored by Florian Schmaus's avatar Florian Schmaus Committed by flow

Moved all date parsing and formating to util.XMPPDateTimeFormat and made it more robust.

Fixes OF-600: XEP-0082 defines the fraction of seconds to be optional in a date format. Fallback to this if the first parser could not parse the date format.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@13437 b35dd754-fafc-0310-a699-88a17e54d16e
parent d6dd94fe
...@@ -29,7 +29,6 @@ import java.util.Collection; ...@@ -29,7 +29,6 @@ import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.regex.Matcher; import java.util.regex.Matcher;
...@@ -45,10 +44,10 @@ import org.jivesoftware.openfire.event.UserEventDispatcher; ...@@ -45,10 +44,10 @@ import org.jivesoftware.openfire.event.UserEventDispatcher;
import org.jivesoftware.openfire.event.UserEventListener; import org.jivesoftware.openfire.event.UserEventListener;
import org.jivesoftware.openfire.user.User; import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.user.UserManager; import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.util.FastDateFormat;
import org.jivesoftware.util.JiveConstants; import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.StringUtils; import org.jivesoftware.util.StringUtils;
import org.jivesoftware.util.XMPPDateTimeFormat;
import org.jivesoftware.util.cache.Cache; import org.jivesoftware.util.cache.Cache;
import org.jivesoftware.util.cache.CacheFactory; import org.jivesoftware.util.cache.CacheFactory;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -88,8 +87,7 @@ public class OfflineMessageStore extends BasicModule implements UserEventListene ...@@ -88,8 +87,7 @@ public class OfflineMessageStore extends BasicModule implements UserEventListene
private static final int POOL_SIZE = 10; private static final int POOL_SIZE = 10;
private Cache<String, Integer> sizeCache; private Cache<String, Integer> sizeCache;
private FastDateFormat dateFormat;
private FastDateFormat dateFormatOld;
/** /**
* Pattern to use for detecting invalid XML characters. Invalid XML characters will * Pattern to use for detecting invalid XML characters. Invalid XML characters will
* be removed from the stored offline messages. * be removed from the stored offline messages.
...@@ -115,10 +113,6 @@ public class OfflineMessageStore extends BasicModule implements UserEventListene ...@@ -115,10 +113,6 @@ public class OfflineMessageStore extends BasicModule implements UserEventListene
*/ */
public OfflineMessageStore() { public OfflineMessageStore() {
super("Offline Message Store"); super("Offline Message Store");
dateFormat = FastDateFormat.getInstance(JiveConstants.XMPP_DATETIME_FORMAT,
TimeZone.getTimeZone("UTC"));
dateFormatOld = FastDateFormat.getInstance(JiveConstants.XMPP_DELAY_DATETIME_FORMAT,
TimeZone.getTimeZone("UTC"));
sizeCache = CacheFactory.createCache("Offline Message Size"); sizeCache = CacheFactory.createCache("Offline Message Size");
} }
...@@ -227,11 +221,11 @@ public class OfflineMessageStore extends BasicModule implements UserEventListene ...@@ -227,11 +221,11 @@ public class OfflineMessageStore extends BasicModule implements UserEventListene
// Add a delayed delivery (XEP-0203) element to the message. // Add a delayed delivery (XEP-0203) element to the message.
Element delay = message.addChildElement("delay", "urn:xmpp:delay"); Element delay = message.addChildElement("delay", "urn:xmpp:delay");
delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain()); delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain());
delay.addAttribute("stamp", dateFormat.format(creationDate)); delay.addAttribute("stamp", XMPPDateTimeFormat.format(creationDate));
// Add a legacy delayed delivery (XEP-0091) element to the message. XEP is obsolete and support should be dropped in future. // Add a legacy delayed delivery (XEP-0091) element to the message. XEP is obsolete and support should be dropped in future.
delay = message.addChildElement("x", "jabber:x:delay"); delay = message.addChildElement("x", "jabber:x:delay");
delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain()); delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain());
delay.addAttribute("stamp", dateFormatOld.format(creationDate)); delay.addAttribute("stamp", XMPPDateTimeFormat.formatOld(creationDate));
messages.add(message); messages.add(message);
} }
// Check if the offline messages loaded should be deleted, and that there are // Check if the offline messages loaded should be deleted, and that there are
...@@ -294,11 +288,11 @@ public class OfflineMessageStore extends BasicModule implements UserEventListene ...@@ -294,11 +288,11 @@ public class OfflineMessageStore extends BasicModule implements UserEventListene
// Add a delayed delivery (XEP-0203) element to the message. // Add a delayed delivery (XEP-0203) element to the message.
Element delay = message.addChildElement("delay", "urn:xmpp:delay"); Element delay = message.addChildElement("delay", "urn:xmpp:delay");
delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain()); delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain());
delay.addAttribute("stamp", dateFormat.format(creationDate)); delay.addAttribute("stamp", XMPPDateTimeFormat.format(creationDate));
// Add a legacy delayed delivery (XEP-0091) element to the message. XEP is obsolete and support should be dropped in future. // Add a legacy delayed delivery (XEP-0091) element to the message. XEP is obsolete and support should be dropped in future.
delay = message.addChildElement("x", "jabber:x:delay"); delay = message.addChildElement("x", "jabber:x:delay");
delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain()); delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain());
delay.addAttribute("stamp", dateFormatOld.format(creationDate)); delay.addAttribute("stamp", XMPPDateTimeFormat.formatOld(creationDate));
} }
} }
catch (Exception e) { catch (Exception e) {
......
...@@ -27,9 +27,8 @@ import org.jivesoftware.openfire.commands.AdHocCommand; ...@@ -27,9 +27,8 @@ import org.jivesoftware.openfire.commands.AdHocCommand;
import org.jivesoftware.openfire.commands.SessionData; import org.jivesoftware.openfire.commands.SessionData;
import org.jivesoftware.openfire.component.InternalComponentManager; import org.jivesoftware.openfire.component.InternalComponentManager;
import org.jivesoftware.openfire.session.ClientSession; import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.util.FastDateFormat;
import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.XMPPDateTimeFormat;
import org.xmpp.forms.DataForm; import org.xmpp.forms.DataForm;
import org.xmpp.forms.FormField; import org.xmpp.forms.FormField;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
...@@ -46,7 +45,6 @@ import java.util.*; ...@@ -46,7 +45,6 @@ import java.util.*;
* @author Gaston Dombiak * @author Gaston Dombiak
*/ */
public class GetServerStats extends AdHocCommand { public class GetServerStats extends AdHocCommand {
final private FastDateFormat dateFormat = FastDateFormat.getInstance(JiveConstants.XMPP_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));
@Override @Override
protected void addStageInformation(SessionData data, Element command) { protected void addStageInformation(SessionData data, Element command) {
...@@ -92,7 +90,7 @@ public class GetServerStats extends AdHocCommand { ...@@ -92,7 +90,7 @@ public class GetServerStats extends AdHocCommand {
field = form.addField(); field = form.addField();
field.setLabel(LocaleUtils.getLocalizedString("index.uptime")); field.setLabel(LocaleUtils.getLocalizedString("index.uptime"));
field.setVariable("uptime"); field.setVariable("uptime");
field.addValue(dateFormat.format(XMPPServer.getInstance().getServerInfo().getLastStarted())); field.addValue(XMPPDateTimeFormat.format(XMPPServer.getInstance().getServerInfo().getLastStarted()));
DecimalFormat mbFormat = new DecimalFormat("#0.00"); DecimalFormat mbFormat = new DecimalFormat("#0.00");
DecimalFormat percentFormat = new DecimalFormat("#0.0"); DecimalFormat percentFormat = new DecimalFormat("#0.0");
......
...@@ -21,13 +21,11 @@ ...@@ -21,13 +21,11 @@
package org.jivesoftware.openfire.handler; package org.jivesoftware.openfire.handler;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.TimeZone;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
import org.dom4j.Element; import org.dom4j.Element;
...@@ -45,7 +43,7 @@ import org.jivesoftware.openfire.disco.IQDiscoItemsHandler; ...@@ -45,7 +43,7 @@ import org.jivesoftware.openfire.disco.IQDiscoItemsHandler;
import org.jivesoftware.openfire.disco.ServerFeaturesProvider; import org.jivesoftware.openfire.disco.ServerFeaturesProvider;
import org.jivesoftware.openfire.session.LocalClientSession; import org.jivesoftware.openfire.session.LocalClientSession;
import org.jivesoftware.openfire.user.UserManager; import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.util.JiveConstants; import org.jivesoftware.util.XMPPDateTimeFormat;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.xmpp.forms.DataForm; import org.xmpp.forms.DataForm;
...@@ -67,8 +65,7 @@ public class IQOfflineMessagesHandler extends IQHandler implements ServerFeature ...@@ -67,8 +65,7 @@ public class IQOfflineMessagesHandler extends IQHandler implements ServerFeature
private static final String NAMESPACE = "http://jabber.org/protocol/offline"; private static final String NAMESPACE = "http://jabber.org/protocol/offline";
final private SimpleDateFormat dateFormat = final private XMPPDateTimeFormat xmppDateTime = new XMPPDateTimeFormat();
new SimpleDateFormat(JiveConstants.XMPP_DATETIME_FORMAT);
private IQHandlerInfo info; private IQHandlerInfo info;
private IQDiscoInfoHandler infoHandler; private IQDiscoInfoHandler infoHandler;
private IQDiscoItemsHandler itemsHandler; private IQDiscoItemsHandler itemsHandler;
...@@ -80,7 +77,6 @@ public class IQOfflineMessagesHandler extends IQHandler implements ServerFeature ...@@ -80,7 +77,6 @@ public class IQOfflineMessagesHandler extends IQHandler implements ServerFeature
public IQOfflineMessagesHandler() { public IQOfflineMessagesHandler() {
super("Flexible Offline Message Retrieval Handler"); super("Flexible Offline Message Retrieval Handler");
info = new IQHandlerInfo("offline", NAMESPACE); info = new IQHandlerInfo("offline", NAMESPACE);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
} }
@Override @Override
...@@ -105,13 +101,10 @@ public class IQOfflineMessagesHandler extends IQHandler implements ServerFeature ...@@ -105,13 +101,10 @@ public class IQOfflineMessagesHandler extends IQHandler implements ServerFeature
for (Iterator it = offlineRequest.elementIterator("item"); it.hasNext();) { for (Iterator it = offlineRequest.elementIterator("item"); it.hasNext();) {
Element item = (Element) it.next(); Element item = (Element) it.next();
Date creationDate = null; Date creationDate = null;
synchronized (dateFormat) { try {
try { creationDate = xmppDateTime.parseString(item.attributeValue("node"));
creationDate = dateFormat.parse(item.attributeValue("node")); } catch (ParseException e) {
} Log.error("Error parsing date", e);
catch (ParseException e) {
Log.error("Error parsing date", e);
}
} }
if ("view".equals(item.attributeValue("action"))) { if ("view".equals(item.attributeValue("action"))) {
// User requested to receive specific message // User requested to receive specific message
...@@ -131,10 +124,8 @@ public class IQOfflineMessagesHandler extends IQHandler implements ServerFeature ...@@ -131,10 +124,8 @@ public class IQOfflineMessagesHandler extends IQHandler implements ServerFeature
private void sendOfflineMessage(JID receipient, OfflineMessage offlineMessage) { private void sendOfflineMessage(JID receipient, OfflineMessage offlineMessage) {
Element offlineInfo = offlineMessage.addChildElement("offline", NAMESPACE); Element offlineInfo = offlineMessage.addChildElement("offline", NAMESPACE);
synchronized (dateFormat) { offlineInfo.addElement("item").addAttribute("node",
offlineInfo.addElement("item").addAttribute("node", XMPPDateTimeFormat.format(offlineMessage.getCreationDate()));
dateFormat.format(offlineMessage.getCreationDate()));
}
routingTable.routePacket(receipient, offlineMessage, true); routingTable.routePacket(receipient, offlineMessage, true);
} }
...@@ -189,9 +180,8 @@ public class IQOfflineMessagesHandler extends IQHandler implements ServerFeature ...@@ -189,9 +180,8 @@ public class IQOfflineMessagesHandler extends IQHandler implements ServerFeature
stopOfflineFlooding(senderJID); stopOfflineFlooding(senderJID);
List<DiscoItem> answer = new ArrayList<DiscoItem>(); List<DiscoItem> answer = new ArrayList<DiscoItem>();
for (OfflineMessage offlineMessage : messageStore.getMessages(senderJID.getNode(), false)) { for (OfflineMessage offlineMessage : messageStore.getMessages(senderJID.getNode(), false)) {
synchronized (dateFormat) { answer.add(new DiscoItem(new JID(senderJID.toBareJID()), offlineMessage.getFrom().toString(),
answer.add(new DiscoItem(new JID(senderJID.toBareJID()), offlineMessage.getFrom().toString(), dateFormat.format(offlineMessage.getCreationDate()), null)); XMPPDateTimeFormat.format(offlineMessage.getCreationDate()), null));
}
} }
return answer.iterator(); return answer.iterator();
......
...@@ -25,15 +25,13 @@ import org.dom4j.Element; ...@@ -25,15 +25,13 @@ import org.dom4j.Element;
import org.dom4j.QName; import org.dom4j.QName;
import org.jivesoftware.openfire.IQHandlerInfo; import org.jivesoftware.openfire.IQHandlerInfo;
import org.jivesoftware.openfire.disco.ServerFeaturesProvider; import org.jivesoftware.openfire.disco.ServerFeaturesProvider;
import org.jivesoftware.util.FastDateFormat; import org.jivesoftware.util.XMPPDateTimeFormat;
import org.jivesoftware.util.JiveConstants;
import org.xmpp.packet.IQ; import org.xmpp.packet.IQ;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.TimeZone;
/** /**
* Implements the TYPE_IQ jabber:iq:time protocol (time info) as * Implements the TYPE_IQ jabber:iq:time protocol (time info) as
...@@ -59,10 +57,6 @@ public class IQTimeHandler extends IQHandler implements ServerFeaturesProvider { ...@@ -59,10 +57,6 @@ public class IQTimeHandler extends IQHandler implements ServerFeaturesProvider {
// todo: Make display text match the locale of user (xml:lang support) // todo: Make display text match the locale of user (xml:lang support)
private static final DateFormat DATE_FORMAT = DateFormat.getDateInstance(DateFormat.MEDIUM); private static final DateFormat DATE_FORMAT = DateFormat.getDateInstance(DateFormat.MEDIUM);
private static final DateFormat TIME_FORMAT = DateFormat.getTimeInstance(DateFormat.LONG); private static final DateFormat TIME_FORMAT = DateFormat.getTimeInstance(DateFormat.LONG);
// UTC and not JEP-0082 time format is used as per the JEP-0090 specification.
private static final FastDateFormat UTC_FORMAT =
FastDateFormat.getInstance(JiveConstants.XMPP_DELAY_DATETIME_FORMAT,
TimeZone.getTimeZone("UTC"));
private Element responseElement; private Element responseElement;
private IQHandlerInfo info; private IQHandlerInfo info;
...@@ -90,7 +84,7 @@ public class IQTimeHandler extends IQHandler implements ServerFeaturesProvider { ...@@ -90,7 +84,7 @@ public class IQTimeHandler extends IQHandler implements ServerFeaturesProvider {
private Element buildResponse() { private Element buildResponse() {
Element response = responseElement.createCopy(); Element response = responseElement.createCopy();
Date current = new Date(); Date current = new Date();
response.element("utc").setText(UTC_FORMAT.format(current)); response.element("utc").setText(XMPPDateTimeFormat.formatOld(current));
StringBuilder display = new StringBuilder(DATE_FORMAT.format(current)); StringBuilder display = new StringBuilder(DATE_FORMAT.format(current));
display.append(' '); display.append(' ');
display.append(TIME_FORMAT.format(current)); display.append(TIME_FORMAT.format(current));
......
...@@ -23,7 +23,6 @@ import java.util.ArrayList; ...@@ -23,7 +23,6 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TimeZone;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
...@@ -36,9 +35,8 @@ import org.jivesoftware.openfire.XMPPServer; ...@@ -36,9 +35,8 @@ import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.component.ComponentEventListener; import org.jivesoftware.openfire.component.ComponentEventListener;
import org.jivesoftware.openfire.component.InternalComponentManager; import org.jivesoftware.openfire.component.InternalComponentManager;
import org.jivesoftware.openfire.session.Session; import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.util.FastDateFormat;
import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.XMPPDateTimeFormat;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.xmpp.packet.IQ; import org.xmpp.packet.IQ;
...@@ -61,8 +59,7 @@ public class PacketCopier implements PacketInterceptor, ComponentEventListener { ...@@ -61,8 +59,7 @@ public class PacketCopier implements PacketInterceptor, ComponentEventListener {
private static final Logger Log = LoggerFactory.getLogger(PacketCopier.class); private static final Logger Log = LoggerFactory.getLogger(PacketCopier.class);
private final static PacketCopier instance = new PacketCopier(); private final static PacketCopier instance = new PacketCopier();
private final static FastDateFormat dateFormat = FastDateFormat
.getInstance(JiveConstants.XMPP_DELAY_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));
private Map<String, Subscription> subscribers = new ConcurrentHashMap<String, Subscription>(); private Map<String, Subscription> subscribers = new ConcurrentHashMap<String, Subscription>();
private String serverName; private String serverName;
...@@ -199,7 +196,7 @@ public class PacketCopier implements PacketInterceptor, ComponentEventListener { ...@@ -199,7 +196,7 @@ public class PacketCopier implements PacketInterceptor, ComponentEventListener {
"http://jabber.org/protocol/packet#event"); "http://jabber.org/protocol/packet#event");
childElement.addAttribute("incoming", subscription.isIncoming() ? "true" : "false"); childElement.addAttribute("incoming", subscription.isIncoming() ? "true" : "false");
childElement.addAttribute("processed", subscription.isProcessed() ? "true" : "false"); childElement.addAttribute("processed", subscription.isProcessed() ? "true" : "false");
childElement.addAttribute("date", dateFormat.format(interceptedPacket.getCreationDate())); childElement.addAttribute("date", XMPPDateTimeFormat.formatOld(interceptedPacket.getCreationDate()));
childElement.add(interceptedPacket.getElement().createCopy()); childElement.add(interceptedPacket.getElement().createCopy());
// Send message notification to subscribed component // Send message notification to subscribed component
routingTable.routePacket(message.getTo(), message, true); routingTable.routePacket(message.getTo(), message, true);
......
...@@ -20,18 +20,15 @@ ...@@ -20,18 +20,15 @@
package org.jivesoftware.openfire.muc; package org.jivesoftware.openfire.muc;
import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.TimeZone;
import org.dom4j.Element; import org.dom4j.Element;
import org.jivesoftware.openfire.muc.spi.LocalMUCRole; import org.jivesoftware.openfire.muc.spi.LocalMUCRole;
import org.jivesoftware.util.JiveConstants; import org.jivesoftware.util.XMPPDateTimeFormat;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.xmpp.packet.Message; import org.xmpp.packet.Message;
...@@ -51,14 +48,7 @@ import org.xmpp.packet.Message; ...@@ -51,14 +48,7 @@ import org.xmpp.packet.Message;
public class HistoryRequest { public class HistoryRequest {
private static final Logger Log = LoggerFactory.getLogger(HistoryRequest.class); private static final Logger Log = LoggerFactory.getLogger(HistoryRequest.class);
private static final XMPPDateTimeFormat xmppDateTime = new XMPPDateTimeFormat();
private static final DateFormat formatter = new SimpleDateFormat(JiveConstants.XMPP_DATETIME_FORMAT);
private static final DateFormat delayedFormatter = new SimpleDateFormat(
JiveConstants.XMPP_DELAY_DATETIME_FORMAT);
static {
delayedFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
}
private int maxChars = -1; private int maxChars = -1;
private int maxStanzas = -1; private int maxStanzas = -1;
...@@ -79,10 +69,8 @@ public class HistoryRequest { ...@@ -79,10 +69,8 @@ public class HistoryRequest {
} }
if (history.attribute("since") != null) { if (history.attribute("since") != null) {
try { try {
// parse utc into Date // parse since String into Date
synchronized (formatter) { this.since = xmppDateTime.parseString(history.attributeValue("since"));
this.since = formatter.parse(history.attributeValue("since"));
}
} }
catch(ParseException pe) { catch(ParseException pe) {
Log.error("Error parsing date from history management", pe); Log.error("Error parsing date from history management", pe);
...@@ -193,11 +181,7 @@ public class HistoryRequest { ...@@ -193,11 +181,7 @@ public class HistoryRequest {
delayInformation = message.getChildElement("x", "jabber:x:delay"); delayInformation = message.getChildElement("x", "jabber:x:delay");
try { try {
// Get the date when the historic message was sent // Get the date when the historic message was sent
Date delayedDate; Date delayedDate = xmppDateTime.parseString(delayInformation.attributeValue("stamp"));
synchronized (delayedFormatter) {
delayedDate = delayedFormatter
.parse(delayInformation.attributeValue("stamp"));
}
if (getSince() != null && delayedDate.before(getSince())) { if (getSince() != null && delayedDate.before(getSince())) {
// Stop collecting history since we have exceded a limit // Stop collecting history since we have exceded a limit
break; break;
......
...@@ -22,15 +22,13 @@ package org.jivesoftware.openfire.muc; ...@@ -22,15 +22,13 @@ package org.jivesoftware.openfire.muc;
import org.dom4j.Element; import org.dom4j.Element;
import org.jivesoftware.openfire.user.UserNotFoundException; import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.FastDateFormat; import org.jivesoftware.util.XMPPDateTimeFormat;
import org.jivesoftware.util.JiveConstants;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
import org.xmpp.packet.Message; import org.xmpp.packet.Message;
import java.util.Date; import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.TimeZone;
/** /**
* Represent the data model for one <code>MUCRoom</code> history. Including chat transcript, * Represent the data model for one <code>MUCRoom</code> history. Including chat transcript,
...@@ -40,11 +38,6 @@ import java.util.TimeZone; ...@@ -40,11 +38,6 @@ import java.util.TimeZone;
*/ */
public final class MUCRoomHistory { public final class MUCRoomHistory {
private static final FastDateFormat UTC_FORMAT = FastDateFormat
.getInstance(JiveConstants.XMPP_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));
private static final FastDateFormat UTC_FORMAT_OLD = FastDateFormat
.getInstance(JiveConstants.XMPP_DELAY_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));
private MUCRoom room; private MUCRoom room;
private HistoryStrategy historyStrategy; private HistoryStrategy historyStrategy;
...@@ -110,8 +103,8 @@ public final class MUCRoomHistory { ...@@ -110,8 +103,8 @@ public final class MUCRoomHistory {
Element delayInformation = packetToAdd.addChildElement("delay", "urn:xmpp:delay"); Element delayInformation = packetToAdd.addChildElement("delay", "urn:xmpp:delay");
Element delayInformationOld = packetToAdd.addChildElement("x", "jabber:x:delay"); Element delayInformationOld = packetToAdd.addChildElement("x", "jabber:x:delay");
Date current = new Date(); Date current = new Date();
delayInformation.addAttribute("stamp", UTC_FORMAT.format(current)); delayInformation.addAttribute("stamp", XMPPDateTimeFormat.format(current));
delayInformationOld.addAttribute("stamp", UTC_FORMAT_OLD.format(current)); delayInformationOld.addAttribute("stamp", XMPPDateTimeFormat.formatOld(current));
if (room.canAnyoneDiscoverJID()) { if (room.canAnyoneDiscoverJID()) {
// Set the Full JID as the "from" attribute // Set the Full JID as the "from" attribute
try { try {
...@@ -178,8 +171,8 @@ public final class MUCRoomHistory { ...@@ -178,8 +171,8 @@ public final class MUCRoomHistory {
// Add the delay information to the message // Add the delay information to the message
Element delayInformation = message.addChildElement("delay", "urn:xmpp:delay"); Element delayInformation = message.addChildElement("delay", "urn:xmpp:delay");
Element delayInformationOld = message.addChildElement("x", "jabber:x:delay"); Element delayInformationOld = message.addChildElement("x", "jabber:x:delay");
delayInformation.addAttribute("stamp", UTC_FORMAT.format(sentDate)); delayInformation.addAttribute("stamp", XMPPDateTimeFormat.format(sentDate));
delayInformationOld.addAttribute("stamp", UTC_FORMAT_OLD.format(sentDate)); delayInformationOld.addAttribute("stamp", XMPPDateTimeFormat.formatOld(sentDate));
if (room.canAnyoneDiscoverJID()) { if (room.canAnyoneDiscoverJID()) {
// Set the Full JID as the "from" attribute // Set the Full JID as the "from" attribute
delayInformation.addAttribute("from", senderJID); delayInformation.addAttribute("from", senderJID);
......
...@@ -28,7 +28,6 @@ import java.util.Iterator; ...@@ -28,7 +28,6 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Queue; import java.util.Queue;
import java.util.TimeZone;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
...@@ -60,10 +59,9 @@ import org.jivesoftware.openfire.muc.cluster.GetNumberConnectedUsers; ...@@ -60,10 +59,9 @@ import org.jivesoftware.openfire.muc.cluster.GetNumberConnectedUsers;
import org.jivesoftware.openfire.muc.cluster.OccupantAddedEvent; import org.jivesoftware.openfire.muc.cluster.OccupantAddedEvent;
import org.jivesoftware.openfire.muc.cluster.RoomAvailableEvent; import org.jivesoftware.openfire.muc.cluster.RoomAvailableEvent;
import org.jivesoftware.openfire.muc.cluster.RoomRemovedEvent; import org.jivesoftware.openfire.muc.cluster.RoomRemovedEvent;
import org.jivesoftware.util.FastDateFormat;
import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.JiveProperties; import org.jivesoftware.util.JiveProperties;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.XMPPDateTimeFormat;
import org.jivesoftware.util.cache.CacheFactory; import org.jivesoftware.util.cache.CacheFactory;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -100,11 +98,6 @@ public class MultiUserChatServiceImpl implements Component, MultiUserChatService ...@@ -100,11 +98,6 @@ public class MultiUserChatServiceImpl implements Component, MultiUserChatService
private static final Logger Log = LoggerFactory.getLogger(MultiUserChatServiceImpl.class); private static final Logger Log = LoggerFactory.getLogger(MultiUserChatServiceImpl.class);
private static final FastDateFormat dateFormatter = FastDateFormat
.getInstance(JiveConstants.XMPP_DELAY_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));
/** /**
* The time to elapse between clearing of idle chat users. * The time to elapse between clearing of idle chat users.
*/ */
...@@ -1340,7 +1333,7 @@ public class MultiUserChatServiceImpl implements Component, MultiUserChatService ...@@ -1340,7 +1333,7 @@ public class MultiUserChatServiceImpl implements Component, MultiUserChatService
final FormField fieldDate = dataForm.addField(); final FormField fieldDate = dataForm.addField();
fieldDate.setVariable("x-muc#roominfo_creationdate"); fieldDate.setVariable("x-muc#roominfo_creationdate");
fieldDate.setLabel(LocaleUtils.getLocalizedString("muc.extended.info.creationdate")); fieldDate.setLabel(LocaleUtils.getLocalizedString("muc.extended.info.creationdate"));
fieldDate.addValue(dateFormatter.format(room.getCreationDate())); fieldDate.addValue(XMPPDateTimeFormat.formatOld(room.getCreationDate()));
return dataForm; return dataForm;
} }
......
...@@ -24,7 +24,6 @@ import java.util.Collection; ...@@ -24,7 +24,6 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
...@@ -52,10 +51,9 @@ import org.jivesoftware.openfire.roster.Roster; ...@@ -52,10 +51,9 @@ import org.jivesoftware.openfire.roster.Roster;
import org.jivesoftware.openfire.roster.RosterItem; import org.jivesoftware.openfire.roster.RosterItem;
import org.jivesoftware.openfire.session.ClientSession; import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.user.UserNotFoundException; import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.FastDateFormat;
import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.StringUtils; import org.jivesoftware.util.StringUtils;
import org.jivesoftware.util.XMPPDateTimeFormat;
import org.jivesoftware.util.cache.Cacheable; import org.jivesoftware.util.cache.Cacheable;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
import org.xmpp.packet.Message; import org.xmpp.packet.Message;
...@@ -72,11 +70,6 @@ import org.xmpp.packet.PacketExtension; ...@@ -72,11 +70,6 @@ import org.xmpp.packet.PacketExtension;
* @author Armando Jagucki * @author Armando Jagucki
*/ */
public class PEPService implements PubSubService, Cacheable { public class PEPService implements PubSubService, Cacheable {
/**
* Date format to use for time stamps in delayed event notifications.
*/
private static final FastDateFormat fastDateFormat;
/** /**
* The bare JID that this service is identified by. * The bare JID that this service is identified by.
...@@ -135,10 +128,6 @@ public class PEPService implements PubSubService, Cacheable { ...@@ -135,10 +128,6 @@ public class PEPService implements PubSubService, Cacheable {
*/ */
private EntityCapabilitiesManager entityCapsManager = EntityCapabilitiesManager.getInstance(); private EntityCapabilitiesManager entityCapsManager = EntityCapabilitiesManager.getInstance();
static {
fastDateFormat = FastDateFormat.getInstance(JiveConstants.XMPP_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));
}
/** /**
* Constructs a PEPService. * Constructs a PEPService.
* *
...@@ -503,7 +492,7 @@ public class PEPService implements PubSubService, Cacheable { ...@@ -503,7 +492,7 @@ public class PEPService implements PubSubService, Cacheable {
notification.setBody(LocaleUtils.getLocalizedString("pubsub.notification.message.body")); notification.setBody(LocaleUtils.getLocalizedString("pubsub.notification.message.body"));
} }
// Include date when published item was created // Include date when published item was created
notification.getElement().addElement("delay", "urn:xmpp:delay").addAttribute("stamp", fastDateFormat.format(leafLastPublishedItem.getCreationDate())); notification.getElement().addElement("delay", "urn:xmpp:delay").addAttribute("stamp", XMPPDateTimeFormat.format(leafLastPublishedItem.getCreationDate()));
// Send the event notification to the subscriber // Send the event notification to the subscriber
this.sendNotification(subscription.getNode(), notification, subscription.getJID()); this.sendNotification(subscription.getNode(), notification, subscription.getJID());
} }
......
...@@ -21,18 +21,15 @@ ...@@ -21,18 +21,15 @@
package org.jivesoftware.openfire.pubsub; package org.jivesoftware.openfire.pubsub;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.TimeZone;
import org.dom4j.Element; import org.dom4j.Element;
import org.jivesoftware.util.FastDateFormat;
import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.XMPPDateTimeFormat;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.xmpp.forms.DataForm; import org.xmpp.forms.DataForm;
...@@ -67,8 +64,7 @@ public class NodeSubscription { ...@@ -67,8 +64,7 @@ public class NodeSubscription {
private static final Logger Log = LoggerFactory.getLogger(NodeSubscription.class); private static final Logger Log = LoggerFactory.getLogger(NodeSubscription.class);
private static final SimpleDateFormat dateFormat; private static final XMPPDateTimeFormat xmppDateTime = new XMPPDateTimeFormat();
private static final FastDateFormat fastDateFormat;
/** /**
* The node to which this subscription is interested in. * The node to which this subscription is interested in.
...@@ -140,13 +136,6 @@ public class NodeSubscription { ...@@ -140,13 +136,6 @@ public class NodeSubscription {
*/ */
private boolean savedToDB = false; private boolean savedToDB = false;
static {
dateFormat = new SimpleDateFormat("yyyy-MM-DD'T'HH:mm:ss.SSS'Z'");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
fastDateFormat = FastDateFormat
.getInstance(JiveConstants.XMPP_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));
}
/** /**
* Creates a new subscription of the specified user with the node. * Creates a new subscription of the specified user with the node.
* *
...@@ -464,13 +453,10 @@ public class NodeSubscription { ...@@ -464,13 +453,10 @@ public class NodeSubscription {
} }
else if ("pubsub#expire".equals(field.getVariable())) { else if ("pubsub#expire".equals(field.getVariable())) {
values = field.getValues(); values = field.getValues();
synchronized (dateFormat) { try {
try { expire = xmppDateTime.parseString(values.get(0));
expire = dateFormat.parse(values.get(0)); } catch (ParseException e) {
} Log.error("Error parsing date", e);
catch (ParseException e) {
Log.error("Error parsing date", e);
}
} }
} }
else if ("pubsub#include_body".equals(field.getVariable())) { else if ("pubsub#include_body".equals(field.getVariable())) {
...@@ -564,7 +550,7 @@ public class NodeSubscription { ...@@ -564,7 +550,7 @@ public class NodeSubscription {
formField.setType(FormField.Type.text_single); formField.setType(FormField.Type.text_single);
formField.setLabel(LocaleUtils.getLocalizedString("pubsub.form.subscription.expire")); formField.setLabel(LocaleUtils.getLocalizedString("pubsub.form.subscription.expire"));
if (expire != null) { if (expire != null) {
formField.addValue(fastDateFormat.format(expire)); formField.addValue(XMPPDateTimeFormat.format(expire));
} }
formField = form.addField(); formField = form.addField();
...@@ -829,7 +815,7 @@ public class NodeSubscription { ...@@ -829,7 +815,7 @@ public class NodeSubscription {
} }
// Include date when published item was created // Include date when published item was created
notification.getElement().addElement("delay", "urn:xmpp:delay") notification.getElement().addElement("delay", "urn:xmpp:delay")
.addAttribute("stamp", fastDateFormat.format(publishedItem.getCreationDate())); .addAttribute("stamp", XMPPDateTimeFormat.format(publishedItem.getCreationDate()));
// Send the event notification to the subscriber // Send the event notification to the subscriber
node.getService().sendNotification(node, notification, jid); node.getService().sendNotification(node, notification, jid);
} }
......
...@@ -37,18 +37,4 @@ public class JiveConstants { ...@@ -37,18 +37,4 @@ public class JiveConstants {
public static final long HOUR = 60 * MINUTE; public static final long HOUR = 60 * MINUTE;
public static final long DAY = 24 * HOUR; public static final long DAY = 24 * HOUR;
public static final long WEEK = 7 * DAY; public static final long WEEK = 7 * DAY;
/**
* Date/time format for use by SimpleDateFormat. The format conforms to
* <a href="http://www.xmpp.org/extensions/xep-0082.html">XEP-0082</a>, which defines
* a unified date/time format for XMPP.
*/
public static final String XMPP_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
/**
* Date/time format for use by SimpleDateFormat. The format conforms to the format
* defined in <a href="http://www.xmpp.org/extensions/xep-0091.html">XEP-0091</a>,
* a specialized date format for historical XMPP usage.
*/
public static final String XMPP_DELAY_DATETIME_FORMAT = "yyyyMMdd'T'HH:mm:ss";
} }
\ No newline at end of file
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2013 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.util;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//import net.jcip.annotations.ThreadSafe;
/**
*
* Utility class for date/time format conversions as specified in
* <a href="http://www.xmpp.org/extensions/xep-0082.html">XEP-0082</a> and
* <a href="http://www.xmpp.org/extensions/xep-0090.html">XEP-0090</a> and
* For Date -> String converstion FastDateFormat is used
*
*/
//@ThreadSafe
public class XMPPDateTimeFormat {
/**
* Date/time format for use by SimpleDateFormat. The format conforms to
* <a href="http://www.xmpp.org/extensions/xep-0082.html">XEP-0082</a>, which defines
* a unified date/time format for XMPP.
*/
public static final String XMPP_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
public static final String XMPP_DATETIME_FORMAT_WO_TIMEZONE = "yyyy-MM-dd'T'HH:mm:ss.SSS";
public static final String XMPP_DATETIME_FORMAT_WO_MILLIS_WO_TIMEZONE = "yyyy-MM-dd'T'HH:mm:ss";
public static final String XMPP_DATE_FORMAT = "yyyy-MM-dd";
public static final String XMPP_TIME_FORMAT = "HH:mm:ss.SSS";
public static final String XMPP_TIME_FORMAT_WO_MILLIS = "HH:mm:ss";
/**
* Date/time format for use by SimpleDateFormat. The format conforms to the format
* defined in <a href="http://www.xmpp.org/extensions/xep-0091.html">XEP-0091</a>,
* a specialized date format for historical XMPP usage.
*/
public static final String XMPP_DELAY_DATETIME_FORMAT = "yyyyMMdd'T'HH:mm:ss";
// matches CCYY-MM-DDThh:mm:ss.SSS(Z|(+|-)hh:mm))
private static final Pattern xep80DateTimePattern = Pattern.compile("^\\d+(-\\d+){2}+T(\\d+:){2}\\d+.\\d+(Z|([+-](\\d+:\\d+)))?$");
// matches CCYY-MM-DDThh:mm:ss(Z|(+|-)hh:mm))
private static final Pattern xep80DateTimeWoMillisPattern = Pattern.compile("^\\d+(-\\d+){2}+T(\\d+:){2}\\d+(Z|([+-](\\d+:\\d+)))?$");
// matches CCYYMMDDThh:mm:ss
@SuppressWarnings("unused")
private static final Pattern xep91Pattern = Pattern.compile("^\\d+T\\d+:\\d+:\\d+$");
private static final FastDateFormat FAST_FORMAT = FastDateFormat.getInstance(
XMPP_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));
private static final FastDateFormat FAST_FORMAT_OLD = FastDateFormat.getInstance(
XMPP_DELAY_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));
private final DateFormat dateTimeFormat = new SimpleDateFormat(XMPP_DATETIME_FORMAT_WO_TIMEZONE + 'Z');
private final DateFormat dateTimeFormatWoMillies = new SimpleDateFormat(XMPP_DATETIME_FORMAT_WO_MILLIS_WO_TIMEZONE + 'Z');
private final DateFormat dateTimeFormatOld = new SimpleDateFormat(XMPP_DELAY_DATETIME_FORMAT);
/**
* Create a new thread-safe instance of this utility class
*/
public XMPPDateTimeFormat() {
TimeZone utc = TimeZone.getTimeZone("UTC");
dateTimeFormat.setTimeZone(utc);
dateTimeFormatWoMillies.setTimeZone(utc);
dateTimeFormatOld.setTimeZone(utc);
}
/**
* Tries to convert a given string to a Date object.
* This method supports the format types defined by XEP-0082 and the format defined in legacy protocols
* XEP-0082: CCYY-MM-DDThh:mm:ss[.sss]TZD
* legacy: CCYYMMDDThh:mm:ss
*
* @param dateStr
* @return
* @throws ParseException
*/
public synchronized Date parseString(String dateString) throws ParseException {
Matcher xep82WoMillisMatcher = xep80DateTimePattern.matcher(dateString);
Matcher xep82Matcher = xep80DateTimeWoMillisPattern.matcher(dateString);
if (xep82WoMillisMatcher.matches() || xep82Matcher.matches()) {
String rfc822Date;
// Convert the ISO 8601 time zone string to a RFC822 compatible format
// since SimpleDateFormat supports ISO8601 only with Java7 or higher
if (dateString.charAt(dateString.length() - 1) == 'Z') {
rfc822Date = dateString.replace("Z", "+0000");
} else {
// If the time zone wasn't specified with 'Z', then it's in
// ISO8601 format (i.e. '(+|-)HH:mm')
// RFC822 needs a similar format just without the colon (i.e.
// '(+|-)HHmm)'), so remove it
int lastColon = dateString.lastIndexOf(':');
rfc822Date = dateString.substring(0, lastColon) + dateString.substring(lastColon + 1);
}
if (xep82WoMillisMatcher.matches()) {
return dateTimeFormatWoMillies.parse(rfc822Date);
} else {
return dateTimeFormat.parse(rfc822Date);
}
} else {
// at last try with the legacy format
return dateTimeFormatOld.parse(dateString);
}
}
/**
* Tries to convert a given string to a Date object.
* This method only supports the legacy XMPP time format: CCYYMMDDThh:mm:ss
*
* @param dateStr
* @return
* @throws ParseException
*/
public synchronized Date parseOldDate(String dateStr) throws ParseException {
return dateTimeFormatOld.parse(dateStr);
}
/**
* Formats a Date object to String as defined in XEP-0082.
*
* The resulting String will have the timezone set to UTC ('Z') and includes milliseconds:
* CCYY-MM-DDThh:mm:ss.sssZ
*
* @param date
* @return
*/
public static String format(Date date) {
return FAST_FORMAT.format(date);
}
/**
* Formats a Date object to String as defined in legacy XMPP protocols (e.g. XEP-0090)
*
* CCYYMMDDThh:mm:ss
*
* @param date
* @return
*/
public static String formatOld(Date date) {
return FAST_FORMAT_OLD.format(date);
}
}
package com.reucon.openfire.plugin.archive.util; package com.reucon.openfire.plugin.archive.util;
import org.jivesoftware.util.JiveConstants; import org.jivesoftware.util.XMPPDateTimeFormat;
import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.TimeZone;
/** /**
* Utility class to parse and format dates in UTC that adhere to the DateTime format specified * Utility class to parse and format dates in UTC that adhere to the DateTime format specified
...@@ -14,61 +11,15 @@ import java.util.TimeZone; ...@@ -14,61 +11,15 @@ import java.util.TimeZone;
*/ */
public class XmppDateUtil public class XmppDateUtil
{ {
private static final DateFormat dateFormat; private static final XMPPDateTimeFormat xmppDateTime = new XMPPDateTimeFormat();
private static final DateFormat dateFormatWithoutMillis;
static
{
dateFormat = new SimpleDateFormat(JiveConstants.XMPP_DATETIME_FORMAT);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
dateFormatWithoutMillis = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
dateFormatWithoutMillis.setTimeZone(TimeZone.getTimeZone("UTC"));
}
private XmppDateUtil()
{
}
public static Date parseDate(String dateString) public static Date parseDate(String dateString)
{ {
Date date = null; try {
return xmppDateTime.parseString(dateString);
if (dateString == null) } catch (ParseException e) {
{
return null; return null;
} }
synchronized(dateFormat)
{
try
{
date = dateFormat.parse(dateString);
}
catch (ParseException e)
{
// ignore
}
}
if (date != null)
{
return date;
}
synchronized(dateFormatWithoutMillis)
{
try
{
date = dateFormatWithoutMillis.parse(dateString);
}
catch (ParseException e)
{
// ignore
}
}
return date;
} }
public static String formatDate(Date date) public static String formatDate(Date date)
...@@ -77,10 +28,6 @@ public class XmppDateUtil ...@@ -77,10 +28,6 @@ public class XmppDateUtil
{ {
return null; return null;
} }
return XMPPDateTimeFormat.format(date);
synchronized(dateFormat)
{
return dateFormat.format(date);
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment