diff --git a/checkstyle.xml b/checkstyle.xml
new file mode 100644
index 0000000000..5a7f8d5526
--- /dev/null
+++ b/checkstyle.xml
@@ -0,0 +1,313 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 470c2c5f98..90e06a0793 100644
--- a/pom.xml
+++ b/pom.xml
@@ -85,13 +85,37 @@
3.5.1
1.6
2.8.2
+ 3.1.1
1.6.8
3.0.0
+ 8.32
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ ${maven-checkstyle-plugin-version}
+
+
+ com.puppycrawl.tools
+ checkstyle
+ ${checkstyle-version}
+
+
+
+ checkstyle.xml
+
+
+
+
+ check
+
+
+
+
org.apache.maven.plugins
maven-deploy-plugin
@@ -293,6 +317,28 @@
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ ${maven-checkstyle-plugin-version}
+
+
+
+
+
ossrh
diff --git a/quickfixj-core/src/main/java/quickfix/CachedFileStore.java b/quickfixj-core/src/main/java/quickfix/CachedFileStore.java
index 7a05793915..37941ba97f 100644
--- a/quickfixj-core/src/main/java/quickfix/CachedFileStore.java
+++ b/quickfixj-core/src/main/java/quickfix/CachedFileStore.java
@@ -163,6 +163,14 @@ public Date getCreationTime() throws IOException {
return cache.getCreationTime();
}
+ /*
+ * (non-Javadoc)
+ * @see quickfix.MessageStore#getCreationTimeCalendar()
+ */
+ public Calendar getCreationTimeCalendar() throws IOException {
+ return cache.getCreationTimeCalendar();
+ }
+
private void initializeSequenceNumbers() throws IOException {
sequenceNumberFile.seek(0);
if (sequenceNumberFile.length() > 0) {
diff --git a/quickfixj-core/src/main/java/quickfix/DefaultSessionSchedule.java b/quickfixj-core/src/main/java/quickfix/DefaultSessionSchedule.java
index 83d8bb5eab..184095f87f 100644
--- a/quickfixj-core/src/main/java/quickfix/DefaultSessionSchedule.java
+++ b/quickfixj-core/src/main/java/quickfix/DefaultSessionSchedule.java
@@ -41,10 +41,17 @@ public class DefaultSessionSchedule implements SessionSchedule {
private final int[] weekdayOffsets;
protected static final Logger LOG = LoggerFactory.getLogger(DefaultSessionSchedule.class);
+ //Cache recent time data to reduce creation of calendar objects
+ private ThreadLocal threadLocalCalendar;
+ private ThreadLocal threadLocalRecentTimeInterval;
+
public DefaultSessionSchedule(SessionSettings settings, SessionID sessionID) throws ConfigError,
FieldConvertError {
+ threadLocalCalendar = ThreadLocal.withInitial(SystemTime::getUtcCalendar);
+ threadLocalRecentTimeInterval = new ThreadLocal<>();
+ isNonStopSession = settings.isSetting(sessionID, Session.SETTING_NON_STOP_SESSION)
+ && settings.getBool(sessionID, Session.SETTING_NON_STOP_SESSION);
- isNonStopSession = settings.isSetting(sessionID, Session.SETTING_NON_STOP_SESSION) && settings.getBool(sessionID, Session.SETTING_NON_STOP_SESSION);
TimeZone defaultTimeZone = getDefaultTimeZone(settings, sessionID);
if (isNonStopSession) {
isWeekdaySession = false;
@@ -104,7 +111,7 @@ private TimeEndPoint getTimeEndPoint(SessionSettings settings, SessionID session
}
private TimeZone getDefaultTimeZone(SessionSettings settings, SessionID sessionID)
- throws ConfigError, FieldConvertError {
+ throws ConfigError {
TimeZone sessionTimeZone;
if (settings.isSetting(sessionID, Session.SETTING_TIMEZONE)) {
String sessionTimeZoneID = settings.getString(sessionID, Session.SETTING_TIMEZONE);
@@ -300,9 +307,16 @@ public boolean isSessionTime() {
if(isNonStopSession()) {
return true;
}
- Calendar now = SystemTime.getUtcCalendar();
- TimeInterval interval = theMostRecentIntervalBefore(now);
- return interval.isContainingTime(now);
+ Calendar now = threadLocalCalendar.get();
+ now.setTimeInMillis(SystemTime.currentTimeMillis());
+ TimeInterval mostRecentInterval = threadLocalRecentTimeInterval.get();
+ if (mostRecentInterval != null && mostRecentInterval.isContainingTime(now)) {
+ return true;
+ }
+ mostRecentInterval = theMostRecentIntervalBefore(now);
+ boolean result = mostRecentInterval.isContainingTime(now);
+ threadLocalRecentTimeInterval.set(mostRecentInterval);
+ return result;
}
public String toString() {
diff --git a/quickfixj-core/src/main/java/quickfix/FileStore.java b/quickfixj-core/src/main/java/quickfix/FileStore.java
index 20ec17f585..f9e3068a48 100644
--- a/quickfixj-core/src/main/java/quickfix/FileStore.java
+++ b/quickfixj-core/src/main/java/quickfix/FileStore.java
@@ -153,6 +153,14 @@ public Date getCreationTime() throws IOException {
return cache.getCreationTime();
}
+ /* (non-Javadoc)
+ * @see quickfix.MessageStore#getCreationTimeCalendar()
+ */
+ @Override
+ public Calendar getCreationTimeCalendar() throws IOException {
+ return cache.getCreationTimeCalendar();
+ }
+
private void initializeSequenceNumbers() throws IOException {
senderSequenceNumberFile.seek(0);
if (senderSequenceNumberFile.length() > 0) {
diff --git a/quickfixj-core/src/main/java/quickfix/JdbcStore.java b/quickfixj-core/src/main/java/quickfix/JdbcStore.java
index 1874d0953b..235784e635 100644
--- a/quickfixj-core/src/main/java/quickfix/JdbcStore.java
+++ b/quickfixj-core/src/main/java/quickfix/JdbcStore.java
@@ -155,6 +155,10 @@ public Date getCreationTime() throws IOException {
return cache.getCreationTime();
}
+ public Calendar getCreationTimeCalendar() throws IOException {
+ return cache.getCreationTimeCalendar();
+ }
+
public int getNextSenderMsgSeqNum() throws IOException {
return cache.getNextSenderMsgSeqNum();
}
diff --git a/quickfixj-core/src/main/java/quickfix/MemoryStore.java b/quickfixj-core/src/main/java/quickfix/MemoryStore.java
index f102056516..f3cb430ad4 100644
--- a/quickfixj-core/src/main/java/quickfix/MemoryStore.java
+++ b/quickfixj-core/src/main/java/quickfix/MemoryStore.java
@@ -70,6 +70,10 @@ public Date getCreationTime() throws IOException {
return creationTime.getTime();
}
+ public Calendar getCreationTimeCalendar() throws IOException {
+ return creationTime;
+ }
+
/* package */void setCreationTime(Calendar creationTime) {
this.creationTime = creationTime;
}
diff --git a/quickfixj-core/src/main/java/quickfix/MessageStore.java b/quickfixj-core/src/main/java/quickfix/MessageStore.java
index 8ff35aa3c9..aaa61ed43a 100644
--- a/quickfixj-core/src/main/java/quickfix/MessageStore.java
+++ b/quickfixj-core/src/main/java/quickfix/MessageStore.java
@@ -19,6 +19,7 @@
package quickfix;
+import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.io.IOException;
@@ -73,6 +74,14 @@ public interface MessageStore {
*/
Date getCreationTime() throws IOException;
+ /**
+ * Get the session creation time as a calendar object.
+ *
+ * @return the session creation time.
+ * @throws IOException IO error
+ */
+ Calendar getCreationTimeCalendar() throws IOException;
+
/**
* Reset the message store. Sequence numbers are set back to 1 and stored
* messages are erased. The session creation time is also set to the time of
diff --git a/quickfixj-core/src/main/java/quickfix/NoopStore.java b/quickfixj-core/src/main/java/quickfix/NoopStore.java
index ddc33b54ca..8bdc4cc354 100644
--- a/quickfixj-core/src/main/java/quickfix/NoopStore.java
+++ b/quickfixj-core/src/main/java/quickfix/NoopStore.java
@@ -20,6 +20,7 @@
package quickfix;
+import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
@@ -31,6 +32,7 @@
public class NoopStore implements MessageStore {
private Date creationTime = new Date();
+ private Calendar creationTimeCalendar = SystemTime.getUtcCalendar(creationTime);
private int nextSenderMsgSeqNum = 1;
private int nextTargetMsgSeqNum = 1;
@@ -41,6 +43,10 @@ public Date getCreationTime() {
return creationTime;
}
+ public Calendar getCreationTimeCalendar() {
+ return creationTimeCalendar;
+ }
+
public int getNextSenderMsgSeqNum() {
return nextSenderMsgSeqNum;
}
diff --git a/quickfixj-core/src/main/java/quickfix/Session.java b/quickfixj-core/src/main/java/quickfix/Session.java
index 897cc9bdf5..8fa06c3379 100644
--- a/quickfixj-core/src/main/java/quickfix/Session.java
+++ b/quickfixj-core/src/main/java/quickfix/Session.java
@@ -584,7 +584,7 @@ public String getRemoteAddress() {
private boolean isCurrentSession(final long time)
throws IOException {
return sessionSchedule == null || sessionSchedule.isSameSession(
- SystemTime.getUtcCalendar(time), SystemTime.getUtcCalendar(state.getCreationTime()));
+ SystemTime.getUtcCalendar(time), state.getCreationTimeCalendar());
}
/**
diff --git a/quickfixj-core/src/main/java/quickfix/SessionState.java b/quickfixj-core/src/main/java/quickfix/SessionState.java
index ef666c8520..6d894e7b75 100644
--- a/quickfixj-core/src/main/java/quickfix/SessionState.java
+++ b/quickfixj-core/src/main/java/quickfix/SessionState.java
@@ -20,6 +20,7 @@
package quickfix;
import java.io.IOException;
+import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
@@ -502,6 +503,10 @@ public Object getLock() {
return lock;
}
+ public Calendar getCreationTimeCalendar() throws IOException {
+ return messageStore.getCreationTimeCalendar();
+ }
+
private final static class NullLog implements Log {
public void onOutgoing(String message) {
}
diff --git a/quickfixj-core/src/main/java/quickfix/SleepycatStore.java b/quickfixj-core/src/main/java/quickfix/SleepycatStore.java
index e9e7aae1c2..3fddd79f54 100644
--- a/quickfixj-core/src/main/java/quickfix/SleepycatStore.java
+++ b/quickfixj-core/src/main/java/quickfix/SleepycatStore.java
@@ -256,10 +256,23 @@ private void convertToIOExceptionAndRethrow(Exception e) throws IOException {
throw ioe;
}
+
+ /*
+ * (non-Javadoc)
+ * @see quickfix.MessageStore#getCreationTime()
+ */
public Date getCreationTime() throws IOException {
return info.getCreationTime().getTime();
}
+ /*
+ * (non-Javadoc)
+ * @see quickfix.MessageStore#getCreationTimeCalendar()
+ */
+ public Calendar getCreationTimeCalendar() throws IOException {
+ return info.getCreationTime();
+ }
+
public int getNextSenderMsgSeqNum() throws IOException {
return info.getNextSenderMsgSeqNum();
}
diff --git a/quickfixj-core/src/test/java/quickfix/DefaultSessionScheduleTest.java b/quickfixj-core/src/test/java/quickfix/DefaultSessionScheduleTest.java
new file mode 100644
index 0000000000..7ae6919656
--- /dev/null
+++ b/quickfixj-core/src/test/java/quickfix/DefaultSessionScheduleTest.java
@@ -0,0 +1,120 @@
+package quickfix;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.ByteArrayInputStream;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+public class DefaultSessionScheduleTest {
+
+ private SessionID sessionID;
+ @Mock
+ private SystemTimeSource mockTimeSource;
+
+ @Before
+ public void before() {
+ MockitoAnnotations.initMocks(this);
+
+ sessionID = new SessionID("FIX.4.2:A->B");
+ SystemTime.setTimeSource(mockTimeSource);
+ }
+
+ @After
+ public void after() {
+ SystemTime.setTimeSource(null);
+ }
+
+ @Test
+ public void isNonStopSession_returns_true_when_SETTING_NON_STOP_SESSION_Y() throws FieldConvertError, ConfigError {
+ String sessionSettingsString = ""
+ + "[DEFAULT]\n"
+ + "NonStopSession=Y\n"
+ + "\n"
+ + "[SESSION]\n"
+ + "BeginString=FIX.4.2\n"
+ + "SenderCompID=A\n"
+ + "TargetCompID=B\n";
+ SessionSettings sessionSettings = new SessionSettings(new ByteArrayInputStream(sessionSettingsString.getBytes()));
+ DefaultSessionSchedule schedule = new DefaultSessionSchedule(sessionSettings, sessionID);
+
+ assertTrue(schedule.isNonStopSession());
+ }
+
+ @Test
+ public void isNonStopSession_returns_false_when_SETTING_NON_STOP_SESSION_N() throws FieldConvertError, ConfigError {
+ String sessionSettingsString = ""
+ + "[DEFAULT]\n"
+ + "NonStopSession=N\n"
+ + "\n"
+ + "[SESSION]\n"
+ + "BeginString=FIX.4.2\n"
+ + "SenderCompID=A\n"
+ + "TargetCompID=B\n"
+ + "StartTime=00:00:00\n"
+ + "EndTime=00:00:01\n";
+ SessionSettings sessionSettings = new SessionSettings(new ByteArrayInputStream(sessionSettingsString.getBytes()));
+ DefaultSessionSchedule schedule = new DefaultSessionSchedule(sessionSettings, sessionID);
+
+ assertFalse(schedule.isNonStopSession());
+ }
+
+ @Test
+ public void isNonStopSession_returns_false_when_SETTING_NON_STOP_SESSION_not_present() throws FieldConvertError, ConfigError {
+ String sessionSettingsString = ""
+ + "[DEFAULT]\n"
+ + "\n"
+ + "[SESSION]\n"
+ + "BeginString=FIX.4.2\n"
+ + "SenderCompID=A\n"
+ + "TargetCompID=B\n"
+ + "StartTime=00:00:00\n"
+ + "EndTime=00:00:01\n";
+ SessionSettings sessionSettings = new SessionSettings(new ByteArrayInputStream(sessionSettingsString.getBytes()));
+ DefaultSessionSchedule schedule = new DefaultSessionSchedule(sessionSettings, sessionID);
+
+ assertFalse(schedule.isNonStopSession());
+ }
+
+ @Test
+ public void isSessionTime_returns_true_for_time_within_window() throws FieldConvertError, ConfigError {
+ when(mockTimeSource.getTime()).thenReturn(1L);
+ String sessionSettingsString = ""
+ + "[DEFAULT]\n"
+ + "\n"
+ + "[SESSION]\n"
+ + "BeginString=FIX.4.2\n"
+ + "SenderCompID=A\n"
+ + "TargetCompID=B\n"
+ + "StartTime=00:00:00\n"
+ + "EndTime=00:00:01\n";
+ SessionSettings sessionSettings = new SessionSettings(new ByteArrayInputStream(sessionSettingsString.getBytes()));
+ DefaultSessionSchedule schedule = new DefaultSessionSchedule(sessionSettings, sessionID);
+
+ assertTrue(schedule.isSessionTime());
+ }
+
+ @Test
+ public void isSessionTime_returns_false_for_time_outside_window() throws FieldConvertError, ConfigError {
+ when(mockTimeSource.getTime()).thenReturn(2000L);
+ String sessionSettingsString = ""
+ + "[DEFAULT]\n"
+ + "\n"
+ + "[SESSION]\n"
+ + "BeginString=FIX.4.2\n"
+ + "SenderCompID=A\n"
+ + "TargetCompID=B\n"
+ + "StartTime=00:00:00\n"
+ + "EndTime=00:00:01\n";
+ SessionSettings sessionSettings = new SessionSettings(new ByteArrayInputStream(sessionSettingsString.getBytes()));
+ DefaultSessionSchedule schedule = new DefaultSessionSchedule(sessionSettings, sessionID);
+
+ assertFalse(schedule.isSessionTime());
+ }
+}
diff --git a/quickfixj-core/src/test/java/quickfix/LogUtilTest.java b/quickfixj-core/src/test/java/quickfix/LogUtilTest.java
index f533c7c042..f6b5af42e4 100644
--- a/quickfixj-core/src/test/java/quickfix/LogUtilTest.java
+++ b/quickfixj-core/src/test/java/quickfix/LogUtilTest.java
@@ -22,6 +22,7 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
+import java.util.Calendar;
import java.util.Date;
import org.junit.After;
import static org.junit.Assert.assertTrue;
@@ -60,7 +61,7 @@ private void createSessionAndGenerateException(LogFactory mockLogFactory) throws
Session session = new Session(null, sessionID1 -> {
try {
return new MemoryStore() {
- public Date getCreationTime() throws IOException {
+ public Calendar getCreationTimeCalendar() throws IOException {
throw new IOException("test");
}
};