void PropertySetter::setProperties(helpers::Properties& properties, const LogString& prefix, Pool& p) { int len = prefix.length(); std::vector<LogString> names = properties.propertyNames(); std::vector<LogString>::iterator it; for (it = names.begin(); it != names.end(); it++) { LogString key = *it; // handle only properties that start with the desired frefix. if (key.find(prefix) == 0) { // ignore key if it contains dots after the prefix if (key.find(0x2E /* '.' */, len + 1) != LogString::npos) { continue; } LogString value = OptionConverter::findAndSubst(key, properties); key = key.substr(len); if (key == LOG4CXX_STR("layout") && obj != 0 && obj->instanceof(Appender::getStaticClass())) { continue; } setProperty(key, value, p); } } activate(p); }
LevelPtr OptionConverter::toLevel(const LogString& value, const LevelPtr& defaultValue) { size_t hashIndex = value.find(LOG4CXX_STR("#")); if (hashIndex == LogString::npos) { if (value.empty()) { return defaultValue; } else { LogLog::debug( ((LogString) LOG4CXX_STR("OptionConverter::toLevel: no class name specified, level=[")) + value +LOG4CXX_STR("]")); // no class name specified : use standard Level class return Level::toLevelLS(value, defaultValue); } } LogString clazz = value.substr(hashIndex + 1); LogString levelName = value.substr(0, hashIndex); LogLog::debug(((LogString) LOG4CXX_STR("OptionConverter::toLevel: class=[")) + clazz + LOG4CXX_STR("], level=[") + levelName + LOG4CXX_STR("]")); // This is degenerate case but you never know. if (levelName.empty()) { return Level::toLevelLS(value, defaultValue); } try { Level::LevelClass& levelClass = (Level::LevelClass&)Loader::loadClass(clazz); return levelClass.toLevel(levelName); } catch (ClassNotFoundException&) { LogLog::warn(((LogString) LOG4CXX_STR("custom level class [")) + clazz + LOG4CXX_STR("] not found.")); } catch(Exception& oops) { LogLog::warn( LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("], level [") + levelName + LOG4CXX_STR("] conversion) failed."), oops); } catch(...) { LogLog::warn( LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("], level [") + levelName + LOG4CXX_STR("] conversion) failed.")); } return defaultValue; }
/** * Gets maximum cache validity for the specified SimpleDateTime * conversion pattern. * @param pattern conversion pattern, may not be null. * @returns Duration in microseconds from an integral second * that the cache will return consistent results. */ int CachedDateFormat::getMaximumCacheValidity(const LogString& pattern) { // // If there are more "S" in the pattern than just one "SSS" then // (for example, "HH:mm:ss,SSS SSS"), then set the expiration to // one millisecond which should only perform duplicate request caching. // const logchar S = 0x53; const logchar SSS[] = { 0x53, 0x53, 0x53, 0 }; size_t firstS = pattern.find(S); size_t len = pattern.length(); // // if there are no S's or // three that start with the first S and no fourth S in the string // if (firstS == LogString::npos || (len >= firstS + 3 && pattern.compare(firstS, 3, SSS) == 0 && (len == firstS + 3 || pattern.find(S, firstS + 3) == LogString::npos))) { return 1000000; } return 1000; }
/** * Abbreviate element of name. * @param buf buffer to receive element. * @param startPos starting index of name element. * @return starting index of next element. */ LogString::size_type abbreviate(LogString& buf, LogString::size_type startPos) const { LogString::size_type nextDot = buf.find(0x2E /* '.' */, startPos); if (nextDot != LogString::npos) { if ((nextDot - startPos) > charCount) { buf.erase(buf.begin() + (startPos + charCount), buf.begin() + nextDot); nextDot = startPos + charCount; if (ellipsis != 0x00) { buf.insert(nextDot, 1, ellipsis); nextDot++; } } nextDot++; } return nextDot; }
LogString OptionConverter::substVars(const LogString& val, Properties& props) { LogString sbuf; const logchar delimStartArray[] = { 0x24, 0x7B, 0 }; const LogString delimStart(delimStartArray); const logchar delimStop = 0x7D; // '}'; const size_t DELIM_START_LEN = 2; const size_t DELIM_STOP_LEN = 1; int i = 0; int j, k; while(true) { j = val.find(delimStart, i); if(j == -1) { // no more variables if(i==0) { // this is a simple string return val; } else { // add the tail string which contails no variables and return the result. sbuf.append(val.substr(i, val.length() - i)); return sbuf; } } else { sbuf.append(val.substr(i, j - i)); k = val.find(delimStop, j); if(k == -1) { LogString msg(1, (logchar) 0x22 /* '\"' */); msg.append(val); msg.append(LOG4CXX_STR("\" has no closing brace. Opening brace at position ")); Pool p; StringHelper::toString(j, p, msg); msg.append(1, (logchar) 0x2E /* '.' */); throw IllegalArgumentException(msg); } else { j += DELIM_START_LEN; LogString key = val.substr(j, k - j); // first try in System properties LogString replacement(getSystemProperty(key, LogString())); // then try props parameter if(replacement.empty()) { replacement = props.getProperty(key); } if(!replacement.empty()) { // Do variable substitution on the replacement string // such that we can solve "Hello ${x2}" as "Hello p1" // the where the properties are // x1=p1 // x2=${x1} LogString recursiveReplacement = substVars(replacement, props); sbuf.append(recursiveReplacement); } i = k + DELIM_STOP_LEN; } } } }