Fix issues identified by static code analysis
- Class fields should not have public visibility
- Utility classes should not have public constructors
- Loggers should be "private static final" and should share a naming convention
- And more: cyclomatic complexity, class/method size, etc.
diff --git a/src/main/java/com/intel/jndn/mock/MockFace.java b/src/main/java/com/intel/jndn/mock/MockFace.java
index cf2f477..d0ec460 100644
--- a/src/main/java/com/intel/jndn/mock/MockFace.java
+++ b/src/main/java/com/intel/jndn/mock/MockFace.java
@@ -14,8 +14,6 @@
package com.intel.jndn.mock;
import net.named_data.jndn.*;
-import net.named_data.jndn.encoding.ElementListener;
-import net.named_data.jndn.encoding.ElementReader;
import net.named_data.jndn.encoding.EncodingException;
import net.named_data.jndn.encoding.TlvWireFormat;
import net.named_data.jndn.encoding.tlv.Tlv;
@@ -26,26 +24,31 @@
import net.named_data.jndn.transport.Transport;
import net.named_data.jndn.util.Blob;
-import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A client-side face for unit testing
+ *
+ * @author Alexander Afanasyev, <aa@cs.ucla.edu>
+ * @author Andrew Brown <andrew.brown@intel.com>
*/
public class MockFace extends Face {
+ /**
+ * API for handling {@link Interest}s
+ */
public interface SignalOnSendInterest {
-
void emit(Interest interest) throws EncodingException, SecurityException;
}
+ /**
+ * API for handling {@link Data}s
+ */
public interface SignalOnSendData {
-
void emit(Data data);
}
@@ -66,7 +69,10 @@
boolean enableRegistrationReply = false;
}
- final public static Options DEFAULT_OPTIONS = new Options() {
+ /**
+ * Default options
+ */
+ public static final Options DEFAULT_OPTIONS = new Options() {
{
enablePacketLogging = true;
enableRegistrationReply = true;
@@ -74,8 +80,10 @@
};
/**
- * Create MockFace that logs packets in sentInterests and sentData and
- * emulates NFD prefix registration
+ * Create MockFace that logs packets in {@link #sentInterests} and
+ * {@link #sentData} and emulates NFD prefix registration
+ *
+ * @throws SecurityException should not be thrown by this test class
*/
public MockFace() throws SecurityException {
this(DEFAULT_OPTIONS);
@@ -94,42 +102,23 @@
*
* To create Face that just logs packets in sentInterests and sentData:
* <pre>
- * new MockFace(new Options(){{ enablePacketLogging=true; }});
+ * new MockFace(new Options(){ enablePacketLogging = true; });
* </pre>
+ *
+ * @param options see {@link Options}
*/
- public MockFace(Options options) throws SecurityException {
+ public MockFace(Options options) {
super(new MockFaceTransport(), null);
- m_transport = (MockFaceTransport) node_.getTransport();
- m_keychain = MockKeyChain.configure(new Name("/mock/key"));
- setCommandSigningInfo(m_keychain, m_keychain.getDefaultCertificateName());
+ transport = (MockFaceTransport) node_.getTransport();
+ transport.setOnSendBlock(new OnIncomingPacket());
- m_transport.onSendBlock = new MockFaceTransport.OnSendBlockSignal() {
- @Override
- public void emit(ByteBuffer buffer) throws EncodingException, SecurityException {
- // @todo Implement NDNLP processing
-
- if (buffer.get(0) == Tlv.Interest || buffer.get(0) == Tlv.Data) {
- TlvDecoder decoder = new TlvDecoder(buffer);
- if (decoder.peekType(Tlv.Interest, buffer.remaining())) {
- Interest interest = new Interest();
- interest.wireDecode(buffer, TlvWireFormat.get());
-
- for (SignalOnSendInterest signal : onSendInterest) {
- signal.emit(interest);
- }
- } else if (decoder.peekType(Tlv.Data, buffer.remaining())) {
- Data data = new Data();
- data.wireDecode(buffer, TlvWireFormat.get());
-
- for (SignalOnSendData signal : onSendData) {
- signal.emit(data);
- }
- }
- } else {
- logger.info("Received an unknown packet");
- }
- }
- };
+ try {
+ keyChain = MockKeyChain.configure(new Name("/mock/key"));
+ setCommandSigningInfo(keyChain, keyChain.getDefaultCertificateName());
+ } catch (SecurityException ex) {
+ LOGGER.log(Level.SEVERE, "Unexpected error in MockKeyChain; this class should never throw", ex);
+ throw new Error(ex);
+ }
if (options.enablePacketLogging) {
onSendInterest.add(new SignalOnSendInterest() {
@@ -148,181 +137,106 @@
}
if (options.enableRegistrationReply) {
- onSendInterest.add(new SignalOnSendInterest() {
- @Override
- public void emit(Interest interest) throws EncodingException, SecurityException {
- final Name localhostRegistration = new Name("/localhost/nfd/rib");
- if (!interest.getName().getPrefix(3).equals(localhostRegistration)) {
- return;
+ onSendInterest.add(new OnPrefixRegistration());
+ }
+ }
+
+ /**
+ * Route incoming packets to the correct callbacks
+ */
+ private class OnIncomingPacket implements MockFaceTransport.OnSendBlockSignal {
+
+ @Override
+ public void emit(ByteBuffer buffer) throws EncodingException, SecurityException {
+ // @todo Implement NDNLP processing
+
+ if (buffer.get(0) == Tlv.Interest || buffer.get(0) == Tlv.Data) {
+ TlvDecoder decoder = new TlvDecoder(buffer);
+ if (decoder.peekType(Tlv.Interest, buffer.remaining())) {
+ Interest interest = new Interest();
+ interest.wireDecode(buffer, TlvWireFormat.get());
+
+ for (SignalOnSendInterest signal : onSendInterest) {
+ signal.emit(interest);
}
-
- ControlParameters params = new ControlParameters();
- params.wireDecode(interest.getName().get(-5).getValue());
- params.setFaceId(1);
- params.setOrigin(0);
-
- if (interest.getName().get(3).toString().equals("register")) {
- params.setCost(0);
- }
-
- // TODO: replace with jNDN ControlResponse encoding when available
- // http://redmine.named-data.net/issues/3455
- TlvEncoder encoder = new TlvEncoder(256);
- int saveLength = encoder.getLength();
- encoder.writeBuffer(params.wireEncode().buf());
- encoder.writeBlobTlv(Tlv.NfdCommand_StatusText, new Blob("OK").buf());
- encoder.writeNonNegativeIntegerTlv(Tlv.NfdCommand_StatusCode, 200);
- encoder.writeTypeAndLength(Tlv.NfdCommand_ControlResponse, encoder.getLength() - saveLength);
-
+ } else if (decoder.peekType(Tlv.Data, buffer.remaining())) {
Data data = new Data();
- data.setName(interest.getName());
- data.setContent(new Blob(encoder.getOutput(), false));
- m_keychain.sign(data);
+ data.wireDecode(buffer, TlvWireFormat.get());
- receive(data);
+ for (SignalOnSendData signal : onSendData) {
+ signal.emit(data);
+ }
}
- });
+ } else {
+ LOGGER.info("Received an unknown packet");
+ }
+ }
+ }
+
+ /**
+ * Handle prefix registration requests
+ */
+ private class OnPrefixRegistration implements SignalOnSendInterest {
+
+ @Override
+ public void emit(Interest interest) throws EncodingException, SecurityException {
+ final Name localhostRegistration = new Name("/localhost/nfd/rib");
+ if (!interest.getName().getPrefix(3).equals(localhostRegistration)) {
+ return;
+ }
+
+ ControlParameters params = new ControlParameters();
+ params.wireDecode(interest.getName().get(-5).getValue());
+ params.setFaceId(1);
+ params.setOrigin(0);
+
+ if ("register".equals(interest.getName().get(3).toString())) {
+ params.setCost(0);
+ }
+
+ // TODO: replace with jNDN ControlResponse encoding when available
+ // http://redmine.named-data.net/issues/3455
+ TlvEncoder encoder = new TlvEncoder(256);
+ int saveLength = encoder.getLength();
+ encoder.writeBuffer(params.wireEncode().buf());
+ encoder.writeBlobTlv(Tlv.NfdCommand_StatusText, new Blob("OK").buf());
+ encoder.writeNonNegativeIntegerTlv(Tlv.NfdCommand_StatusCode, 200);
+ encoder.writeTypeAndLength(Tlv.NfdCommand_ControlResponse, encoder.getLength() - saveLength);
+
+ Data data = new Data();
+ data.setName(interest.getName());
+ data.setContent(new Blob(encoder.getOutput(), false));
+ keyChain.sign(data);
+
+ receive(data);
}
}
/**
* Mock reception of the Interest packet on the Face (from transport)
+ *
* @param interest the mock-remote interest to add to the PIT
* @throws EncodingException if packet encoding fails (it should not)
*/
public void receive(Interest interest) throws EncodingException {
- m_transport.receive(interest.wireEncode().buf());
+ transport.receive(interest.wireEncode().buf());
}
/**
* Mock reception of the Data packet on the Face (from transport)
+ *
* @param data the mock-remote data to add to the CS
* @throws EncodingException if packet encoding fails (it should not)
*/
public void receive(Data data) throws EncodingException {
- m_transport.receive(data.wireEncode().buf());
+ transport.receive(data.wireEncode().buf());
}
/**
* @return the transport for this face
*/
public Transport getTransport() {
- return m_transport;
- }
-
- /**
- * Internal transport for {@link MockFace}
- */
- private static class MockFaceTransport extends Transport {
-
- public interface OnSendBlockSignal {
-
- void emit(ByteBuffer buffer) throws EncodingException, SecurityException;
- }
-
- /**
- * Receive some bytes to add to the mock socket
- * @param block the byte buffer
- * @throws EncodingException
- */
- public void receive(ByteBuffer block) throws EncodingException {
- synchronized (receiveBuffer) {
- receiveBuffer.add(block.duplicate());
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isLocal(ConnectionInfo connectionInfo) {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isAsync() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void connect(Transport.ConnectionInfo connectionInfo,
- ElementListener elementListener, Runnable onConnected) {
- logger.fine("Connecting...");
- connected = true;
- elementReader = new ElementReader(elementListener);
- if (onConnected != null) {
- onConnected.run();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void send(ByteBuffer data) throws IOException {
- logger.log(Level.FINE, "Sending {0} bytes", (data.capacity() - data.position()));
-
- try {
- onSendBlock.emit(data);
- } catch (EncodingException e) {
- logger.log(Level.WARNING, "Failed to decode packet", e);
- } catch (SecurityException e) {
- logger.log(Level.WARNING, "Failed signature", e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void processEvents() throws IOException, EncodingException {
- if (!getIsConnected()) {
- logger.warning("Not connnected...");
- }
-
- while (true) {
- ByteBuffer block = null;
- synchronized (receiveBuffer) {
- if (!receiveBuffer.isEmpty()) {
- block = receiveBuffer.remove(0);
- }
- }
- if (block == null) {
- break;
- }
- elementReader.onReceivedData(block);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean getIsConnected() {
- return connected;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void close() throws IOException {
- logger.fine("Closing...");
- connected = false;
- }
-
- public OnSendBlockSignal onSendBlock;
-
- private static final Logger logger = Logger.getLogger(MockFaceTransport.class.getName());
- private boolean connected;
- private ElementReader elementReader;
- private final List<ByteBuffer> receiveBuffer = new LinkedList<>();
+ return transport;
}
/**
@@ -333,7 +247,7 @@
* if necessary. After .expressInterest, .processEvents must be called before
* the Interest would show up here.
*/
- public List<Interest> sentInterests = new ArrayList<>();
+ public final List<Interest> sentInterests = new ArrayList<>();
/**
* Data sent out of this MockFace
@@ -343,7 +257,7 @@
* necessary. After .put, .processEvents must be called before the Data would
* show up here.
*/
- public List<Data> sentData = new ArrayList<>();
+ public final List<Data> sentData = new ArrayList<>();
/**
* Emits whenever an Interest is sent
@@ -351,7 +265,7 @@
* After .expressInterest, .processEvents must be called before this signal
* would be emitted.
*/
- public List<SignalOnSendInterest> onSendInterest = new ArrayList<>();
+ public final List<SignalOnSendInterest> onSendInterest = new ArrayList<>();
/**
* Emits whenever a Data packet is sent
@@ -359,9 +273,9 @@
* After .putData, .processEvents must be called before this signal would be
* emitted.
*/
- public List<SignalOnSendData> onSendData = new ArrayList<>();
+ public final List<SignalOnSendData> onSendData = new ArrayList<>();
- private static final Logger logger = Logger.getLogger(MockFace.class.getName());
- private MockFaceTransport m_transport;
- private KeyChain m_keychain;
+ private static final Logger LOGGER = Logger.getLogger(MockFace.class.getName());
+ private MockFaceTransport transport;
+ private KeyChain keyChain;
}
diff --git a/src/main/java/com/intel/jndn/mock/MockKeyChain.java b/src/main/java/com/intel/jndn/mock/MockKeyChain.java
index 2933c0a..b367808 100644
--- a/src/main/java/com/intel/jndn/mock/MockKeyChain.java
+++ b/src/main/java/com/intel/jndn/mock/MockKeyChain.java
@@ -29,6 +29,10 @@
*/
public class MockKeyChain {
+ private MockKeyChain() {
+ // do not allow instances of this key chain
+ }
+
/**
* Build and configure an in-memory {@link KeyChain}.
*
diff --git a/src/main/java/com/intel/jndn/mock/MockTransport.java b/src/main/java/com/intel/jndn/mock/MockTransport.java
new file mode 100644
index 0000000..1fd935d
--- /dev/null
+++ b/src/main/java/com/intel/jndn/mock/MockTransport.java
@@ -0,0 +1,156 @@
+/*
+ * jndn-mock
+ * Copyright (c) 2015, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 3, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+package com.intel.jndn.mock;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import net.named_data.jndn.encoding.ElementListener;
+import net.named_data.jndn.encoding.ElementReader;
+import net.named_data.jndn.encoding.EncodingException;
+import net.named_data.jndn.security.SecurityException;
+import net.named_data.jndn.transport.Transport;
+
+/**
+ * Non-public class for handling data buffering in NDN unit tests; works in
+ * conjunction with {@link MockFace}.
+ *
+ * @author Alexander Afanasyev, <aa@cs.ucla.edu>
+ * @author Andrew Brown <andrew.brown@intel.com>
+ */
+class MockFaceTransport extends Transport {
+
+ /**
+ * API for buffer handling
+ */
+ public interface OnSendBlockSignal {
+ void emit(ByteBuffer buffer) throws EncodingException, SecurityException;
+ }
+
+ /**
+ * Receive some bytes to add to the mock socket
+ *
+ * @param block the byte buffer
+ * @throws EncodingException
+ */
+ public void receive(ByteBuffer block) throws EncodingException {
+ synchronized (receiveBuffer) {
+ receiveBuffer.add(block.duplicate());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isLocal(Transport.ConnectionInfo connectionInfo) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isAsync() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void connect(Transport.ConnectionInfo connectionInfo,
+ ElementListener elementListener, Runnable onConnected) {
+ LOGGER.fine("Connecting...");
+ connected = true;
+ elementReader = new ElementReader(elementListener);
+ if (onConnected != null) {
+ onConnected.run();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void send(ByteBuffer data) throws IOException {
+ LOGGER.log(Level.FINE, "Sending {0} bytes", data.capacity() - data.position());
+
+ try {
+ onSendBlock.emit(data);
+ } catch (EncodingException e) {
+ LOGGER.log(Level.WARNING, "Failed to decode packet", e);
+ } catch (SecurityException e) {
+ LOGGER.log(Level.WARNING, "Failed signature", e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void processEvents() throws IOException, EncodingException {
+ if (!getIsConnected()) {
+ LOGGER.warning("Not connnected...");
+ }
+
+ while (true) {
+ ByteBuffer block = null;
+ synchronized (receiveBuffer) {
+ if (!receiveBuffer.isEmpty()) {
+ block = receiveBuffer.remove(0);
+ }
+ }
+ if (block == null) {
+ break;
+ }
+ elementReader.onReceivedData(block);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean getIsConnected() {
+ return connected;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void close() throws IOException {
+ LOGGER.fine("Closing...");
+ connected = false;
+ }
+
+ /**
+ * @param onSendBlock the handler to execute when packets are received;
+ * ideally this would be hidden completely but the super() call in MockFace
+ * requires this callback to be set after the parent constructor is called
+ */
+ public void setOnSendBlock(OnSendBlockSignal onSendBlock) {
+ this.onSendBlock = onSendBlock;
+ }
+
+ private OnSendBlockSignal onSendBlock;
+ private static final Logger LOGGER = Logger.getLogger(MockFaceTransport.class.getName());
+ private boolean connected;
+ private ElementReader elementReader;
+ private final List<ByteBuffer> receiveBuffer = new LinkedList<>();
+}
diff --git a/src/test/java/com/intel/jndn/mock/MockFaceTest.java b/src/test/java/com/intel/jndn/mock/MockFaceTest.java
index 9682f95..32a8d35 100644
--- a/src/test/java/com/intel/jndn/mock/MockFaceTest.java
+++ b/src/test/java/com/intel/jndn/mock/MockFaceTest.java
@@ -193,8 +193,7 @@
/////////////////////////////////////////////////////////////////////////////
- private void
- run(int limit, int maxCounter) throws IOException, EncodingException, InterruptedException {
+ private void run(int limit, int maxCounter) throws IOException, EncodingException, InterruptedException {
// process face until a response is received
int allowedLoops = limit;
while (counter < maxCounter && allowedLoops > 0) {
@@ -204,8 +203,7 @@
}
}
- private void
- run(int limit) throws IOException, EncodingException, InterruptedException {
+ private void run(int limit) throws IOException, EncodingException, InterruptedException {
run(limit, 1);
}
@@ -231,7 +229,6 @@
/////////////////////////////////////////////////////////////////////////////
private static final Logger logger = Logger.getLogger(MockFaceTest.class.getName());
-
private MockFace face;
private int counter;
private Data recvData = null;