From fd8da9e04b9836ff0c8525b56515c26bc1185de1 Mon Sep 17 00:00:00 2001
From: Marco De Marco <demarco@oats.inaf.it>
Date: Thu, 6 Feb 2014 22:25:10 +0100
Subject: [PATCH] Properties checks added

---
 src/Configuration.h  |  22 ++++--
 src/PreProcessor.cpp | 180 +++++++++++++++++++++++++++++++++++++++++--
 src/PreProcessor.h   |  31 +++++++-
 3 files changed, 219 insertions(+), 14 deletions(-)

diff --git a/src/Configuration.h b/src/Configuration.h
index d2ebeaf..50574f9 100644
--- a/src/Configuration.h
+++ b/src/Configuration.h
@@ -21,10 +21,12 @@ private:
 //------------------------------------------------------------------------------
 //	[Private] Constructor destructor deleter
 //------------------------------------------------------------------------------
-	Configuration(std::string watchPath, std::string destPath, int workerNumber,
-        int sleepTime, int waitTime, uint32_t iNotifyMask) : m_watchPath(watchPath),
-        m_destPath(destPath), m_workerNumber(workerNumber), m_sleepTime(sleepTime),
-        m_waitTime(waitTime), m_iNotifyMask(iNotifyMask) { }
+	Configuration(std::string watchPath, std::string destPath,
+        std::string scriptPath, int workerNumber, int sleepTime, int waitTime,
+        uint32_t iNotifyMask) : m_watchPath(watchPath), m_destPath(destPath),
+        m_scriptPath(scriptPath), m_workerNumber(workerNumber),
+        m_sleepTime(sleepTime), m_waitTime(waitTime),
+        m_iNotifyMask(iNotifyMask) { }
 
 	virtual ~Configuration() {}
 
@@ -41,16 +43,19 @@ public:
 //	[Public] User methods
 //------------------------------------------------------------------------------
 	static Configuration::SP create(std::string watchPath, std::string destPath,
-        int workerNumber, int sleepTime, int waitTime, uint32_t iNotifyMask)
+        std::string scriptPath, int workerNumber, int sleepTime, int waitTime,
+        uint32_t iNotifyMask)
 	{
-		Configuration::SP c_sp(new Configuration(watchPath, destPath, workerNumber,
-			 sleepTime, waitTime, iNotifyMask), Configuration::Deleter());
+		Configuration::SP c_sp(new Configuration(watchPath, destPath, scriptPath,
+             workerNumber, sleepTime, waitTime, iNotifyMask),
+             Configuration::Deleter());
 
 		return c_sp;
 	}
 
 	std::string getWatchPath() const { return m_watchPath; }
     std::string getDestPath() const { return m_destPath; }
+    std::string getScriptPath() const { return m_scriptPath; }
 	unsigned int getWorkerNumber() const { return m_workerNumber; }
     unsigned int getSleepTime() const { return m_sleepTime; }
 	unsigned int getWaitTime() const { return m_waitTime; }
@@ -66,6 +71,9 @@ private:
     //File destination path
     const std::string m_destPath;
 
+    //Script path file
+    const std::string m_scriptPath;
+
 	//Worker thread number
 	const unsigned int m_workerNumber;
 
diff --git a/src/PreProcessor.cpp b/src/PreProcessor.cpp
index 60497b5..8c95422 100644
--- a/src/PreProcessor.cpp
+++ b/src/PreProcessor.cpp
@@ -135,7 +135,8 @@ void PreProcessor::init_device()
 	DEBUG_STREAM << "PreProcessor::init_device() create device " << device_name << endl;
 	/*----- PROTECTED REGION ID(PreProcessor::init_device_before) ENABLED START -----*/
 
-	//	Initialization before get_device_property() call
+    set_state(Tango::INIT);
+    set_status("Initializing device");
 
 	/*----- PROTECTED REGION END -----*/	//	PreProcessor::init_device_before
 
@@ -146,7 +147,30 @@ void PreProcessor::init_device()
 
 	/*----- PROTECTED REGION ID(PreProcessor::init_device) ENABLED START -----*/
 
-	//	Initialize device
+    try
+    {
+            //Create event thread
+            m_eventThread_sp = EventThread::create(this, m_configuration_sp);
+
+            //Start device if auto start enabled
+//            if(autoStart)
+//            {
+//                INFO_STREAM << "FitsImporter::init_device() auto start enabled " << endl;
+//                on();
+//            }
+    }
+    catch(std::exception& ex)
+    {
+        set_state(Tango::FAULT);
+        std::stringstream error_stream;
+        error_stream << "PreProcessor::init_device() " << ex.what() << std::endl;
+        set_status(error_stream.str());
+    }
+    catch(...)
+    {
+        set_state(Tango::FAULT);
+        set_status("PreProcessor::init_device() unknown error");
+    }
 
 	/*----- PROTECTED REGION END -----*/	//	PreProcessor::init_device
 }
@@ -269,7 +293,51 @@ void PreProcessor::get_device_property()
 
 	/*----- PROTECTED REGION ID(PreProcessor::get_device_property_after) ENABLED START -----*/
 
-	//	Check device property data members init
+    try
+    {
+        if(watchPath.empty())
+            throw(invalid_argument("WatchPath property is empty or not defined"));
+
+        if(destPath.empty())
+            throw(invalid_argument("DestPath property is empty or not defined"));
+
+        if(scriptPath.empty())
+            throw(invalid_argument("ScriptPath property is empty or not defined"));
+
+        if(eventList.empty())
+            throw(invalid_argument("EventList property is empty or not defined"));
+
+        for(vector<string>::size_type e_ind=0; e_ind<eventList.size(); ++e_ind)
+            if(eventList.at(e_ind).empty())
+            {
+                stringstream event_list_error;
+                event_list_error << "EventList property has an empty element at \""
+                        << e_ind << "\" position" << endl;
+                throw(invalid_argument(event_list_error.str()));
+            }
+
+        //Create i-notify mask from event list property
+        const uint32_t inotifyMask = create_inotify_mask(eventList);
+
+        if(sleepTime<MIN_SLEEP_TIME || sleepTime>MAX_SLEEP_TIME)
+            throw(invalid_argument("SleepTime property is out of range or not defined"));
+
+        if(waitTime>MAX_WAIT_TIME)
+            throw(invalid_argument("WaitTime property is out of range or not defined"));
+
+        if(workerNumber<1 || workerNumber>MAX_WORKER_NUMBER)
+            throw(invalid_argument("WorkerNumber property out of range or not defined"));
+
+        m_configuration_sp = Configuration::create(watchPath,
+            destPath, scriptPath, workerNumber, sleepTime, waitTime, inotifyMask);
+    }
+    catch(invalid_argument& ex)
+    {
+        set_state(Tango::FAULT);
+        stringstream error_stream;
+        error_stream << "FitsImporter::get_device_property() " << ex.what() << endl;
+        set_status(error_stream.str());
+    }
 
 	/*----- PROTECTED REGION END -----*/	//	PreProcessor::get_device_property_after
 }
@@ -285,7 +353,15 @@ void PreProcessor::always_executed_hook()
 	INFO_STREAM << "PreProcessor::always_executed_hook()  " << device_name << endl;
 	/*----- PROTECTED REGION ID(PreProcessor::always_executed_hook) ENABLED START -----*/
 
-	//	code always executed before all requests
+	if(get_state() != Tango::FAULT)
+    {
+        if(m_eventThread_sp)
+        {
+            set_state(m_eventThread_sp->readState());
+
+            set_status(m_eventThread_sp->readStatus());
+        }
+    }
 
 	/*----- PROTECTED REGION END -----*/	//	PreProcessor::always_executed_hook
 }
@@ -358,7 +434,101 @@ void PreProcessor::off()
 
 /*----- PROTECTED REGION ID(PreProcessor::namespace_ending) ENABLED START -----*/
 
-//	Additional Methods
+//==============================================================================
+//	FitsImporter::create_inotify_mask()
+//==============================================================================
+uint32_t PreProcessor::create_inotify_mask(const std::vector<std::string>& event_list)
+    throw(std::invalid_argument)
+{
+    DEBUG_STREAM << "PreProcessor::create_inotify_mask()  - " << device_name << endl;
+
+	uint32_t iNotifyMask = 0;
+
+	if(event_list.empty())
+		throw std::invalid_argument("PreProcessor::create_inotify_mask(): "
+                "event list is empty");
+
+	std::vector<std::string>::const_iterator it;
+	for(it=event_list.begin(); it!=event_list.end(); it++)
+	{
+        std::stringstream event_stream;
+        event_stream << "FitsImporter::create_inotify_mask() ";
+
+		if(it->compare("IN_ACCESS")==0)
+		{
+            event_stream << "IN_ACCESS event found";
+			iNotifyMask += IN_ACCESS;
+		}
+		else if(it->compare("IN_MODIFY")==0)
+		{
+
+            event_stream << "IN_MODIFY event found";
+			iNotifyMask += IN_MODIFY;
+		}
+		else if(it->compare("IN_ATTRIB")==0)
+		{
+            event_stream << "IN_ATTRIB event found";
+			iNotifyMask += IN_ATTRIB;
+		}
+		else if(it->compare("IN_CLOSE_WRITE")==0)
+		{
+            event_stream << "IN_CLOSE_WRITE event found";
+			iNotifyMask += IN_CLOSE_WRITE;
+		}
+		else if(it->compare("IN_CLOSE_NOWRITE")==0)
+		{
+            event_stream << "IN_CLOSE_NOWRITE event found";
+			iNotifyMask += IN_CLOSE_NOWRITE;
+		}
+		else if(it->compare("IN_OPEN")==0)
+		{
+            event_stream << "IN_OPEN event found";
+			iNotifyMask += IN_OPEN;
+		}
+		else if(it->compare("IN_MOVED_FROM")==0)
+		{
+            event_stream << "IN_MOVED_FROM event found";
+			iNotifyMask += IN_MOVED_FROM;
+		}
+		else if(it->compare("IN_MOVED_TO")==0)
+		{
+            event_stream << "IN_MOVED_TO event found";
+			iNotifyMask += IN_MOVED_TO;
+		}
+		else if(it->compare("IN_DELETE")==0)
+		{
+            event_stream << "IN_DELETE event found";
+			iNotifyMask += IN_DELETE;
+		}
+		else if(it->compare("IN_DELETE_SELF")==0)
+		{
+            event_stream << "IN_DELETE_SELF event found";
+			iNotifyMask += IN_DELETE_SELF;
+		}
+		else if(it->compare("IN_CLOSE")==0)
+		{
+            event_stream << "IN_CLOSE event found";
+			iNotifyMask += IN_CLOSE;
+		}
+		else if(it->compare("IN_MOVE")==0)
+		{
+            event_stream << "IN_MOVE event found";
+			iNotifyMask += IN_MOVE;
+		}
+		else if(it->compare("IN_ALL_EVENTS")==0)
+		{
+            event_stream << "IN_ALL_EVENTS event found";
+			iNotifyMask += IN_ALL_EVENTS;
+		}
+		else
+			throw std::invalid_argument("FitsImporter::create_inotify_mask() "
+                    "string \"" + *it + " \" is invalid inotify event");
+
+        INFO_STREAM << event_stream.str() << endl;
+	}
+
+	return iNotifyMask;
+}
 
 /*----- PROTECTED REGION END -----*/	//	PreProcessor::namespace_ending
 } //	namespace
diff --git a/src/PreProcessor.h b/src/PreProcessor.h
index a8d5336..e472238 100644
--- a/src/PreProcessor.h
+++ b/src/PreProcessor.h
@@ -38,6 +38,9 @@
 #ifndef PreProcessor_H
 #define PreProcessor_H
 
+#include <Configuration.h>
+#include <EventThread.h>
+
 #include <tango.h>
 
 
@@ -61,7 +64,26 @@ class PreProcessor : public TANGO_BASE_CLASS
 
 /*----- PROTECTED REGION ID(PreProcessor::Data Members) ENABLED START -----*/
 
-//	Add your own data members
+//------------------------------------------------------------------------------
+//  [Private] Class variables
+//------------------------------------------------------------------------------
+    //Configuration shared pointer
+    Configuration::SP m_configuration_sp;
+
+    //Thread shared pointer
+    EventThread::SP m_eventThread_sp;
+
+    //Min milli second of sleep time allowed
+    static const unsigned long MIN_SLEEP_TIME = 100;
+
+    //Max milli second of sleep time allowed
+    static const unsigned long MAX_SLEEP_TIME = 10000;
+
+    //Max milli second of wait time allowed
+    static const unsigned long MAX_WAIT_TIME = 10000;
+
+    //Max number of worker thread allowed
+    static const unsigned int MAX_WORKER_NUMBER = 100;
 
 /*----- PROTECTED REGION END -----*/	//	PreProcessor::Data Members
 
@@ -174,7 +196,12 @@ public:
 
 /*----- PROTECTED REGION ID(PreProcessor::Additional Method prototypes) ENABLED START -----*/
 
-//	Additional Method prototypes
+private:
+//------------------------------------------------------------------------------
+//  [Private] Utilities methods
+//------------------------------------------------------------------------------
+    uint32_t create_inotify_mask(const std::vector<std::string>&)
+        throw (std::invalid_argument);
 
 /*----- PROTECTED REGION END -----*/	//	PreProcessor::Additional Method prototypes
 };
-- 
GitLab