conf: Add log4cxx path to conf file

refs: #1950

Change-Id: I51f9217c6ee40fd49a53d5f8294b60fb306e82ee
diff --git a/src/conf-file-processor.cpp b/src/conf-file-processor.cpp
index de36941..b3067a3 100644
--- a/src/conf-file-processor.cpp
+++ b/src/conf-file-processor.cpp
@@ -348,7 +348,7 @@
       }
     }
     else {
-      std::cerr << "Log directory provided does not exists" << std::endl;
+      std::cerr << "Provided log directory <" << logDir << "> does not exist" << std::endl;
       return false;
     }
   }
@@ -357,6 +357,7 @@
     std::cerr << ex.what() << std::endl;
     return false;
   }
+
   try {
     std::string seqDir = section.get<string>("seq-dir");
     if (boost::filesystem::exists(seqDir)) {
@@ -381,7 +382,7 @@
       }
     }
     else {
-      std::cerr << "Seq directory provided does not exists" << std::endl;
+      std::cerr << "Provided sequence directory <" << seqDir << "> does not exist" << std::endl;
       return false;
     }
   }
@@ -391,6 +392,28 @@
     return false;
   }
 
+  try {
+    std::string log4cxxPath = section.get<string>("log4cxx-conf");
+
+    if (log4cxxPath == "") {
+      std::cerr << "No value provided for log4cxx-conf" << std::endl;
+      return false;
+    }
+
+    if (boost::filesystem::exists(log4cxxPath)) {
+      m_nlsr.getConfParameter().setLog4CxxConfPath(log4cxxPath);
+    }
+    else {
+      std::cerr << "Provided path for log4cxx-conf <" << log4cxxPath
+                << "> does not exist" << std::endl;
+
+      return false;
+    }
+  }
+  catch (const std::exception& ex) {
+    // Variable is optional so default configuration will be used; continue processing file
+  }
+
   return true;
 }
 
@@ -648,4 +671,4 @@
   return true;
 }
 
-} // namespace nlsr
+} // namespace nlsr
\ No newline at end of file
diff --git a/src/conf-parameter.cpp b/src/conf-parameter.cpp
index 763d771..30f0cf4 100644
--- a/src/conf-parameter.cpp
+++ b/src/conf-parameter.cpp
@@ -20,6 +20,7 @@
  * \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
  *
  **/
+
 #include "conf-parameter.hpp"
 #include "logger.hpp"
 
diff --git a/src/conf-parameter.hpp b/src/conf-parameter.hpp
index 02eee7b..e25c4d3 100644
--- a/src/conf-parameter.hpp
+++ b/src/conf-parameter.hpp
@@ -111,6 +111,7 @@
     , m_corR(0)
     , m_corTheta(0)
     , m_maxFacesPerPrefix(MAX_FACES_PER_PREFIX_MIN)
+    , m_isLog4cxxConfAvailable(false)
   {
   }
 
@@ -381,6 +382,25 @@
     return m_seqFileDir;
   }
 
+  bool
+  isLog4CxxConfAvailable() const
+  {
+    return m_isLog4cxxConfAvailable;
+  }
+
+  void
+  setLog4CxxConfPath(const std::string& path)
+  {
+    m_log4CxxConfPath = path;
+    m_isLog4cxxConfAvailable = true;
+  }
+
+  const std::string&
+  getLog4CxxConfPath() const
+  {
+    return m_log4CxxConfPath;
+  }
+
   void
   writeLog();
 
@@ -420,6 +440,8 @@
   std::string m_logDir;
   std::string m_seqFileDir;
 
+  bool m_isLog4cxxConfAvailable;
+  std::string m_log4CxxConfPath;
 };
 
 } // namespace nlsr
diff --git a/src/logger.cpp b/src/logger.cpp
index a82f5a9..6451a32 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -22,16 +22,30 @@
  **/
 #include <log4cxx/logger.h>
 #include <log4cxx/basicconfigurator.h>
+#include <log4cxx/xml/domconfigurator.h>
+#include <log4cxx/propertyconfigurator.h>
 #include <log4cxx/patternlayout.h>
 #include <log4cxx/level.h>
 #include <log4cxx/helpers/exception.h>
 #include <log4cxx/rollingfileappender.h>
 
 #include <boost/algorithm/string.hpp>
+#include <boost/filesystem.hpp>
 
 #include "logger.hpp"
 
 void
+INIT_LOG4CXX(const std::string& log4cxxConfPath)
+{
+  if (boost::filesystem::path(log4cxxConfPath).extension().string() == ".xml") {
+    log4cxx::xml::DOMConfigurator::configure(log4cxxConfPath);
+  }
+  else {
+    log4cxx::PropertyConfigurator::configure(log4cxxConfPath);
+  }
+}
+
+void
 INIT_LOGGERS(const std::string& logDir, const std::string& logLevel)
 {
   static bool configured = false;
@@ -71,4 +85,4 @@
          boost::iequals(logLevel, "debug") || boost::iequals(logLevel, "info")  ||
          boost::iequals(logLevel, "warn")  || boost::iequals(logLevel, "error") ||
          boost::iequals(logLevel, "none");
-}
+}
\ No newline at end of file
diff --git a/src/logger.hpp b/src/logger.hpp
index 267f30f..2a8e907 100644
--- a/src/logger.hpp
+++ b/src/logger.hpp
@@ -20,6 +20,7 @@
  * \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
  *
  **/
+
 #ifndef NLSR_LOGGER_HPP
 #define NLSR_LOGGER_HPP
 
@@ -49,6 +50,9 @@
 void
 INIT_LOGGERS(const std::string& logDir, const std::string& logLevel);
 
+void
+INIT_LOG4CXX(const std::string& log4cxxConfPath);
+
 bool
 isValidLogLevel(const std::string& logLevel);
 
diff --git a/src/main.cpp b/src/main.cpp
index a21b0fd..45772aa 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -66,13 +66,20 @@
         return EXIT_FAILURE;
       }
   }
+
   ConfFileProcessor cfp(nlsr, nlsr.getConfFileName());
   if (!cfp.processConfFile()) {
     std::cerr << "Error in configuration file processing! Exiting from NLSR" << std::endl;
     return EXIT_FAILURE;
   }
 
-  INIT_LOGGERS(nlsr.getConfParameter().getLogDir(), nlsr.getConfParameter().getLogLevel());
+  if (nlsr.getConfParameter().isLog4CxxConfAvailable()) {
+    INIT_LOG4CXX(nlsr.getConfParameter().getLog4CxxConfPath());
+  }
+  else {
+    INIT_LOGGERS(nlsr.getConfParameter().getLogDir(), nlsr.getConfParameter().getLogLevel());
+  }
+
   INIT_LOGGER("Main");
 
   nlsr.initialize();
@@ -96,4 +103,4 @@
 main(int32_t argc, char** argv)
 {
   return nlsr::main(argc, argv);
-}
+}
\ No newline at end of file
diff --git a/src/nlsr.cpp b/src/nlsr.cpp
index a66e6aa..19bb3cf 100644
--- a/src/nlsr.cpp
+++ b/src/nlsr.cpp
@@ -20,6 +20,7 @@
  * \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
  *
  **/
+
 #include <cstdlib>
 #include <string>
 #include <sstream>