I'm developing a Java EE project which uses Redis through the Jedis library. I'm retrieving the chat history of a particular channel from the servlet context and if absent, from Redis.
The PMD plugin of Netbeans shows me a message that the Cyclomatic Complexity of the code is 15 which is very large. I wish to reduce that and I need to know if there is a better mechanism which can be used.
private transient final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(HistoryRetriever.class);
private transient final JedisHelper jedisHelper = new JedisHelper();
public String retrieveHistory(final JSONObject data) {
final ServletContext context = ContextManager.getContext();
JSONObject object = new JSONObject();
final Jedis jedis = jedisHelper.getJedisObjectFromPool();
try {
String key1, key2, channel, timestamp, count;
key1 = data.getString("key1");
key2 = data.getString("key2");
channel = key2 + "_" + data.getString("channel-id");
timestamp = "";
count = "";
int historyType = 0;
LOGGER.info("History requested for " + channel + " belonging to subkey: " + key2);
if (jedisHelper.checkValidity(key1, key2)) {
if (data.has("timestamp")) {
historyType = 1;
timestamp = data.getString("timestamp");
}
if (data.has("count")) {
historyType = 2;
count = data.getString("count");
}
ConcurrentHashMap history = (ConcurrentHashMap) context.getAttribute("history");
if (null == history) {
history = new ConcurrentHashMap<Object, Object>();
context.setAttribute("history", history);
object = getHistoryFromRedis(timestamp, count, channel, historyType);
} else {
ConcurrentSkipListMap<Long, String> myHistory = (ConcurrentSkipListMap<Long, String>) history.get(channel);
if (null == myHistory) {
LOGGER.info("History for this channel not found in Context");
myHistory = new ConcurrentSkipListMap<Long, String>();
history.put(channel, myHistory);
object = getHistoryFromRedis(timestamp, count, channel, historyType);
} else {
/* Check for history in context */
if (historyType == 1) {
final Map<Long, String> channelHistory = myHistory.tailMap(Long.parseLong(timestamp));
if (!channelHistory.isEmpty()) {
for (Map.Entry<Long, String> entry : channelHistory.entrySet()) {
object.put(String.valueOf(entry.getKey()), entry.getValue());
}
}
}
if (historyType == 2) {
final Map<Long, String> channelHistory = myHistory.descendingMap();
if (!channelHistory.isEmpty()) {
int counter = 0;
final int i = Integer.parseInt(count);
for (Map.Entry<Long, String> entry : channelHistory.entrySet()) {
if (counter >= i) {
break;
}
object.put(String.valueOf(entry.getKey()), entry.getValue());
counter++;
}
}
}
}
}
} else {
LOGGER.info("Invalid Keys or keys deactivated");
}
} catch (JSONException ex) {
LOGGER.error("JSON Exception: " + ex);
} catch (NumberFormatException ex) {
LOGGER.error("NumberFormatException: " + ex);
} finally {
jedisHelper.returnJedisObjectToPool(jedis);
LOGGER.info("History is: " + object.toString());
}
return object.toString();
}
private JSONObject getHistoryFromRedis(final String timestamp, final String count, final String channelId, final int type) {
LOGGER.info("get history from redis");
Set<Tuple> set = null;
JSONObject history = new JSONObject();
try {
final Jedis jedis = jedisHelper.getJedisObjectFromPool();
if (type == 1 && timestamp != null && !timestamp.isEmpty() && !"0".equals(timestamp)) {
set = jedis.zrangeByScoreWithScores(channelId, timestamp, String.valueOf(System.currentTimeMillis()));
}
if (type == 2 && !"0".equals(count)) {
final int limit = Integer.parseInt(count);
set = jedis.zrevrangeByScoreWithScores(channelId, "+inf", "-inf", 0, limit);
}
if (set != null) {
history = new JSONObject(set);
}
jedisHelper.returnJedisObjectToPool(jedis);
} catch (NumberFormatException ex) {
LOGGER.error("Exception in returning history from Redis: " + ex);
}
return history;
}
returnJedisObjectToPool
in the second method from afinally
block, so that is a resource leak hazard. – abuzittin gillifirca Nov 29 '13 at 15:04