Coverage Report

Created: 2025-07-01 06:08

/src/logging-log4cxx/src/main/cpp/propertyconfigurator.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
#include <log4cxx/logstring.h>
19
#include <log4cxx/propertyconfigurator.h>
20
#include <log4cxx/helpers/properties.h>
21
#include <log4cxx/helpers/loglog.h>
22
#include <log4cxx/helpers/exception.h>
23
#include <log4cxx/logmanager.h>
24
#include <log4cxx/helpers/optionconverter.h>
25
#include <log4cxx/level.h>
26
#if LOG4CXX_ABI_VERSION <= 15
27
#include <log4cxx/defaultloggerfactory.h>
28
#else
29
#include <log4cxx/spi/loggerfactory.h>
30
#endif
31
#include <log4cxx/helpers/stringhelper.h>
32
#include <log4cxx/layout.h>
33
#include <log4cxx/config/propertysetter.h>
34
#include <log4cxx/helpers/stringtokenizer.h>
35
#include <log4cxx/helpers/transcoder.h>
36
#include <log4cxx/helpers/fileinputstream.h>
37
#include <log4cxx/helpers/loader.h>
38
#include <log4cxx/helpers/threadutility.h>
39
#include <log4cxx/rolling/rollingfileappender.h>
40
41
#define LOG4CXX 1
42
#include <log4cxx/helpers/aprinitializer.h>
43
44
using namespace LOG4CXX_NS;
45
using namespace LOG4CXX_NS::spi;
46
using namespace LOG4CXX_NS::helpers;
47
using namespace LOG4CXX_NS::config;
48
using namespace LOG4CXX_NS::rolling;
49
50
#include <log4cxx/helpers/filewatchdog.h>
51
namespace LOG4CXX_NS
52
{
53
class PropertyWatchdog  : public FileWatchdog
54
{
55
  public:
56
0
    PropertyWatchdog(const File& filename) : FileWatchdog(filename)
57
0
    {
58
0
    }
59
60
    /**
61
    Call PropertyConfigurator#doConfigure(const String& configFileName,
62
    const spi::LoggerRepositoryPtr& hierarchy) with the
63
    <code>filename</code> to reconfigure log4cxx.
64
    */
65
    void doOnChange()
66
0
    {
67
0
      PropertyConfigurator().doConfigure(file(),
68
0
        LogManager::getLoggerRepository());
69
0
    }
70
};
71
}
72
73
PropertyWatchdog* PropertyConfigurator::pdog = NULL;
74
75
IMPLEMENT_LOG4CXX_OBJECT(PropertyConfigurator)
76
77
PropertyConfigurator::PropertyConfigurator()
78
1
  : registry(new std::map<LogString, AppenderPtr>())
79
#if LOG4CXX_ABI_VERSION <= 15
80
1
  , loggerFactory(new DefaultLoggerFactory())
81
#else
82
  , loggerFactory(new LoggerFactory())
83
#endif
84
1
{
85
1
}
Unexecuted instantiation: log4cxx::PropertyConfigurator::PropertyConfigurator()
log4cxx::PropertyConfigurator::PropertyConfigurator()
Line
Count
Source
78
1
  : registry(new std::map<LogString, AppenderPtr>())
79
#if LOG4CXX_ABI_VERSION <= 15
80
1
  , loggerFactory(new DefaultLoggerFactory())
81
#else
82
  , loggerFactory(new LoggerFactory())
83
#endif
84
1
{
85
1
}
86
87
PropertyConfigurator::~PropertyConfigurator()
88
1
{
89
1
  delete registry;
90
1
}
91
92
spi::ConfigurationStatus PropertyConfigurator::doConfigure
93
  ( const File&                     configFileName
94
#if LOG4CXX_ABI_VERSION <= 15
95
  , spi::LoggerRepositoryPtr        repository
96
#else
97
  , const spi::LoggerRepositoryPtr& repository
98
#endif
99
  )
100
1
{
101
1
  auto hierarchy = repository ? repository : LogManager::getLoggerRepository();
102
1
  hierarchy->setConfigured(true);
103
104
1
  Properties props;
105
106
1
  try
107
1
  {
108
1
    InputStreamPtr inputStream = InputStreamPtr( new FileInputStream(configFileName) );
109
1
    props.load(inputStream);
110
1
  }
111
1
  catch (const IOException& ex)
112
1
  {
113
0
    LOG4CXX_DECODE_CHAR(lsMsg, ex.what());
114
0
    LogLog::error(((LogString) LOG4CXX_STR("Could not read configuration file ["))
115
0
      + configFileName.getPath() + LOG4CXX_STR("]: ") + lsMsg);
116
0
    return spi::ConfigurationStatus::NotConfigured;
117
0
  }
118
119
1
  try
120
1
  {
121
1
    if (LogLog::isDebugEnabled())
122
0
    {
123
0
      LogString debugMsg = LOG4CXX_STR("Loading configuration file [")
124
0
          + configFileName.getPath() + LOG4CXX_STR("].");
125
0
      LogLog::debug(debugMsg);
126
0
    }
127
1
    return doConfigure(props, hierarchy);
128
1
  }
129
1
  catch (const std::exception& ex)
130
1
  {
131
0
    LogLog::error(((LogString) LOG4CXX_STR("Could not parse configuration file ["))
132
0
      + configFileName.getPath() + LOG4CXX_STR("]: "), ex);
133
0
  }
134
135
0
  return spi::ConfigurationStatus::NotConfigured;
136
1
}
137
138
spi::ConfigurationStatus PropertyConfigurator::configure(const File& configFilename)
139
1
{
140
1
  return PropertyConfigurator().doConfigure(configFilename, LogManager::getLoggerRepository());
141
1
}
142
143
spi::ConfigurationStatus PropertyConfigurator::configure(helpers::Properties& properties)
144
0
{
145
0
  return PropertyConfigurator().doConfigure(properties, LogManager::getLoggerRepository());
146
0
}
147
148
#if LOG4CXX_ABI_VERSION <= 15
149
spi::ConfigurationStatus PropertyConfigurator::configureAndWatch(const File& configFilename)
150
0
{
151
0
  return configureAndWatch(configFilename, FileWatchdog::DEFAULT_DELAY);
152
0
}
153
#endif
154
155
spi::ConfigurationStatus PropertyConfigurator::configureAndWatch(
156
  const File& configFilename, long delay)
157
0
{
158
0
  if (pdog)
159
0
  {
160
0
    APRInitializer::unregisterCleanup(pdog);
161
0
    delete pdog;
162
0
  }
163
164
0
  spi::ConfigurationStatus stat = PropertyConfigurator().doConfigure(configFilename, LogManager::getLoggerRepository());
165
166
0
  pdog = new PropertyWatchdog(configFilename);
167
0
  APRInitializer::registerCleanup(pdog);
168
0
  pdog->setDelay(0 < delay ? delay : FileWatchdog::DEFAULT_DELAY);
169
0
  pdog->start();
170
171
0
  return stat;
172
0
}
173
174
spi::ConfigurationStatus PropertyConfigurator::doConfigure(helpers::Properties& properties,
175
  spi::LoggerRepositoryPtr hierarchy)
176
1
{
177
1
  hierarchy->setConfigured(true);
178
179
1
  static const WideLife<LogString> DEBUG_KEY(LOG4CXX_STR("log4j.debug"));
180
1
  LogString value(properties.getProperty(DEBUG_KEY));
181
182
1
  if (!value.empty())
183
0
  {
184
0
    LogLog::setInternalDebugging(OptionConverter::toBoolean(value, true));
185
0
  }
186
187
1
  static const WideLife<LogString> THRESHOLD_PREFIX(LOG4CXX_STR("log4j.threshold"));
188
1
  LogString thresholdStr =
189
1
    OptionConverter::findAndSubst(THRESHOLD_PREFIX, properties);
190
191
1
  if (!thresholdStr.empty())
192
0
  {
193
0
    hierarchy->setThreshold(OptionConverter::toLevel(thresholdStr, Level::getAll()));
194
0
    if (LogLog::isDebugEnabled())
195
0
    {
196
0
      LogLog::debug(((LogString) LOG4CXX_STR("Hierarchy threshold set to ["))
197
0
        + hierarchy->getThreshold()->toString()
198
0
        + LOG4CXX_STR("]."));
199
0
    }
200
0
  }
201
202
1
  LogString threadConfigurationValue(properties.getProperty(LOG4CXX_STR("log4j.threadConfiguration")));
203
204
1
  if ( threadConfigurationValue == LOG4CXX_STR("NoConfiguration") )
205
0
  {
206
0
    helpers::ThreadUtility::configure( ThreadConfigurationType::NoConfiguration );
207
0
  }
208
1
  else if ( threadConfigurationValue == LOG4CXX_STR("BlockSignalsOnly") )
209
0
  {
210
0
    helpers::ThreadUtility::configure( ThreadConfigurationType::BlockSignalsOnly );
211
0
  }
212
1
  else if ( threadConfigurationValue == LOG4CXX_STR("NameThreadOnly") )
213
0
  {
214
0
    helpers::ThreadUtility::configure( ThreadConfigurationType::NameThreadOnly );
215
0
  }
216
1
  else if ( threadConfigurationValue == LOG4CXX_STR("BlockSignalsAndNameThread") )
217
0
  {
218
0
    helpers::ThreadUtility::configure( ThreadConfigurationType::BlockSignalsAndNameThread );
219
0
  }
220
221
1
  configureRootLogger(properties, hierarchy);
222
1
  configureLoggerFactory(properties);
223
1
  parseCatsAndRenderers(properties, hierarchy);
224
225
1
  LogLog::debug(LOG4CXX_STR("Finished configuring."));
226
227
  // We don't want to hold references to appenders preventing their
228
  // destruction.
229
1
  registry->clear();
230
231
1
  return spi::ConfigurationStatus::Configured;
232
1
}
233
234
void PropertyConfigurator::configureLoggerFactory(helpers::Properties& props)
235
1
{
236
1
  static const WideLife<LogString> LOGGER_FACTORY_KEY(LOG4CXX_STR("log4j.loggerFactory"));
237
238
1
  LogString factoryClassName =
239
1
    OptionConverter::findAndSubst(LOGGER_FACTORY_KEY, props);
240
241
1
  if (!factoryClassName.empty())
242
0
  {
243
0
    if (LogLog::isDebugEnabled())
244
0
    {
245
0
      LogString msg(LOG4CXX_STR("Setting logger factory to ["));
246
0
      msg += factoryClassName;
247
0
      msg += LOG4CXX_STR("].");
248
0
      LogLog::debug(msg);
249
0
    }
250
0
    std::shared_ptr<Object> instance = std::shared_ptr<Object>(
251
0
        Loader::loadClass(factoryClassName).newInstance() );
252
253
0
    loggerFactory = LOG4CXX_NS::cast<LoggerFactory>( instance );
254
0
    static const WideLife<LogString> FACTORY_PREFIX(LOG4CXX_STR("log4j.factory."));
255
0
    Pool p;
256
0
    PropertySetter::setProperties(loggerFactory, props, FACTORY_PREFIX, p);
257
0
  }
258
1
}
259
260
void PropertyConfigurator::configureRootLogger(helpers::Properties& props,
261
  spi::LoggerRepositoryPtr& hierarchy)
262
1
{
263
1
  static const WideLife<LogString> ROOT_CATEGORY_PREFIX(LOG4CXX_STR("log4j.rootCategory"));
264
1
  static const WideLife<LogString> ROOT_LOGGER_PREFIX(LOG4CXX_STR("log4j.rootLogger"));
265
266
267
268
1
  LogString effectiveFrefix(ROOT_LOGGER_PREFIX);
269
1
  LogString value = OptionConverter::findAndSubst(ROOT_LOGGER_PREFIX, props);
270
271
1
  if (value.empty())
272
0
  {
273
0
    value = OptionConverter::findAndSubst(ROOT_CATEGORY_PREFIX, props);
274
0
    effectiveFrefix = ROOT_CATEGORY_PREFIX;
275
0
  }
276
277
1
  if (value.empty())
278
0
  {
279
0
    LogLog::debug(LOG4CXX_STR("Could not find root logger information. Is this OK?"));
280
0
  }
281
1
  else
282
1
  {
283
1
    LoggerPtr root = hierarchy->getRootLogger();
284
285
1
    static const WideLife<LogString> INTERNAL_ROOT_NAME(LOG4CXX_STR("root"));
286
1
    parseLogger(props, root, effectiveFrefix, INTERNAL_ROOT_NAME, value, true);
287
1
  }
288
1
}
289
290
void PropertyConfigurator::parseCatsAndRenderers(helpers::Properties& props,
291
  spi::LoggerRepositoryPtr& hierarchy)
292
1
{
293
1
  static const WideLife<LogString> CATEGORY_PREFIX(LOG4CXX_STR("log4j.category."));
294
1
  static const WideLife<LogString> LOGGER_PREFIX(LOG4CXX_STR("log4j.logger."));
295
296
1
  for (auto key : props.propertyNames())
297
4
  {
298
4
    if (key.find(CATEGORY_PREFIX) == 0 || key.find(LOGGER_PREFIX) == 0)
299
0
    {
300
0
      LogString loggerName;
301
302
0
      if (key.find(CATEGORY_PREFIX) == 0)
303
0
      {
304
0
        loggerName = key.substr(CATEGORY_PREFIX.value().length());
305
0
      }
306
0
      else if (key.find(LOGGER_PREFIX.value()) == 0)
307
0
      {
308
0
        loggerName = key.substr(LOGGER_PREFIX.value().length());
309
0
      }
310
311
0
      LogString value = OptionConverter::findAndSubst(key, props);
312
0
      LoggerPtr logger = hierarchy->getLogger(loggerName, loggerFactory);
313
314
0
      bool additivity = parseAdditivityForLogger(props, logger, loggerName);
315
0
      parseLogger(props, logger, key, loggerName, value, additivity);
316
317
0
    }
318
4
  }
319
1
}
320
321
bool PropertyConfigurator::parseAdditivityForLogger(helpers::Properties& props,
322
  LoggerPtr& cat, const LogString& loggerName)
323
0
{
324
325
0
  static const WideLife<LogString> ADDITIVITY_PREFIX(LOG4CXX_STR("log4j.additivity."));
326
327
328
329
0
  LogString value(OptionConverter::findAndSubst(ADDITIVITY_PREFIX.value() + loggerName, props));
330
0
  if (LogLog::isDebugEnabled())
331
0
  {
332
0
    LogLog::debug((LogString) LOG4CXX_STR("Handling ") + ADDITIVITY_PREFIX.value()
333
0
      + loggerName + LOG4CXX_STR("=[") +  value + LOG4CXX_STR("]"));
334
0
  }
335
  // touch additivity only if necessary
336
0
  if (!value.empty())
337
0
  {
338
0
    bool additivity = OptionConverter::toBoolean(value, true);
339
0
    if (LogLog::isDebugEnabled())
340
0
    {
341
0
      LogLog::debug(((LogString) LOG4CXX_STR("Setting additivity for \""))
342
0
        + loggerName
343
0
        + ((additivity) ?  LOG4CXX_STR("\" to true") :
344
0
          LOG4CXX_STR("\" to false")));
345
0
    }
346
347
0
    return additivity;
348
0
  }
349
350
0
  return true;
351
0
}
352
353
/**
354
        This method must work for the root logger as well.
355
*/
356
void PropertyConfigurator::parseLogger(
357
  helpers::Properties& props, LoggerPtr& logger, const LogString& /* optionKey */,
358
  const LogString& loggerName, const LogString& value, bool additivity)
359
1
{
360
1
  if (LogLog::isDebugEnabled())
361
0
  {
362
0
    LogLog::debug(((LogString) LOG4CXX_STR("Parsing for ["))
363
0
      + loggerName
364
0
      + LOG4CXX_STR("] with value=[")
365
0
      + value + LOG4CXX_STR("]."));
366
0
  }
367
368
  // We must skip over ',' but not white space
369
1
  StringTokenizer st(value, LOG4CXX_STR(","));
370
371
  // If value is not in the form ", appender.." or "", then we should set
372
  // the level of the logger.
373
1
  if (!(value.find(LOG4CXX_STR(",")) == 0 || value.empty()))
374
1
  {
375
    // just to be on the safe side...
376
1
    if (!st.hasMoreTokens())
377
0
    {
378
0
      return;
379
0
    }
380
381
1
    LogString levelStr = st.nextToken();
382
1
    if (LogLog::isDebugEnabled())
383
0
    {
384
0
      LogLog::debug((LogString) LOG4CXX_STR("Level token is [")
385
0
        + levelStr +  LOG4CXX_STR("]."));
386
0
    }
387
388
389
    // If the level value is inherited, set logger level value to
390
    // null. We also check that the user has not specified inherited for the
391
    // root logger.
392
1
    if (StringHelper::equalsIgnoreCase(levelStr, LOG4CXX_STR("INHERITED"), LOG4CXX_STR("inherited"))
393
1
      || StringHelper::equalsIgnoreCase(levelStr, LOG4CXX_STR("NULL"), LOG4CXX_STR("null")))
394
0
    {
395
0
      static const WideLife<LogString> INTERNAL_ROOT_NAME(LOG4CXX_STR("root"));
396
397
0
      if (loggerName == INTERNAL_ROOT_NAME.value())
398
0
      {
399
0
        LogLog::warn(LOG4CXX_STR("The root logger cannot be set to null."));
400
0
      }
401
0
      else
402
0
      {
403
0
        logger->setLevel(0);
404
0
        if (LogLog::isDebugEnabled())
405
0
        {
406
0
          LogLog::debug((LogString) LOG4CXX_STR("Logger ")
407
0
            + loggerName + LOG4CXX_STR(" set to null"));
408
0
        }
409
0
      }
410
0
    }
411
1
    else
412
1
    {
413
1
      logger->setLevel(OptionConverter::toLevel(levelStr, Level::getDebug()));
414
415
1
      if (LogLog::isDebugEnabled())
416
0
      {
417
0
        LogLog::debug((LogString) LOG4CXX_STR("Logger ")
418
0
          + loggerName + LOG4CXX_STR(" set to ")
419
0
          + logger->getLevel()->toString());
420
0
      }
421
1
    }
422
423
1
  }
424
425
1
  AppenderPtr appender;
426
1
  LogString appenderName;
427
1
  std::vector<AppenderPtr> newappenders;
428
429
2
  while (st.hasMoreTokens())
430
1
  {
431
1
    appenderName = StringHelper::trim(st.nextToken());
432
433
1
    if (appenderName.empty() || appenderName == LOG4CXX_STR(","))
434
0
    {
435
0
      continue;
436
0
    }
437
438
1
    if (LogLog::isDebugEnabled())
439
0
    {
440
0
      LogLog::debug(LOG4CXX_STR("Parsing appender named ")
441
0
        + appenderName + LOG4CXX_STR("\"."));
442
0
    }
443
1
    appender = parseAppender(props, appenderName);
444
445
1
    if (appender != 0)
446
1
    {
447
1
      newappenders.push_back(appender);
448
1
    }
449
1
  }
450
451
1
  logger->reconfigure( newappenders, additivity );
452
1
}
453
454
AppenderPtr PropertyConfigurator::parseAppender(
455
  helpers::Properties& props, const LogString& appenderName)
456
1
{
457
1
  AppenderPtr appender = registryGet(appenderName);
458
459
1
  if (appender != 0)
460
0
  {
461
0
    if (LogLog::isDebugEnabled())
462
0
    {
463
0
      LogLog::debug((LogString) LOG4CXX_STR("Appender \"")
464
0
        + appenderName + LOG4CXX_STR("\" was already parsed."));
465
0
    }
466
467
0
    return appender;
468
0
  }
469
470
1
  static const WideLife<LogString> APPENDER_PREFIX(LOG4CXX_STR("log4j.appender."));
471
472
  // Appender was not previously initialized.
473
1
  LogString prefix = APPENDER_PREFIX.value() + appenderName;
474
1
  LogString layoutPrefix = prefix + LOG4CXX_STR(".layout");
475
476
1
  std::shared_ptr<Object> obj =
477
1
    OptionConverter::instantiateByKey(
478
1
      props, prefix, Appender::getStaticClass(), 0);
479
1
  appender = LOG4CXX_NS::cast<Appender>( obj );
480
481
  // Map obsolete DailyRollingFileAppender property configuration
482
1
  if (!appender &&
483
1
    StringHelper::endsWith(OptionConverter::findAndSubst(prefix, props), LOG4CXX_STR("DailyRollingFileAppender")))
484
0
  {
485
0
    appender = std::make_shared<RollingFileAppender>();
486
0
    auto datePattern = OptionConverter::findAndSubst(prefix + LOG4CXX_STR(".datePattern"), props);
487
0
    if (!datePattern.empty())
488
0
      props.put(prefix + LOG4CXX_STR(".fileDatePattern"), datePattern);
489
0
  }
490
491
1
  if (!appender)
492
0
  {
493
0
    LogLog::error((LogString) LOG4CXX_STR("Could not instantiate appender named \"")
494
0
      + appenderName + LOG4CXX_STR("\"."));
495
0
    return 0;
496
0
  }
497
498
1
  appender->setName(appenderName);
499
500
1
  if (appender->instanceof(OptionHandler::getStaticClass()))
501
1
  {
502
1
    Pool p;
503
504
1
    if (appender->requiresLayout())
505
1
    {
506
1
      LayoutPtr layout;
507
1
      std::shared_ptr<Object> obj =
508
1
        OptionConverter::instantiateByKey(
509
1
          props, layoutPrefix, Layout::getStaticClass(), 0);
510
1
      layout = LOG4CXX_NS::cast<Layout>( obj );
511
512
1
      if (layout != 0)
513
1
      {
514
1
        appender->setLayout(layout);
515
1
        if (LogLog::isDebugEnabled())
516
0
        {
517
0
          LogLog::debug((LogString) LOG4CXX_STR("Parsing layout options for \"")
518
0
            + appenderName + LOG4CXX_STR("\"."));
519
0
        }
520
521
1
        PropertySetter::setProperties(layout, props, layoutPrefix + LOG4CXX_STR("."), p);
522
1
        if (LogLog::isDebugEnabled())
523
0
        {
524
0
          LogLog::debug((LogString) LOG4CXX_STR("End of parsing for \"")
525
0
            + appenderName +  LOG4CXX_STR("\"."));
526
0
        }
527
1
      }
528
1
    }
529
530
1
    RollingFileAppenderPtr rolling = LOG4CXX_NS::cast<rolling::RollingFileAppender>(appender);
531
1
    if (rolling)
532
0
    {
533
0
      LogString rollingPolicyKey = prefix + LOG4CXX_STR(".rollingPolicy");
534
0
      if (!OptionConverter::findAndSubst(rollingPolicyKey, props).empty())
535
0
      {
536
0
        RollingPolicyPtr rollingPolicy;
537
0
        std::shared_ptr<Object> rolling_obj =
538
0
          OptionConverter::instantiateByKey(
539
0
            props, rollingPolicyKey, RollingPolicy::getStaticClass(), 0);
540
0
        rollingPolicy = LOG4CXX_NS::cast<RollingPolicy>( rolling_obj );
541
0
        if(rollingPolicy)
542
0
        {
543
0
          rolling->setRollingPolicy(rollingPolicy);
544
545
0
          if (LogLog::isDebugEnabled())
546
0
          {
547
0
            LogLog::debug((LogString) LOG4CXX_STR("Parsing rolling policy options for \"")
548
0
              + appenderName + LOG4CXX_STR("\"."));
549
0
          }
550
0
          PropertySetter::setProperties(rollingPolicy, props, rollingPolicyKey + LOG4CXX_STR("."), p);
551
0
        }
552
0
      }
553
554
0
      LogString triggeringPolicyKey = prefix + LOG4CXX_STR(".triggeringPolicy");
555
0
      if (!OptionConverter::findAndSubst(triggeringPolicyKey, props).empty())
556
0
      {
557
0
        TriggeringPolicyPtr triggeringPolicy;
558
0
        std::shared_ptr<Object> triggering_obj =
559
0
          OptionConverter::instantiateByKey(
560
0
            props, triggeringPolicyKey, TriggeringPolicy::getStaticClass(), 0);
561
0
        triggeringPolicy = LOG4CXX_NS::cast<TriggeringPolicy>( triggering_obj );
562
0
        if(triggeringPolicy)
563
0
        {
564
0
          rolling->setTriggeringPolicy(triggeringPolicy);
565
566
0
          if (LogLog::isDebugEnabled())
567
0
          {
568
0
            LogLog::debug((LogString) LOG4CXX_STR("Parsing triggering policy options for \"")
569
0
              + appenderName + LOG4CXX_STR("\"."));
570
0
          }
571
0
          PropertySetter::setProperties(triggeringPolicy, props, triggeringPolicyKey + LOG4CXX_STR("."), p);
572
0
        }
573
0
      }
574
0
    }
575
576
1
    PropertySetter::setProperties(appender, props, prefix + LOG4CXX_STR("."), p);
577
1
    if (LogLog::isDebugEnabled())
578
0
    {
579
0
      LogLog::debug((LogString) LOG4CXX_STR("Parsed \"")
580
0
        + appenderName + LOG4CXX_STR("\" options."));
581
0
    }
582
1
  }
583
584
1
  registryPut(appender);
585
586
1
  return appender;
587
1
}
588
589
void PropertyConfigurator::registryPut(const AppenderPtr& appender)
590
1
{
591
1
  (*registry)[appender->getName()] = appender;
592
1
}
593
594
AppenderPtr PropertyConfigurator::registryGet(const LogString& name)
595
1
{
596
1
  return (*registry)[name];
597
1
}