2 * ============LICENSE_START=======================================================
3 * ONAP : ccsdk features
4 * ================================================================================
5 * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.ccsdk.features.sdnr.wt.common.configuration;
24 import java.io.BufferedReader;
25 import java.io.BufferedWriter;
27 import java.io.FileReader;
28 import java.io.FileWriter;
29 import java.io.IOException;
30 import java.util.HashMap;
31 import java.util.Optional;
33 import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.ConfigFileObserver;
34 import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener;
35 import org.onap.ccsdk.features.sdnr.wt.common.configuration.subtypes.Section;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * Representation of configuration file with section.<br>
41 * A root section is used for parameters, not assigned to a specific section.<br>
42 * The definitions of the configuration are attributes of a java class<br>
44 public class ConfigurationFileRepresentation implements IConfigChangedListener {
47 private static final Logger LOG = LoggerFactory.getLogger(ConfigurationFileRepresentation.class);
49 private static final long FILE_POLL_INTERVAL_MS = 1000;
50 private static final String SECTIONNAME_ROOT = "";
51 private static final String LR = "\n";
52 private static final String EMPTY = "";
56 /** Related configuration file **/
57 private final File mFile;
58 /** Monitor changes of file **/
59 private final ConfigFileObserver fileObserver;
60 /** List of sections **/
61 private final HashMap<String, Section> sections;
65 public ConfigurationFileRepresentation(File f) {
68 this.sections = new HashMap<String, Section>();
70 if (!this.mFile.exists()) {
71 if (!this.mFile.createNewFile()) {
72 LOG.error("Can not create file {}", f.getAbsolutePath());
77 } catch (IOException e) {
78 LOG.error("Problem loading config file {} : {}", f.getAbsolutePath(), e.getMessage());
80 this.fileObserver = new ConfigFileObserver(f.getAbsolutePath(), FILE_POLL_INTERVAL_MS);
81 this.fileObserver.start();
82 this.fileObserver.registerConfigChangedListener(this);
85 public ConfigurationFileRepresentation(String configurationfile) {
86 this(new File(configurationfile));
88 // end of constructors
90 // getters and setters
91 public synchronized Optional<Section> getSection(String name) {
92 return Optional.ofNullable(sections.get(name));
94 // end of getters and setters
97 private synchronized void reLoad() {
99 addSection(SECTIONNAME_ROOT);
103 private synchronized void load() {
104 LOG.debug("loading file {}", getMFileName());
105 String curSectionName = SECTIONNAME_ROOT;
106 Optional<Section> sectionOptional = this.getSection(curSectionName);
107 Section curSection = sectionOptional.isPresent() ? sectionOptional.get() : this.addSection(curSectionName);
108 BufferedReader br = null;
110 br = new BufferedReader(new FileReader(this.mFile));
111 for (String line; (line = br.readLine()) != null;) {
113 if (line.isEmpty()) {
116 if (line.startsWith("[") && line.endsWith("]")) {
117 curSectionName = line.substring(1, line.length() - 1);
118 curSection = this.addSection(curSectionName);
120 curSection.addLine(line);
124 } catch (Exception e) {
125 LOG.info("Problem loading configuration file. {} {}", getMFileName(), e);
131 } catch (IOException e) {
134 LOG.debug("finished loading file");
135 LOG.debug("start parsing sections");
136 for (Section section : this.sections.values()) {
137 section.parseLines();
139 LOG.debug("finished parsing " + this.sections.size() + " sections");
142 private String getMFileName() {
143 return mFile.getAbsolutePath();
146 // end of private methods
149 public synchronized Section addSection(String name) {
150 if (this.sections.containsKey(name)) {
151 return this.sections.get(name);
153 Section s = new Section(name);
154 this.sections.put(name, s);
158 public synchronized void save() {
159 LOG.debug("Write configuration to {}", getMFileName());
160 try (BufferedWriter bw = new BufferedWriter(new FileWriter(this.mFile, false))) {
161 for (Section section : this.sections.values()) {
162 if (section.hasValues()) {
163 bw.write(String.join(LR, section.toLines()) + LR + LR);
167 } catch (Exception e) {
168 LOG.warn("problem saving value: " + e.getMessage());
172 public void registerConfigChangedListener(IConfigChangedListener l) {
173 this.fileObserver.registerConfigChangedListener(l);
176 public void unregisterConfigChangedListener(IConfigChangedListener l) {
177 this.fileObserver.unregisterConfigChangedListener(l);
181 public void onConfigChanged() {
182 LOG.debug("Reload on change {}", getMFileName());
187 public String toString() {
188 return "ConfigurationFileRepresentation [mFile=" + mFile + ", sections=" + sections + "]";
192 protected void finalize() throws Throwable {
193 if (this.fileObserver != null) {
194 this.fileObserver.interrupt();
200 * Property access set/get
202 public synchronized void setProperty(String section, String key, Object value) {
203 Optional<Section> os = this.getSection(section);
204 if (os.isPresent()) {
205 os.get().setProperty(key, value == null ? "null" : value.toString());
208 LOG.info("Unknown configuration section {}", section);
212 public synchronized String getProperty(String section, String propertyKey) {
213 Optional<Section> os = this.getSection(section);
214 if (os.isPresent()) {
215 return os.get().getProperty(propertyKey);
217 LOG.debug("Unknown configuration section {}", section);
222 public synchronized Optional<Long> getPropertyLong(String section, String propertyKey) {
223 Optional<Section> os = this.getSection(section);
224 if (os.isPresent()) {
225 return os.get().getLong(propertyKey);
227 LOG.debug("Unknown configuration section {}", section);
228 return Optional.empty();
232 public synchronized boolean isPropertyAvailable(String section, String propertyKey) {
233 Optional<Section> s = this.getSection(section);
234 return s.isPresent() && s.get().hasKey(propertyKey);
237 public synchronized void setPropertyIfNotAvailable(String section, String propertyKey, Object propertyValue) {
238 if (!isPropertyAvailable(section, propertyKey)) {
239 setProperty(section, propertyKey, propertyValue.toString());
243 public synchronized boolean getPropertyBoolean(String section, String propertyKey) {
244 return getProperty(section, propertyKey).equalsIgnoreCase("true");
246 // end of public methods