414 lines
14 KiB
C++
414 lines
14 KiB
C++
//----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) Intel Corporation, 2007 - 2008.
|
|
//
|
|
// File: Options.h
|
|
//
|
|
// Contents: Parses a static and dynamic configuration file.
|
|
// Provides access to its elements, with the actual type
|
|
// of the element obtained from the configuration file.
|
|
//
|
|
// Notes:
|
|
//----------------------------------------------------------------------------
|
|
#ifndef OPTIONS_H
|
|
#define OPTIONS_H
|
|
|
|
//------------------
|
|
// Includes
|
|
//------------------
|
|
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
|
# pragma once
|
|
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
|
|
|
#include <ace/SString.h>
|
|
#include <ace/Synch.h>
|
|
#include <ace/INET_Addr.h>
|
|
#include <ace/Guard_T.h>
|
|
|
|
#include <vector>
|
|
|
|
#include "ConfigFormat.h"
|
|
#include "ConfigElement.h"
|
|
|
|
//------------------
|
|
// Classes
|
|
//------------------
|
|
|
|
/*************************************************************
|
|
*
|
|
* Singleton class that consolidates all Options for the MPS.
|
|
* Parses a static and dynamic configuration file.
|
|
* Provides access to its elements, with the actual type
|
|
* of the element obtained from the configuration file.
|
|
*
|
|
*************************************************************/
|
|
class Options
|
|
{
|
|
public:
|
|
|
|
//------------------
|
|
// Public Functions
|
|
//------------------
|
|
|
|
/*
|
|
* Creates the Options Singleton.
|
|
* Requires the filenames to parse, and the type of formats that are
|
|
* allowed and needed.
|
|
* staticFileName - Pointer to the name of the static file to parse.
|
|
* dynamicFileName - Pointer to the name of the dynamic file to parse.
|
|
* format_static_mandatory - Pointer to the static mandatory format.
|
|
* format_static_optional - Pointer to the static optional format.
|
|
* format_dynamic_mandatory - Pointer to the dynamic mandatory format.
|
|
* format_dynamic_optional - Pointer to the dynamic optional format.
|
|
* Returns STATUS_FAILURE on failure.
|
|
* Returns STATUS_SUCCESS on success.
|
|
*/
|
|
static STATUS createInstance(const ACE_TCHAR * staticFileName,
|
|
const ACE_TCHAR * dynamicFileName,
|
|
const Format * format_static_mandatory,
|
|
const Format * format_static_optional,
|
|
const Format * format_dynamic_mandatory,
|
|
const Format * format_dynamic_optional);
|
|
/*
|
|
* Return Singleton of Options.
|
|
* Must be called only after createInstance was called.
|
|
* On error throws MPSConfigurationException.
|
|
*/
|
|
static Options * instance (void);
|
|
|
|
/*
|
|
* Default destructor.
|
|
* If error occurs at any point that can not be recovered than
|
|
* destruction is stopped and not all elements are deleted
|
|
*/
|
|
~Options (void);
|
|
|
|
/*
|
|
* Reads the static files and parses its elements.
|
|
* After successful usage, the static elements may be received.
|
|
* Returns STATUS_FAILURE on failure.
|
|
* Returns STATUS_SUCCESS on success.
|
|
*/
|
|
STATUS read_static_file();
|
|
|
|
/*
|
|
* Reads the dynamic files and parses its elements.
|
|
* After successful usage, the dynamic elements may be received.
|
|
* Returns -1 on failure.
|
|
* Returns 0 if none of the files were changed, and therefore not read.
|
|
* Returns 1 on read of only the dynamic config file.
|
|
* Returns 2 on read of the dynamic config file and at least one of the external files.
|
|
* Returns 3 on read of at least one of the external files. (no read of the dynamic config file).
|
|
*/
|
|
int read_dynamic_file(void);
|
|
|
|
|
|
// The following functions are implemented in the header file:
|
|
|
|
/*
|
|
* Indicates if the class was init successfully.
|
|
* Returns true if it was init successfully.
|
|
* Returns false otherwise.
|
|
*/
|
|
bool isInit() { return _init; }
|
|
|
|
/*
|
|
* Returns a const pointer to the value of the element in the given section and element name.
|
|
* section - An ACE_TCHAR pointer to the section name from which to retrieve the value.
|
|
* element - An ACE_TCHAR pointer to the element name (in the above section)
|
|
* from which to retrieve the value.
|
|
* Example for a regular call:
|
|
* ACE_TString ip = getValue<ACE_TString>("Network", "AMTListenIP");
|
|
*
|
|
* If an element was added to the Files section, than the data structure which holds
|
|
* the data contained in the referenced file has the same section and element name
|
|
* as was stated in the Files section.
|
|
* Example:
|
|
* if in config file:
|
|
* [Files]
|
|
* MCSubscribersList = MCSubscribersList.config
|
|
* than to obtain the data:
|
|
* MCList mcList = getValue<MCList>("MCSubscribersList", "MCSubscribersList");
|
|
*
|
|
* Uses a mutex so no return of values will be done while ctor the Options
|
|
*/
|
|
template <class T>
|
|
const T * getValue(const ACE_TCHAR * section, const ACE_TCHAR * element) {
|
|
T * ret = NULL;
|
|
Element<T> * elem;
|
|
ACE_GUARD_REACTION(ACE_Recursive_Thread_Mutex,
|
|
locker1,
|
|
_mutex,
|
|
return NULL);
|
|
|
|
BaseElement * base = NULL;
|
|
if (_element_hash.getValue(ACE_TString(section), ACE_TString(element), &base) != STATUS_SUCCESS)
|
|
{
|
|
ACE_DEBUG((MY_ERROR
|
|
ACE_TEXT("Element %s is not found.\n"),
|
|
element));
|
|
return NULL;
|
|
}
|
|
elem = dynamic_cast< Element<T> * >(base);
|
|
if (elem != NULL)
|
|
{
|
|
ret = elem->getElement();
|
|
}
|
|
else
|
|
{
|
|
ACE_DEBUG((MY_ERROR
|
|
ACE_TEXT("Element %s is NULL.\n"),
|
|
element));
|
|
return NULL;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Returns a pointer to the value of the element in the given section and element name
|
|
* On error returns NULL
|
|
* Uses a mutex so no return of values will be done while ctor the Options
|
|
*/
|
|
template <class T>
|
|
T * getValueChangable(const ACE_TCHAR * section, const ACE_TCHAR * element) {
|
|
T * ret = NULL;
|
|
ACE_GUARD_REACTION(ACE_Recursive_Thread_Mutex, locker1,
|
|
_mutex, return NULL);
|
|
|
|
BaseElement * base = NULL;
|
|
if (_element_hash.getValue(ACE_TString(section), ACE_TString(element), &base) == -1)
|
|
{
|
|
return ret;
|
|
}
|
|
Element<T> * elem = dynamic_cast< Element<T> * >(base);
|
|
if (elem != NULL)
|
|
{
|
|
ret = elem->getElement();
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
private:
|
|
|
|
//------------------
|
|
// Private Typedefs
|
|
//------------------
|
|
typedef Canonical_Hash < ACE_TString, ACE_TString,
|
|
BaseElement *, ACE_TString_compare, ACE_TString_compare > ElementHash;
|
|
typedef Canonical_Hash < ACE_TString, ACE_TString,
|
|
ACE_TString, ACE_TString_compare, ACE_TString_compare > ACE_TStringHash;
|
|
|
|
//------------------
|
|
// Private functions
|
|
//------------------
|
|
|
|
/*
|
|
* Default constructor.
|
|
* Is private so it won't be called outside.
|
|
* Does nothing
|
|
*/
|
|
Options():_lastModification(), _format_static_mandatory(), _format_static_optional(),
|
|
_format_dynamic_mandatory(), _format_dynamic_optional(){}
|
|
|
|
// The following functions are implemented in the source file:
|
|
|
|
/*
|
|
* Constructor.
|
|
* Requires the filenames to parse, and the type of formats that are
|
|
* allowed and needed.
|
|
* staticFileName - Pointer to the name of the static file to parse.
|
|
* dynamicFileName - Pointer to the name of the dynamic file to parse.
|
|
* format_static_mandatory - Pointer to the static mandatory format.
|
|
* format_static_optional - Pointer to the static optional format.
|
|
* format_dynamic_mandatory - Pointer to the dynamic mandatory format.
|
|
* format_dynamic_optional - Pointer to the dynamic optional format.
|
|
*/
|
|
Options(const ACE_TCHAR * staticFileName,
|
|
const ACE_TCHAR * dynamicFileName,
|
|
const Format * format_static_mandatory,
|
|
const Format * format_static_optional,
|
|
const Format * format_dynamic_mandatory,
|
|
const Format * format_dynamic_optional);
|
|
|
|
/*
|
|
* Reads the file and parses its elements according to the formats given.
|
|
* This is the main bulk function, after which the static file is parsed.
|
|
* fileName - filename to be read
|
|
* format_mandatory - mandatory format to use
|
|
* format_optional - optional format to use
|
|
* Returns STATUS_FAILURE on failure.
|
|
* Returns STATUS_SUCCESS on success.
|
|
*/
|
|
STATUS read_file(const ACE_TCHAR * fileName, const Format * format_mandatory, const Format * format_optional);
|
|
|
|
/*
|
|
* Builds the element hash according to previously entered parsing data to the
|
|
* string hash.
|
|
* Builds it according to the given formats -
|
|
* If an element parsed is missing from the mandatory and optional format than an error is ensued.
|
|
* Returns STATUS_FAILURE on failure.
|
|
* Returns STATUS_SUCCESS on success.
|
|
*/
|
|
STATUS build_element_hash(const Format * mandatory_format, const Format * optional_format);
|
|
|
|
/*
|
|
* Adds an element to the element hash, putting it in the correct section, and element in the section,
|
|
* and providing it with the correct type (using elemType). The element value is obtained from
|
|
* elementValue.
|
|
* sectionName - section to put the element in
|
|
* elementName - element name in the section to put the element in
|
|
* elemType - the type of the element according which the needed type for the element is decided.
|
|
* elementValue- the value of the element.
|
|
* Returns STATUS_FAILURE on failure.
|
|
* Returns STATUS_SUCCESS on success.
|
|
*/
|
|
STATUS addToElementHash(const ACE_TString §ionName,
|
|
const ACE_TString &elementName,
|
|
const ELEMENT_TYPES_ENUM &elemType,
|
|
ACE_TString &elementValue);
|
|
|
|
/*
|
|
* Adds a single element with the given sectionName, elementName and elemValue to the hash.
|
|
* If it already exists, than its value is changed.
|
|
* sectionName - section to put the element in
|
|
* elementName - element name in the section to put the element in
|
|
* elementValue- the value of the element.
|
|
* Returns STATUS_FAILURE on failure.
|
|
* Returns STATUS_SUCCESS on success.
|
|
*/
|
|
template <class T>
|
|
STATUS addSingleElement(const ACE_TString §ionName, const ACE_TString &elementName, T &elemValue)
|
|
{
|
|
STATUS status = STATUS_FAILURE;
|
|
|
|
if (!_element_hash.hasInner(sectionName, elementName))
|
|
{
|
|
Element<T> * element = new Element<T>(elemValue);
|
|
if (element == NULL)
|
|
{
|
|
return status;
|
|
}
|
|
_element_hash.addInner(sectionName, elementName, element);
|
|
}
|
|
// Has element, change it then with the new value.
|
|
else
|
|
{
|
|
T * oldValue = getValueChangable<T>(sectionName.c_str(), elementName.c_str());
|
|
if (oldValue == NULL)
|
|
{
|
|
return status;
|
|
}
|
|
*oldValue = elemValue;
|
|
}
|
|
status = STATUS_SUCCESS;
|
|
|
|
return status;
|
|
}
|
|
|
|
/*
|
|
* Adds an INET type element to the hash according to the given sectionName and elementName.
|
|
* isPort indicates if the given element indicates a port or an ip, by which the indication
|
|
* of the INET is recognized. It may be that an INET object is not currently possible to add, in which
|
|
* case, this is not considered as error (such as in the example that only the port is known)
|
|
* Returns STATUS_FAILURE on failure.
|
|
* Returns STATUS_SUCCESS on success.
|
|
*/
|
|
/*STATUS addINET(const ACE_TString §ionName,
|
|
const ACE_TString &elementName,
|
|
bool isPort);*/
|
|
|
|
/*
|
|
* Checks that the format given (mandatory or optional set by isMandatory), fits the inner hash.
|
|
* i.e: if the hash holding all the data has all the elements it is required off according to
|
|
* the formats (if it does not hold an element that is in the optional format, than its
|
|
* default value is added)
|
|
* This is done after the inner hash is filled.
|
|
* Returns STATUS_FAILURE on failure.
|
|
* Returns STATUS_SUCCESS on success.
|
|
*/
|
|
STATUS checkFormat(const Format * format, bool isMandatory);
|
|
|
|
/*
|
|
* Reads and parses all external files, and enters them to the element hash according
|
|
* their data.
|
|
* Returns -1 on failure.
|
|
* Otherwise, returns the amount of files that were read (files that were changed).
|
|
*/
|
|
int read_all_external_files();
|
|
|
|
/*
|
|
* Adds an element to the element hash according to an external file which was parsed to a vector.
|
|
* The vector reference is the vector which holds the parsed information.
|
|
* The section name indicates which section the new element is supposed to be in.
|
|
* The element type indicates the needed element type
|
|
* Note: A single element (in the final hash) is provided per file (usually a list or a hash)
|
|
* Returns STATUS_FAILURE on failure.
|
|
* Returns STATUS_SUCCESS on success.
|
|
*/
|
|
STATUS build_element_hash_ext_from_vector(const vector<ACE_TString> &vec,
|
|
const ACE_TString §ionName,
|
|
Element_Type_Enum * elementType);
|
|
|
|
/*
|
|
* Adds an element to the element hash according to an external file which was parsed to a canonical hash.
|
|
* The section name indicates which section the new element is supposed to be in.
|
|
* The element type indicates the needed element type
|
|
* Note: A single element is provided per file (usually a list or a hash)
|
|
* Returns STATUS_FAILURE on failure.
|
|
* Returns STATUS_SUCCESS on success.
|
|
*/
|
|
//STATUS build_element_hash_ext_from_hash(const ACE_TString §ionName, Element_Type_Enum * elementType);
|
|
|
|
/*
|
|
* Obtains a single elements' type according to the given formats. Puts a pointer to the
|
|
* element type in **elementType.
|
|
* Returns STATUS_FAILURE on failure.
|
|
* Returns STATUS_SUCCESS on success.
|
|
*/
|
|
STATUS obtainElementType(const Format * mandatory_format, const Format * optional_format,
|
|
const ACE_TString §ionName, const ACE_TString &elementName,
|
|
Element_Type_Enum ** elementType);
|
|
|
|
/*
|
|
* Deletes an element from the element hash (deleting the element itself and removing
|
|
* it from the canonical element hash).
|
|
* Returns STATUS_FAILURE on failure.
|
|
* Returns STATUS_SUCCESS on success.
|
|
*/
|
|
STATUS deleteElement(const ACE_TString §ionName, const ACE_TString &elementName);
|
|
|
|
/*
|
|
* Deletes an element from the element hash (deleting the element itself but not removing
|
|
* it from the canonical element hash).
|
|
* Returns STATUS_FAILURE on failure.
|
|
* Returns STATUS_SUCCESS on success.
|
|
*/
|
|
STATUS deleteElementContent(const ACE_TString §ionName, const ACE_TString &elementName);
|
|
|
|
//--------------
|
|
// Data Members
|
|
//--------------
|
|
|
|
// Options Singleton instance.
|
|
static Options * _instance;
|
|
static bool _init;
|
|
static ACE_Mutex _ctor_mutex;
|
|
|
|
ACE_Recursive_Thread_Mutex _mutex;
|
|
time_t _lastModification;
|
|
|
|
const Format * _format_static_mandatory;
|
|
const Format * _format_static_optional;
|
|
const Format * _format_dynamic_mandatory;
|
|
const Format * _format_dynamic_optional;
|
|
|
|
ElementHash _element_hash;
|
|
ACE_TStringHash _temp_String_Hash;
|
|
map< ACE_TString, time_t, ACE_TString_compare_no_toUpper > _extModifTimeMap;
|
|
ACE_TCHAR _static_config_file[MAXPATHLEN + 1];
|
|
ACE_TCHAR _dynamic_config_file[MAXPATHLEN + 1];
|
|
};
|
|
|
|
#endif /* OPTIONS_H */
|