$search
00001 /* 00002 * Properties.cpp 00003 * 00004 * Copyright 2002, Log4cpp Project. All rights reserved. 00005 * 00006 * See the COPYING file for the terms of usage and distribution. 00007 */ 00008 00009 #include "Properties.hh" 00010 #include <cstdlib> 00011 #include "StringUtil.hh" 00012 00013 namespace log4cpp { 00014 00015 Properties::Properties() { 00016 } 00017 00018 Properties::~Properties() { 00019 } 00020 00021 void Properties::load(std::istream& in) { 00022 clear(); 00023 00024 std::string fullLine, command; 00025 std::string leftSide, rightSide; 00026 char line[256]; 00027 std::string::size_type length; 00028 00029 while (in.getline(line, 256)) { 00030 fullLine = line; 00031 00032 /* if the line contains a # then it is a comment 00033 if we find it anywhere other than the beginning, then we assume 00034 there is a command on that line, and it we don't find it at all 00035 we assume there is a command on the line (we test for valid 00036 command later) if neither is true, we continue with the next line 00037 */ 00038 length = fullLine.find('#'); 00039 if (length == std::string::npos) { 00040 command = fullLine; 00041 } else if (length > 0) { 00042 command = fullLine.substr(0, length); 00043 } else { 00044 continue; 00045 } 00046 00047 // check the command and handle it 00048 length = command.find('='); 00049 if (length != std::string::npos) { 00050 leftSide = StringUtil::trim(command.substr(0, length)); 00051 rightSide = StringUtil::trim(command.substr(length + 1, command.size() - length)); 00052 _substituteVariables(rightSide); 00053 } else { 00054 continue; 00055 } 00056 00057 /* handle the command by determining what object the left side 00058 refers to and setting the value given on the right 00059 ASSUMPTIONS: 00060 1. first object given on left side is "log4j" or "log4cpp" 00061 2. all class names on right side are ignored because we 00062 probably cannot resolve them anyway. 00063 */ 00064 00065 // strip off the "log4j" or "log4cpp" 00066 length = leftSide.find('.'); 00067 if (leftSide.substr(0, length) == "log4j" || 00068 leftSide.substr(0, length) == "log4cpp") 00069 leftSide = leftSide.substr(length + 1); 00070 00071 // add to the map of properties 00072 insert(value_type(leftSide, rightSide)); 00073 } 00074 } 00075 00076 void Properties::save(std::ostream& out) { 00077 for(const_iterator i = begin(); i != end(); ++i) { 00078 out << (*i).first << "=" << (*i).second << std::endl; 00079 } 00080 } 00081 00082 int Properties::getInt(const std::string& property, int defaultValue) { 00083 const_iterator key = find(property); 00084 return (key == end()) ? defaultValue : std::atoi((*key).second.c_str()); 00085 } 00086 00087 bool Properties::getBool(const std::string& property, bool defaultValue) { 00088 const_iterator key = find(property); 00089 return (key == end()) ? defaultValue : ((*key).second == "true"); 00090 } 00091 00092 std::string Properties::getString(const std::string& property, 00093 const char* defaultValue) { 00094 const_iterator key = find(property); 00095 return (key == end()) ? std::string(defaultValue) : (*key).second; 00096 } 00097 00098 void Properties::_substituteVariables(std::string& value) { 00099 std::string result; 00100 00101 std::string::size_type left = 0; 00102 std::string::size_type right = value.find("${", left); 00103 if (right == std::string::npos) { 00104 // bail out early for 99% of cases 00105 return; 00106 } 00107 00108 while(true) { 00109 result += value.substr(left, right - left); 00110 if (right == std::string::npos) { 00111 break; 00112 } 00113 00114 left = right + 2; 00115 right = value.find('}', left); 00116 if (right == std::string::npos) { 00117 // no close tag, use string literally 00118 result += value.substr(left - 2); 00119 break; 00120 } else { 00121 const std::string key = value.substr(left, right - left); 00122 if (key == "${") { 00123 result += "${"; 00124 } else { 00125 char* value = std::getenv(key.c_str()); 00126 if (value) { 00127 result += value; 00128 } else { 00129 const_iterator it = find(key); 00130 if (it == end()) { 00131 // not found assume empty; 00132 } else { 00133 result += (*it).second; 00134 } 00135 } 00136 } 00137 left = right + 1; 00138 } 00139 00140 right = value.find("${", left); 00141 } 00142 00143 value = result; 00144 } 00145 }