version 1.1.2.1, 2013/02/04 07:38:57
|
version 1.1.2.2, 2013/06/03 22:36:06
|
|
|
|
//%LICENSE//////////////////////////////////////////////////////////////// |
|
// |
|
// Licensed to The Open Group (TOG) under one or more contributor license |
|
// agreements. Refer to the OpenPegasusNOTICE.txt file distributed with |
|
// this work for additional information regarding copyright ownership. |
|
// Each contributor licenses this file to you under the OpenPegasus Open |
|
// Source License; you may not use this file except in compliance with the |
|
// License. |
|
// |
|
// Permission is hereby granted, free of charge, to any person obtaining a |
|
// copy of this software and associated documentation files (the "Software"), |
|
// to deal in the Software without restriction, including without limitation |
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense, |
|
// and/or sell copies of the Software, and to permit persons to whom the |
|
// Software is furnished to do so, subject to the following conditions: |
|
// |
|
// The above copyright notice and this permission notice shall be included |
|
// in all copies or substantial portions of the Software. |
|
// |
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
|
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
|
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
|
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
// |
|
////////////////////////////////////////////////////////////////////////// |
|
// |
|
//%///////////////////////////////////////////////////////////////////////////// |
|
|
|
#include <Pegasus/Common/Exception.h> |
|
#include <Pegasus/Common/Tracer.h> |
|
#include <Pegasus/Common/CommonUTF.h> |
|
#include <Pegasus/Common/Constants.h> |
|
#include <Pegasus/Common/StringConversion.h> |
|
#include <Pegasus/Common/ArrayInternal.h> |
|
|
|
#if defined(PEGASUS_HAS_ICU) && defined(PEGASUS_INDFORMATTER_USE_ICU) |
|
# include <unicode/locid.h> |
|
# include <unicode/datefmt.h> |
|
# include <unicode/unistr.h> |
|
#endif |
|
|
|
#include "IndicationFormatter.h" |
|
|
|
PEGASUS_NAMESPACE_BEGIN |
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// CIMValueLocalizer |
|
// |
|
/////////////////////////////////////////////////////////////////////////////// |
|
|
|
class CIMValueLocalizer |
|
{ |
|
public: |
|
|
|
/** |
|
Constructs a CIMValueLocalizer object. The CIMValueLocalizer can be |
|
used to localize a CIMValue string based on a specified |
|
ContentLanguageList. Localization is possible only if the |
|
ContentLanguageList includes no more than one language tag. |
|
|
|
@param contentLangs A ContentLanguageList containing a LanguageTag |
|
with which to perform localization. |
|
*/ |
|
CIMValueLocalizer(const ContentLanguageList& contentLangs); |
|
~CIMValueLocalizer(); |
|
|
|
String getLocalizedValue(Boolean value) const |
|
{ |
|
return _localizeBoolean(value); |
|
} |
|
|
|
String getLocalizedValue(Uint8 value) const |
|
{ |
|
return getLocalizedValue(Uint32(value)); |
|
} |
|
|
|
String getLocalizedValue(Sint8 value) const |
|
{ |
|
return getLocalizedValue(Sint32(value)); |
|
} |
|
|
|
String getLocalizedValue(Uint16 value) const |
|
{ |
|
return getLocalizedValue(Uint32(value)); |
|
} |
|
|
|
String getLocalizedValue(Sint16 value) const |
|
{ |
|
return getLocalizedValue(Sint32(value)); |
|
} |
|
|
|
String getLocalizedValue(Uint32 value) const |
|
{ |
|
Uint32 outputLength = 0; |
|
char buffer[22]; |
|
const char* output = Uint32ToString(buffer, value, outputLength); |
|
return String(output, outputLength); |
|
} |
|
|
|
String getLocalizedValue(Sint32 value) const |
|
{ |
|
Uint32 outputLength = 0; |
|
char buffer[22]; |
|
const char* output = Sint32ToString(buffer, value, outputLength); |
|
return String(output, outputLength); |
|
} |
|
|
|
String getLocalizedValue(Uint64 value) const |
|
{ |
|
Uint32 outputLength = 0; |
|
char buffer[22]; |
|
const char* output = Uint64ToString(buffer, value, outputLength); |
|
return String(output, outputLength); |
|
} |
|
|
|
String getLocalizedValue(Sint64 value) const |
|
{ |
|
Uint32 outputLength = 0; |
|
char buffer[22]; |
|
const char* output = Sint64ToString(buffer, value, outputLength); |
|
return String(output, outputLength); |
|
} |
|
|
|
String getLocalizedValue(Real32 value) const |
|
{ |
|
char buffer[32]; |
|
sprintf(buffer, "%.7e", value); |
|
return String(buffer); |
|
} |
|
|
|
String getLocalizedValue(Real64 value) const |
|
{ |
|
char buffer[32]; |
|
sprintf(buffer, "%.16e", value); |
|
return String(buffer); |
|
} |
|
|
|
String getLocalizedValue(Char16 value) const |
|
{ |
|
return String(&value, 1); |
|
} |
|
|
|
String getLocalizedValue(const String& value) const |
|
{ |
|
return value; |
|
} |
|
|
|
String getLocalizedValue(const CIMDateTime& value) const |
|
{ |
|
return _localizeDateTime(value); |
|
} |
|
|
|
String getLocalizedValue(const CIMObjectPath& value) const |
|
{ |
|
return value.toString(); |
|
} |
|
|
|
String getLocalizedValue(const CIMObject& value) const |
|
{ |
|
return value.toString(); |
|
} |
|
|
|
String getLocalizedValue(const CIMInstance& value) const |
|
{ |
|
return CIMObject(value).toString(); |
|
} |
|
|
|
private: |
|
|
|
CIMValueLocalizer(const CIMValueLocalizer&); |
|
CIMValueLocalizer& operator=(const CIMValueLocalizer&); |
|
|
|
String _localizeDateTime(const CIMDateTime& dateTimeValue) const; |
|
String _localizeBoolean(Boolean booleanValue) const; |
|
|
|
Boolean canLocalize; |
|
#if defined(PEGASUS_HAS_ICU) && defined(PEGASUS_INDFORMATTER_USE_ICU) |
|
Locale locale; |
|
#endif |
|
}; |
|
|
|
CIMValueLocalizer::CIMValueLocalizer(const ContentLanguageList& contentLangs) |
|
{ |
|
canLocalize = false; |
|
|
|
#if defined(PEGASUS_HAS_ICU) && defined(PEGASUS_INDFORMATTER_USE_ICU) |
|
if (InitializeICU::initICUSuccessful()) |
|
{ |
|
if (contentLangs.size() == 0) |
|
{ |
|
// No language specified; use the default. |
|
locale = Locale::getDefault(); |
|
canLocalize = true; |
|
} |
|
else if (contentLangs.size() == 1) |
|
{ |
|
LanguageTag languageTag = contentLangs.getLanguageTag(0); |
|
locale = Locale( |
|
(const char*) languageTag.getLanguage.getCString(), |
|
(const char*) languageTag.getCountry.getCString(), |
|
(const char*) languageTag.getVariant.getCString()); |
|
canLocalize = !locale.isBogus(); |
|
} |
|
else |
|
{ |
|
// ContentLanguageList has multiple language tags; do not localize. |
|
} |
|
} |
|
#endif |
|
} |
|
|
|
CIMValueLocalizer::~CIMValueLocalizer() |
|
{ |
|
} |
|
|
|
String CIMValueLocalizer::_localizeDateTime( |
|
const CIMDateTime& dateTimeValue) const |
|
{ |
|
#if defined(PEGASUS_HAS_ICU) && defined(PEGASUS_INDFORMATTER_USE_ICU) |
|
PEG_METHOD_ENTER(TRC_IND_FORMATTER, "CIMValueLocalizer::_localizeDateTime"); |
|
|
|
if (canLocalize) |
|
{ |
|
// The CIMDateTime epoch begins 1/1/0000 (12 am Jan 1, 1BCE). |
|
// The ICU epoch begins 1/1/1970 (1 January 1970 0:00 UTC). |
|
|
|
const CIMDateTime EPOCH1970 = CIMDateTime("19700101000000.000000+000"); |
|
UDate icuDateTimeMillisecs = (Sint64) |
|
(dateTimeValue.toMicroSeconds() - EPOCH1970.toMicroSeconds())/1000; |
|
|
|
// Use a medium length DATE/TIME format (e.g., Jan 12, 1982 3:30:32pm) |
|
AutoPtr<DateFormat> fmt; |
|
|
|
try |
|
{ |
|
if (locale == 0) |
|
{ |
|
fmt.reset(DateFormat::createDateTimeInstance( |
|
DateFormat::MEDIUM, DateFormat::MEDIUM)); |
|
} |
|
else |
|
{ |
|
fmt.reset(DateFormat::createDateTimeInstance( |
|
DateFormat::MEDIUM, DateFormat::MEDIUM, locale)); |
|
} |
|
} |
|
catch (...) |
|
{ |
|
PEG_TRACE_CSTRING(TRC_IND_FORMATTER, Tracer::LEVEL2, |
|
"Caught exception from DateFormat::createDateTimeInstance"); |
|
|
|
PEG_METHOD_EXIT(); |
|
return dateTimeValue.toString(); |
|
} |
|
|
|
if (fmt.get() == 0) |
|
{ |
|
PEG_TRACE_CSTRING(TRC_IND_FORMATTER, Tracer::LEVEL2, |
|
"Memory allocation error creating DateTime instance."); |
|
PEG_METHOD_EXIT(); |
|
return dateTimeValue.toString(); |
|
} |
|
|
|
// Format the Date and Time |
|
UErrorCode status = U_ZERO_ERROR; |
|
UnicodeString dateTimeUniStr; |
|
fmt->format(icuDateTimeMillisecs, dateTimeUniStr, status); |
|
|
|
if (U_FAILURE(status)) |
|
{ |
|
PEG_METHOD_EXIT(); |
|
return dateTimeValue.toString(); |
|
} |
|
|
|
// convert UnicodeString to char * |
|
char dateTimeBuffer[256]; |
|
String datetimeStr; |
|
|
|
// Copy the contents of the string into dateTimeBuffer |
|
Uint32 strLen = dateTimeUniStr.extract( |
|
0, sizeof(dateTimeBuffer), dateTimeBuffer); |
|
|
|
if (strLen >= sizeof(dateTimeBuffer)) |
|
{ |
|
// There is not enough space in dateTimeBuffer |
|
char* extractedStr = new char[strLen + 1]; |
|
strLen = dateTimeUniStr.extract(0, strLen + 1, extractedStr); |
|
datetimeStr = extractedStr; |
|
delete [] extractedStr; |
|
} |
|
else |
|
{ |
|
datetimeStr = dateTimeBuffer; |
|
} |
|
|
|
PEG_METHOD_EXIT(); |
|
return datetimeStr; |
|
} |
|
|
|
PEG_METHOD_EXIT(); |
|
#endif |
|
|
|
return dateTimeValue.toString(); |
|
} |
|
|
|
String CIMValueLocalizer::_localizeBoolean(Boolean booleanValue) const |
|
{ |
|
PEG_METHOD_ENTER(TRC_IND_FORMATTER, "CIMValueLocalizer::_localizeBoolean"); |
|
|
|
if (canLocalize) |
|
{ |
|
if (booleanValue) |
|
{ |
|
MessageLoaderParms parms( |
|
"Common.IndicationFormatter._MSG_BOOLEAN_TRUE", |
|
"true"); |
|
|
|
PEG_METHOD_EXIT(); |
|
return MessageLoader::getMessage(parms); |
|
} |
|
else |
|
{ |
|
MessageLoaderParms parms( |
|
"Common.IndicationFormatter._MSG_BOOLEAN_FALSE", |
|
"false"); |
|
|
|
PEG_METHOD_EXIT(); |
|
return MessageLoader::getMessage(parms); |
|
} |
|
} |
|
|
|
PEG_METHOD_EXIT(); |
|
return booleanValue ? "true" : "false"; |
|
} |
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// IndicationFormatter |
|
// |
|
/////////////////////////////////////////////////////////////////////////////// |
|
|
|
template<class T> |
|
void appendArrayValue( |
|
String& buffer, |
|
const CIMValue& value, |
|
Uint32 arrayIndex, |
|
const CIMValueLocalizer& cimValueLocalizer) |
|
{ |
|
PEGASUS_ASSERT(value.isArray()); |
|
|
|
Array<T> arrayValue; |
|
value.get(arrayValue); |
|
|
|
// Empty brackets (e.g. []), gets all values of the array |
|
if (arrayIndex == PEG_NOT_FOUND) |
|
{ |
|
buffer.append("["); |
|
|
|
for (Uint32 i = 0, arraySize = arrayValue.size(); i < arraySize; i++) |
|
{ |
|
buffer.append(cimValueLocalizer.getLocalizedValue(arrayValue[i])); |
|
if (i < arraySize - 1) |
|
{ |
|
buffer.append(","); |
|
} |
|
} |
|
|
|
buffer.append("]"); |
|
} |
|
else |
|
{ |
|
buffer.append( |
|
cimValueLocalizer.getLocalizedValue(arrayValue[arrayIndex])); |
|
} |
|
} |
|
|
|
void IndicationFormatter::validateTextFormat( |
|
const String& textStr, |
|
const CIMClass& indicationClass, |
|
const Array<String>& textFormatParams) |
|
{ |
|
PEG_METHOD_ENTER(TRC_IND_FORMATTER, |
|
"IndicationFormatter::validateTextFormat"); |
|
|
|
String textFormatStr = textStr; |
|
Uint32 leftBrace = textFormatStr.find("{"); |
|
Uint32 rightBrace; |
|
|
|
do |
|
{ |
|
String textFormatSubStr; |
|
|
|
if (leftBrace != PEG_NOT_FOUND) |
|
{ |
|
// Do not expect a right brace before the left |
|
// brace. e.g An invalid text format string could be: |
|
// "Indication occurred at 2, datetime} with |
|
// identify ID {3, string}" |
|
|
|
textFormatSubStr = textFormatStr.subString(0, leftBrace); |
|
|
|
Uint32 rightBrace2 = textFormatSubStr.find("}"); |
|
if (rightBrace2 != PEG_NOT_FOUND) |
|
{ |
|
textFormatSubStr = textFormatStr.subString( |
|
0, (rightBrace2 + 1)); |
|
MessageLoaderParms parms( |
|
"Common.IndicationFormatter." |
|
"_MSG_INVALID_SYNTAX_OF_FOR_PROPERTY", |
|
"Invalid syntax at $0 in property $1", |
|
textFormatSubStr, |
|
_PROPERTY_TEXTFORMAT.getString()); |
|
|
|
PEG_METHOD_EXIT(); |
|
throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_INVALID_PARAMETER, parms); |
|
} |
|
|
|
// expect right brace |
|
textFormatStr = textFormatStr.subString(leftBrace+1); |
|
rightBrace = textFormatStr.find("}"); |
|
|
|
// Do not expect a left brace between left and right |
|
// braces. e.g A text string: "Indication occurred |
|
// at {2, datetime with identify ID {3, string}" is |
|
// an invalid format. |
|
|
|
if (rightBrace != PEG_NOT_FOUND) |
|
{ |
|
textFormatSubStr.clear(); |
|
textFormatSubStr = textFormatStr.subString(0, rightBrace); |
|
|
|
Uint32 leftBrace2 = textFormatSubStr.find("{"); |
|
if (leftBrace2 != PEG_NOT_FOUND) |
|
{ |
|
textFormatSubStr = textFormatStr.subString( |
|
0, (leftBrace2 + 1)); |
|
MessageLoaderParms parms( |
|
"Common.IndicationFormatter." |
|
"_MSG_INVALID_SYNTAX_OF_FOR_PROPERTY", |
|
"Invalid syntax at $0 in property $1", |
|
textFormatSubStr, |
|
_PROPERTY_TEXTFORMAT.getString()); |
|
|
|
PEG_METHOD_EXIT(); |
|
throw PEGASUS_CIM_EXCEPTION_L( |
|
CIM_ERR_INVALID_PARAMETER, parms); |
|
} |
|
|
|
String propertyParam; |
|
String propertyTypeStr; |
|
String propertyIndexStr; |
|
Uint32 comma = textFormatSubStr.find(","); |
|
|
|
if (comma == PEG_NOT_FOUND) |
|
{ |
|
// A dynamic content can have format either |
|
// {index} or {index[x]} |
|
propertyParam = textFormatSubStr; |
|
propertyTypeStr = String::EMPTY; |
|
} |
|
else |
|
{ |
|
// A dynamic content can have format either |
|
// {index, type} or {index[x], type} |
|
propertyParam = textFormatSubStr.subString(0, comma); |
|
propertyTypeStr = textFormatSubStr.subString(comma +1); |
|
} |
|
|
|
Uint32 leftBracket = propertyParam.find("["); |
|
Uint32 rightBracket = propertyParam.find("]"); |
|
Boolean isArray = false; |
|
|
|
// A dynamic content has syntax either {index} or {index, type} |
|
if (leftBracket == PEG_NOT_FOUND) |
|
{ |
|
// there is no left bracket, do not expect a right bracket |
|
if (rightBracket != PEG_NOT_FOUND) |
|
{ |
|
textFormatSubStr = textFormatStr.subString( |
|
0, (rightBracket + 1)); |
|
MessageLoaderParms parms( |
|
"Common.IndicationFormatter." |
|
"_MSG_INVALID_SYNTAX_OF_FOR_PROPERTY", |
|
"Invalid syntax at $0 in property $1", |
|
textFormatSubStr, |
|
_PROPERTY_TEXTFORMAT.getString()); |
|
|
|
PEG_METHOD_EXIT(); |
|
throw PEGASUS_CIM_EXCEPTION_L( |
|
CIM_ERR_INVALID_PARAMETER, parms); |
|
} |
|
|
|
propertyIndexStr = propertyParam; |
|
isArray = false; |
|
} |
|
// A dynamic content has syntax either |
|
// {index[]} or {index[], type} |
|
else |
|
{ |
|
// there is a left bracket, expect a right bracket |
|
if (rightBracket == PEG_NOT_FOUND) |
|
{ |
|
MessageLoaderParms parms( |
|
"Common.IndicationFormatter." |
|
"_MSG_INVALID_SYNTAX_OF_FOR_PROPERTY", |
|
"Invalid syntax at $0 in property $1", |
|
textFormatSubStr, |
|
_PROPERTY_TEXTFORMAT.getString()); |
|
|
|
PEG_METHOD_EXIT(); |
|
throw PEGASUS_CIM_EXCEPTION_L( |
|
CIM_ERR_INVALID_PARAMETER, parms); |
|
} |
|
|
|
propertyIndexStr = propertyParam.subString(0, leftBracket); |
|
isArray = true; |
|
} |
|
|
|
Uint32 propertyIndex = _parseIndex(propertyIndexStr); |
|
|
|
// check the property index |
|
if (propertyIndex >= textFormatParams.size()) |
|
{ |
|
// property index is out of bounds |
|
MessageLoaderParms parms( |
|
"Common.IndicationFormatter." |
|
"_MSG_INDEX_IS_OUT_OF_BOUNDS", |
|
"The value of index $0 in property $1 is out of bounds", |
|
propertyIndex, |
|
_PROPERTY_TEXTFORMATPARAMETERS.getString()); |
|
|
|
PEG_METHOD_EXIT(); |
|
throw PEGASUS_CIM_EXCEPTION_L( |
|
CIM_ERR_INVALID_PARAMETER, parms); |
|
} |
|
|
|
if (propertyTypeStr != String::EMPTY) |
|
{ |
|
_validatePropertyType(indicationClass, |
|
textFormatParams[propertyIndex], |
|
propertyTypeStr, isArray); |
|
} |
|
|
|
textFormatStr = textFormatStr.subString(rightBrace+1); |
|
} |
|
else // no right brace |
|
{ |
|
MessageLoaderParms parms( |
|
"Common.IndicationFormatter." |
|
"_MSG_INVALID_SYNTAX_OF_FOR_PROPERTY", |
|
"Invalid syntax at $0 in property $1", |
|
textFormatSubStr, |
|
_PROPERTY_TEXTFORMAT.getString()); |
|
|
|
PEG_METHOD_EXIT(); |
|
throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_INVALID_PARAMETER, parms); |
|
} |
|
} |
|
else // no left brace |
|
{ |
|
// does not expect right brace |
|
rightBrace = textFormatStr.find("}"); |
|
|
|
if (rightBrace != PEG_NOT_FOUND) |
|
{ |
|
textFormatSubStr = textFormatStr.subString(0, rightBrace + 1); |
|
MessageLoaderParms parms( |
|
"Common.IndicationFormatter." |
|
"_MSG_INVALID_SYNTAX_OF_FOR_PROPERTY", |
|
"Invalid syntax at $0 in property $1", |
|
textFormatSubStr, |
|
_PROPERTY_TEXTFORMAT.getString()); |
|
|
|
PEG_METHOD_EXIT(); |
|
throw PEGASUS_CIM_EXCEPTION_L( |
|
CIM_ERR_INVALID_PARAMETER, parms); |
|
} |
|
|
|
break; |
|
} |
|
|
|
leftBrace = textFormatStr.find("{"); |
|
} while (textFormatStr.size() > 0); |
|
|
|
PEG_METHOD_EXIT(); |
|
} |
|
|
|
inline Boolean _isSpace(Char16 c) |
|
{ |
|
return (c == ' ') || (c == '\t') || (c == '\r') || (c == '\n'); |
|
} |
|
|
|
void IndicationFormatter::_trim(String& s) |
|
{ |
|
while (s.size() && _isSpace(s[s.size()-1])) |
|
{ |
|
s.remove(s.size() - 1); |
|
} |
|
|
|
while (s.size() && _isSpace(s[0])) |
|
{ |
|
s.remove(0, 1); |
|
} |
|
} |
|
|
|
void IndicationFormatter::_validatePropertyType( |
|
const CIMClass& indicationClass, |
|
const String& propertyParam, |
|
const String& typeStr, |
|
const Boolean& isArray) |
|
{ |
|
PEG_METHOD_ENTER(TRC_IND_FORMATTER, |
|
"IndicationFormatter::_validatePropertyType"); |
|
|
|
String propertyTypeStr = typeStr; |
|
|
|
Array<String> validPropertyTypes; |
|
validPropertyTypes.append("boolean"); |
|
validPropertyTypes.append("uint8"); |
|
validPropertyTypes.append("sint8"); |
|
validPropertyTypes.append("uint16"); |
|
validPropertyTypes.append("sint16"); |
|
validPropertyTypes.append("uint32"); |
|
validPropertyTypes.append("sint32"); |
|
validPropertyTypes.append("uint64"); |
|
validPropertyTypes.append("sint64"); |
|
validPropertyTypes.append("real32"); |
|
validPropertyTypes.append("real64"); |
|
validPropertyTypes.append("char16"); |
|
validPropertyTypes.append("string"); |
|
validPropertyTypes.append("datetime"); |
|
validPropertyTypes.append("reference"); |
|
|
|
propertyTypeStr.toLower(); |
|
_trim(propertyTypeStr); |
|
|
|
// |
|
// Checks if the provided property type is a valid type |
|
// |
|
if (!(Contains(validPropertyTypes, propertyTypeStr))) |
|
{ |
|
// the provided property type is not valid type |
|
MessageLoaderParms parms( |
|
"Common.IndicationFormatter." |
|
"_MSG_INVALID_TYPE_OF_FOR_PROPERTY", |
|
"Invalid property type of $0 in property $1", |
|
propertyTypeStr, |
|
_PROPERTY_TEXTFORMAT.getString()); |
|
|
|
PEG_METHOD_EXIT(); |
|
throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_INVALID_PARAMETER, parms); |
|
} |
|
|
|
for (Uint32 i = 0; i < indicationClass.getPropertyCount(); i++) |
|
{ |
|
CIMName propertyName = indicationClass.getProperty(i).getName(); |
|
|
|
if (String::equalNoCase(propertyParam, propertyName.getString())) |
|
{ |
|
// get the property type; |
|
CIMType propertyType = indicationClass.getProperty(i).getType(); |
|
|
|
// Check if the property is an array type |
|
if ((isArray && !(indicationClass.getProperty(i).isArray())) || |
|
(!isArray && indicationClass.getProperty(i).isArray())) |
|
{ |
|
MessageLoaderParms parms( |
|
"Common.IndicationFormatter." |
|
"_MSG_PROPERTY_IS_NOT_AN_ARRAY_TYPE", |
|
"The property $0 is not an array type", |
|
propertyName.getString()); |
|
|
|
PEG_METHOD_EXIT(); |
|
throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_INVALID_PARAMETER, parms); |
|
} |
|
|
|
// property type matches |
|
if (String::equalNoCase( |
|
propertyTypeStr, cimTypeToString(propertyType))) |
|
{ |
|
break; |
|
} |
|
|
|
MessageLoaderParms parms( |
|
"Common.IndicationFormatter." |
|
"_MSG_MISS_MATCHED_TYPE_OF_FOR_PROPERTY", |
|
"The provided property type of $0 in $1 does not match " |
|
"the property type $2", |
|
propertyTypeStr, |
|
cimTypeToString(propertyType), |
|
_PROPERTY_TEXTFORMAT.getString()); |
|
|
|
PEG_METHOD_EXIT(); |
|
throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_INVALID_PARAMETER, parms); |
|
} |
|
} |
|
|
|
PEG_METHOD_EXIT(); |
|
} |
|
|
|
void IndicationFormatter::validateTextFormatParameters( |
|
const CIMPropertyList& propertyList, |
|
const CIMClass& indicationClass, |
|
const Array<String>& textFormatParams) |
|
{ |
|
PEG_METHOD_ENTER(TRC_IND_FORMATTER, |
|
"IndicationFormatter::validateTextFormatParameters"); |
|
|
|
Array<String> indicationClassProperties; |
|
|
|
if (propertyList.isNull()) |
|
{ |
|
// All the properties are selected |
|
for (Uint32 i = 0; i < indicationClass.getPropertyCount(); i++) |
|
{ |
|
indicationClassProperties.append( |
|
indicationClass.getProperty(i).getName().getString()); |
|
} |
|
} |
|
else |
|
{ |
|
// Partial properties are selected |
|
Array<CIMName> propertyNames = propertyList.getPropertyNameArray(); |
|
|
|
for (Uint32 j = 0; j < propertyNames.size(); j++) |
|
{ |
|
indicationClassProperties.append(propertyNames[j].getString()); |
|
} |
|
} |
|
|
|
// check if the textFormatParams is contained in the |
|
// indicationClassProperties |
|
for (Uint32 k = 0; k < textFormatParams.size(); k++) |
|
{ |
|
if (!Contains(indicationClassProperties, textFormatParams[k])) |
|
{ |
|
// The property name in TextFormatParameters is not |
|
// included in the select clause of the associated filter query |
|
MessageLoaderParms parms( |
|
"Common.IndicationFormatter." |
|
"_MSG_MISS_MATCHED_PROPERTY_NAME", |
|
"The property name $0 in $1 does not match the properties " |
|
"in the select clause", |
|
textFormatParams[k], |
|
_PROPERTY_TEXTFORMATPARAMETERS.getString()); |
|
|
|
PEG_METHOD_EXIT(); |
|
throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_INVALID_PARAMETER, parms); |
|
} |
|
} |
|
|
|
PEG_METHOD_EXIT(); |
|
} |
|
|
|
Uint32 IndicationFormatter::_parseIndex(const String& indexStr) |
|
{ |
|
Uint32 index = PEG_NOT_FOUND; |
|
char dummy[2]; |
|
int numConversions = |
|
sscanf(indexStr.getCString(), "%u%1s", &index, dummy); |
|
|
|
if ((numConversions != 1) || (index == PEG_NOT_FOUND)) |
|
{ |
|
MessageLoaderParms parms( |
|
"IndicationFormatter.IndicationFormatter._MSG_INVALID_INDEX", |
|
"Invalid index string '$0'", |
|
indexStr); |
|
|
|
throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_INVALID_PARAMETER, parms); |
|
} |
|
|
|
return index; |
|
} |
|
|
|
String IndicationFormatter::getFormattedIndText( |
|
const CIMInstance& subscription, |
|
const CIMInstance& indication, |
|
const ContentLanguageList& contentLangs) |
|
{ |
|
PEG_METHOD_ENTER (TRC_IND_FORMATTER, |
|
"IndicationFormatter::getFormattedIndText"); |
|
|
|
String indicationText; |
|
String textFormat; |
|
CIMValue textFormatValue; |
|
CIMValue textFormatParamsValue; |
|
|
|
Array<String> textFormatParams; |
|
|
|
// get TextFormat from subscription |
|
Uint32 textFormatPos = subscription.findProperty(_PROPERTY_TEXTFORMAT); |
|
|
|
// if the property TextFormat is not found, |
|
// indication is constructed with default format |
|
if (textFormatPos == PEG_NOT_FOUND) |
|
{ |
|
indicationText = _formatDefaultIndicationText(indication, contentLangs); |
|
} |
|
else |
|
{ |
|
textFormatValue = subscription.getProperty(textFormatPos).getValue(); |
|
|
|
// if the value of textFormat is NULL, |
|
// indication is constructed with default format |
|
if (textFormatValue.isNull()) |
|
{ |
|
indicationText = |
|
_formatDefaultIndicationText(indication, contentLangs); |
|
} |
|
else |
|
{ |
|
// get TextFormatParameters from subscription |
|
Uint32 textFormatParamsPos = subscription.findProperty( |
|
_PROPERTY_TEXTFORMATPARAMETERS); |
|
|
|
if (textFormatParamsPos != PEG_NOT_FOUND) |
|
{ |
|
textFormatParamsValue = subscription.getProperty( |
|
textFormatParamsPos).getValue(); |
|
} |
|
|
|
// constructs indication with specified format |
|
if ((textFormatValue.getType() == CIMTYPE_STRING) && |
|
!(textFormatValue.isArray())) |
|
{ |
|
textFormatValue.get(textFormat); |
|
if (!textFormatParamsValue.isNull()) |
|
{ |
|
if ((textFormatParamsValue.getType() == CIMTYPE_STRING) && |
|
(textFormatParamsValue.isArray())) |
|
{ |
|
textFormatParamsValue.get(textFormatParams); |
|
} |
|
} |
|
|
|
indicationText = _formatIndicationText( |
|
textFormat, |
|
textFormatParams, |
|
indication, |
|
contentLangs); |
|
} |
|
else |
|
{ |
|
indicationText = |
|
_formatDefaultIndicationText(indication, contentLangs); |
|
} |
|
} |
|
} |
|
|
|
PEG_METHOD_EXIT(); |
|
return indicationText; |
|
} |
|
|
|
String IndicationFormatter::_formatDefaultIndicationText( |
|
const CIMInstance& indication, |
|
const ContentLanguageList& contentLangs) |
|
{ |
|
PEG_METHOD_ENTER (TRC_IND_FORMATTER, |
|
"IndicationFormatter::_formatDefaultIndicationText"); |
|
|
|
String indicationStr = "Indication (default format):"; |
|
|
|
CIMValueLocalizer cimValueLocalizer(contentLangs); |
|
|
|
for (Uint32 i = 0, n = indication.getPropertyCount(); i < n; i++) |
|
{ |
|
if (i > 0) |
|
{ |
|
indicationStr.append(", "); |
|
} |
|
|
|
CIMConstProperty property = indication.getProperty(i); |
|
CIMValue propertyValue = property.getValue(); |
|
|
|
indicationStr.append(property.getName().getString()); |
|
indicationStr.append(" = "); |
|
|
|
if (!propertyValue.isNull()) |
|
{ |
|
if (propertyValue.isArray()) |
|
{ |
|
indicationStr.append(_getArrayValues( |
|
propertyValue, PEG_NOT_FOUND, contentLangs)); |
|
} |
|
else // value is not an array |
|
{ |
|
CIMType type = propertyValue.getType(); |
|
|
|
if (type == CIMTYPE_DATETIME) |
|
{ |
|
CIMDateTime dateTimeValue; |
|
propertyValue.get(dateTimeValue); |
|
indicationStr.append( |
|
cimValueLocalizer.getLocalizedValue(dateTimeValue)); |
|
} |
|
else if (type == CIMTYPE_BOOLEAN) |
|
{ |
|
Boolean booleanValue; |
|
propertyValue.get(booleanValue); |
|
indicationStr.append( |
|
cimValueLocalizer.getLocalizedValue(booleanValue)); |
|
} |
|
else |
|
{ |
|
indicationStr.append(propertyValue.toString()); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
indicationStr.append("NULL"); |
|
} |
|
} |
|
|
|
PEG_METHOD_EXIT(); |
|
return indicationStr; |
|
} |
|
|
|
String IndicationFormatter::_formatIndicationText( |
|
const String& textFormat, |
|
const Array<String>& textFormatParams, |
|
const CIMInstance& indication, |
|
const ContentLanguageList& contentLangs) |
|
{ |
|
PEG_METHOD_ENTER(TRC_IND_FORMATTER, |
|
"IndicationFormatter::_formatIndicationText"); |
|
|
|
String indicationText; |
|
String indicationFormat = textFormat; |
|
|
|
// Parsing the specified indication text format. |
|
// As an example, a format string for a UPS AlertIndication |
|
// could be defined as follows: A {4, string} UPS Alert was |
|
// detected on the device {6[1]}. |
|
Uint32 leftBrace; |
|
while ((leftBrace = indicationFormat.find("{")) != PEG_NOT_FOUND) |
|
{ |
|
// Append the text up to the left brace |
|
indicationText.append(indicationFormat.subString(0, leftBrace)); |
|
indicationFormat = indicationFormat.subString(leftBrace+1); |
|
Uint32 rightBrace = indicationFormat.find("}"); |
|
|
|
// expecting a right brace |
|
if (rightBrace != PEG_NOT_FOUND) |
|
{ |
|
// gets property index which is inside braces. |
|
// The supported formats are: {index} or {index, type} |
|
// or {index[x]} or {index[x], type} |
|
String propertyParam = indicationFormat.subString(0, rightBrace); |
|
Uint32 comma = propertyParam.find(","); |
|
|
|
// A dynamic content has syntax {index, type} or {index[x], type} |
|
if (comma != PEG_NOT_FOUND) |
|
{ |
|
propertyParam = propertyParam.subString(0, comma); |
|
} |
|
|
|
String propertyIndexStr; |
|
String arrayIndexStr; |
|
Uint32 leftBracket = propertyParam.find("["); |
|
|
|
if (leftBracket == PEG_NOT_FOUND) |
|
{ |
|
// A dynamic content has syntax {index} or {index, type} |
|
propertyIndexStr = propertyParam; |
|
} |
|
else |
|
{ |
|
// A dynamic content has syntax {index[x]} or {index[x], type} |
|
propertyIndexStr = propertyParam.subString(0, leftBracket); |
|
propertyParam = propertyParam.subString(leftBracket); |
|
|
|
Uint32 rightBracket = propertyParam.find("]"); |
|
arrayIndexStr = propertyParam.subString(1, rightBracket-1); |
|
} |
|
|
|
String propertyValue; |
|
|
|
try |
|
{ |
|
Uint32 propertyIndex = _parseIndex(propertyIndexStr); |
|
Uint32 arrayIndex = PEG_NOT_FOUND; |
|
|
|
if (arrayIndexStr.size()) |
|
{ |
|
arrayIndex = _parseIndex(arrayIndexStr); |
|
} |
|
|
|
if (propertyIndex >= textFormatParams.size()) |
|
{ |
|
// Property index is out of range |
|
propertyValue = "UNKNOWN"; |
|
} |
|
else |
|
{ |
|
// get indication property value |
|
propertyValue = _getIndPropertyValue( |
|
textFormatParams[propertyIndex], |
|
arrayIndex, |
|
indication, |
|
contentLangs); |
|
} |
|
} |
|
catch (CIMException& c) |
|
{ |
|
PEG_TRACE((TRC_IND_FORMATTER, Tracer::LEVEL2, |
|
"Exception at parsing indication property: %s", |
|
(const char*)c.getMessage().getCString())); |
|
propertyValue = "UNKNOWN"; |
|
} |
|
|
|
indicationText.append(propertyValue); |
|
} |
|
|
|
indicationFormat = indicationFormat.subString(rightBrace+1); |
|
} |
|
|
|
indicationText.append(indicationFormat); |
|
|
|
PEG_METHOD_EXIT(); |
|
return indicationText; |
|
} |
|
|
|
String IndicationFormatter::_getIndPropertyValue( |
|
const String& propertyName, |
|
Uint32 arrayIndex, |
|
const CIMInstance& indication, |
|
const ContentLanguageList& contentLangs) |
|
{ |
|
PEG_METHOD_ENTER(TRC_IND_FORMATTER, |
|
"IndicationFormatter::_getIndPropertyValue"); |
|
|
|
Uint32 pos = indication.findProperty(propertyName); |
|
|
|
if (pos == PEG_NOT_FOUND) |
|
{ |
|
PEG_METHOD_EXIT(); |
|
return "UNKNOWN"; |
|
} |
|
|
|
CIMConstProperty property = indication.getProperty(pos); |
|
CIMValue propertyValue = property.getValue(); |
|
|
|
if (propertyValue.isNull()) |
|
{ |
|
PEG_METHOD_EXIT(); |
|
return "NULL"; |
|
} |
|
|
|
if (propertyValue.isArray()) |
|
{ |
|
PEG_METHOD_EXIT(); |
|
return _getArrayValues(propertyValue, arrayIndex, contentLangs); |
|
} |
|
|
|
// Value is not an array |
|
|
|
CIMValueLocalizer cimValueLocalizer(contentLangs); |
|
|
|
if (propertyValue.getType() == CIMTYPE_DATETIME) |
|
{ |
|
CIMDateTime dateTimeValue; |
|
propertyValue.get(dateTimeValue); |
|
PEG_METHOD_EXIT(); |
|
return cimValueLocalizer.getLocalizedValue(dateTimeValue); |
|
} |
|
|
|
if (propertyValue.getType() == CIMTYPE_BOOLEAN) |
|
{ |
|
Boolean booleanValue; |
|
propertyValue.get(booleanValue); |
|
PEG_METHOD_EXIT(); |
|
return cimValueLocalizer.getLocalizedValue(booleanValue); |
|
} |
|
|
|
PEG_METHOD_EXIT(); |
|
return propertyValue.toString(); |
|
} |
|
|
|
String IndicationFormatter::_getArrayValues( |
|
const CIMValue& value, |
|
Uint32 arrayIndex, |
|
const ContentLanguageList& contentLangs) |
|
{ |
|
PEG_METHOD_ENTER(TRC_IND_FORMATTER, "IndicationFormatter::_getArrayValues"); |
|
|
|
if ((arrayIndex != PEG_NOT_FOUND) && |
|
(arrayIndex >= value.getArraySize())) |
|
{ |
|
// Array index is out of range |
|
PEG_METHOD_EXIT(); |
|
return "UNKNOWN"; |
|
} |
|
|
|
String arrayValues; |
|
CIMValueLocalizer cimValueLocalizer(contentLangs); |
|
|
|
switch (value.getType()) |
|
{ |
|
case CIMTYPE_UINT8: |
|
{ |
|
appendArrayValue<Uint8>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_SINT8: |
|
{ |
|
appendArrayValue<Sint8>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_UINT16: |
|
{ |
|
appendArrayValue<Uint16>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_SINT16: |
|
{ |
|
appendArrayValue<Sint16>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_UINT32: |
|
{ |
|
appendArrayValue<Uint32>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_SINT32: |
|
{ |
|
appendArrayValue<Sint32>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_UINT64: |
|
{ |
|
appendArrayValue<Uint64>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_SINT64: |
|
{ |
|
appendArrayValue<Sint64>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_REAL32: |
|
{ |
|
appendArrayValue<Real32>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_REAL64: |
|
{ |
|
appendArrayValue<Real64>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_BOOLEAN: |
|
{ |
|
appendArrayValue<Boolean>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_CHAR16: |
|
{ |
|
appendArrayValue<Char16>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_STRING: |
|
{ |
|
appendArrayValue<String>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_DATETIME: |
|
{ |
|
appendArrayValue<CIMDateTime>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_REFERENCE: |
|
{ |
|
appendArrayValue<CIMObjectPath>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_OBJECT: |
|
{ |
|
appendArrayValue<CIMObject>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
case CIMTYPE_INSTANCE: |
|
{ |
|
appendArrayValue<CIMInstance>( |
|
arrayValues, value, arrayIndex, cimValueLocalizer); |
|
break; |
|
} |
|
|
|
default: |
|
{ |
|
PEG_TRACE((TRC_IND_FORMATTER, Tracer::LEVEL2, |
|
"Unknown CIMType: %u", |
|
value.getType())); |
|
|
|
arrayValues.append("UNKNOWN"); |
|
break; |
|
} |
|
} |
|
|
|
PEG_METHOD_EXIT(); |
|
return arrayValues; |
|
} |
|
|
|
PEGASUS_NAMESPACE_END |