//%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 #include #include #include #include #include #if defined(PEGASUS_HAS_ICU) && defined(PEGASUS_INDFORMATTER_USE_ICU) # include # include # include #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 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 void appendArrayValue( String& buffer, const CIMValue& value, Uint32 arrayIndex, const CIMValueLocalizer& cimValueLocalizer) { PEGASUS_ASSERT(value.isArray()); Array 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& 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 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& textFormatParams) { PEG_METHOD_ENTER(TRC_IND_FORMATTER, "IndicationFormatter::validateTextFormatParameters"); Array 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 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 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& 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( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_SINT8: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_UINT16: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_SINT16: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_UINT32: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_SINT32: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_UINT64: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_SINT64: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_REAL32: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_REAL64: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_BOOLEAN: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_CHAR16: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_STRING: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_DATETIME: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_REFERENCE: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_OBJECT: { appendArrayValue( arrayValues, value, arrayIndex, cimValueLocalizer); break; } case CIMTYPE_INSTANCE: { appendArrayValue( 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