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 * https://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 package org.apache.commons.configuration2.builder;
18
19 import org.apache.commons.configuration2.event.Event;
20 import org.apache.commons.configuration2.event.EventListener;
21 import org.apache.commons.configuration2.reloading.ReloadingController;
22 import org.apache.commons.configuration2.reloading.ReloadingEvent;
23
24 /**
25 * <p>
26 * An internally used helper class for adding reloading support to an arbitrary {@link ConfigurationBuilder}.
27 * </p>
28 * <p>
29 * This class connects a configuration builder with a {@link ReloadingController}. This is done in the following way:
30 * <ul>
31 * <li>An instance is registered as listener at a {@code ReloadingController}. Whenever the controller indicates that a
32 * reload should happen, the associated configuration builder's {@link BasicConfigurationBuilder#resetResult()} method
33 * is called.</li>
34 * <li>When the builder fires a {@link ConfigurationBuilderResultCreatedEvent} event the reloading controller's
35 * reloading state is reset. At that time the reload has actually happened, and the controller is prepared to observe
36 * new changes.</li>
37 * </ul>
38 * </p>
39 *
40 * @since 2.0
41 */
42 final class ReloadingBuilderSupportListener implements EventListener<Event> {
43 /**
44 * Creates a new instance of {@code ReloadingBuilderSupportListener} which connects the specified
45 * {@code ConfigurationBuilder} with the given {@code ReloadingController}. Listeners are registered to react on
46 * notifications and implement a reloading protocol as described in the class comment.
47 *
48 * @param configBuilder the {@code ConfigurationBuilder}
49 * @param controller the {@code ReloadingController}
50 * @return the newly created listener object
51 */
52 public static ReloadingBuilderSupportListener connect(final BasicConfigurationBuilder<?> configBuilder, final ReloadingController controller) {
53 final ReloadingBuilderSupportListener listener = new ReloadingBuilderSupportListener(configBuilder, controller);
54 controller.addEventListener(ReloadingEvent.ANY, listener);
55 configBuilder.installEventListener(ConfigurationBuilderResultCreatedEvent.RESULT_CREATED, listener);
56 return listener;
57 }
58
59 /** Stores the associated configuration builder. */
60 private final BasicConfigurationBuilder<?> builder;
61
62 /** Stores the associated reloading controller. */
63 private final ReloadingController reloadingController;
64
65 /**
66 * Creates a new instance of {@code ReloadingBuilderSupportListener} and initializes it with the associated objects.
67 *
68 * @param configBuilder the configuration builder
69 * @param controller the {@code ReloadingController}
70 */
71 private ReloadingBuilderSupportListener(final BasicConfigurationBuilder<?> configBuilder, final ReloadingController controller) {
72 builder = configBuilder;
73 reloadingController = controller;
74 }
75
76 /**
77 * {@inheritDoc} This implementation resets the controller's reloading state if an event about a newly created result
78 * was received. Otherwise, in case of a reloading event, the builder's result object is reset.
79 */
80 @Override
81 public void onEvent(final Event event) {
82 if (ConfigurationBuilderResultCreatedEvent.RESULT_CREATED.equals(event.getEventType())) {
83 reloadingController.resetReloadingState();
84 } else {
85 builder.resetResult();
86 }
87 }
88 }