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 {
46 private static final Logger LOG = LoggerFactory.getLogger(ConfigurationFileRepresentation.class);
48 private static final long FILE_POLL_INTERVAL_MS = 1000;
49 private static final String SECTIONNAME_ROOT = "";
50 private static final String LR = "\n";
51 private static final String EMPTY = "";
53 /** Related configuration file **/
54 private final File mFile;
55 /** Monitor changes of file **/
56 private final ConfigFileObserver fileObserver;
57 /** List of sections **/
58 private final HashMap<String, Section> sections;
60 public ConfigurationFileRepresentation(File f) {
63 this.sections = new HashMap<String, Section>();
65 if (!this.mFile.exists()) {
66 if (!this.mFile.createNewFile()) {
67 LOG.error("Can not create file {}", f.getAbsolutePath());
72 } catch (IOException e) {
73 LOG.error("Problem loading config file {} : {}", f.getAbsolutePath(), e.getMessage());
75 this.fileObserver = new ConfigFileObserver(f.getAbsolutePath(), FILE_POLL_INTERVAL_MS);
76 this.fileObserver.start();
77 this.fileObserver.registerConfigChangedListener(this);
80 public ConfigurationFileRepresentation(String configurationfile) {
81 this(new File(configurationfile));
84 public synchronized Optional<Section> getSection(String name) {
85 return Optional.ofNullable(sections.get(name));
88 public synchronized Section addSection(String name) {
89 if (this.sections.containsKey(name)) {
90 return this.sections.get(name);
92 Section s = new Section(name);
93 this.sections.put(name, s);
97 private synchronized void reLoad() {
99 addSection(SECTIONNAME_ROOT);
103 public synchronized void save() {
104 LOG.debug("Write configuration to {}", getMFileName());
105 try (BufferedWriter bw = new BufferedWriter(new FileWriter(this.mFile, false))) {
106 for (Section section : this.sections.values()) {
107 if (section.hasValues()) {
108 bw.write(String.join(LR, section.toLines()) + LR + LR);
112 } catch (Exception e) {
113 LOG.warn("problem saving value: " + e.getMessage());
117 public void registerConfigChangedListener(IConfigChangedListener l) {
118 this.fileObserver.registerConfigChangedListener(l);
121 public void unregisterConfigChangedListener(IConfigChangedListener l) {
122 this.fileObserver.unregisterConfigChangedListener(l);
126 public void onConfigChanged() {
127 LOG.debug("Reload on change {}", getMFileName());
132 public String toString() {
133 return "ConfigurationFileRepresentation [mFile=" + mFile + ", sections=" + sections + "]";
137 protected void finalize() throws Throwable {
138 if (this.fileObserver != null) {
139 this.fileObserver.interrupt();
145 * Property access set/get
147 public synchronized void setProperty(String section, String key, Object value) {
148 Optional<Section> os = this.getSection(section);
149 if (os.isPresent()) {
150 os.get().setProperty(key, value == null ? "null" : value.toString());
153 LOG.info("Unknown configuration section {}", section);
157 public synchronized String getProperty(String section, String propertyKey) {
158 Optional<Section> os = this.getSection(section);
159 if (os.isPresent()) {
160 return os.get().getProperty(propertyKey);
162 LOG.debug("Unknown configuration section {}", section);
167 public synchronized Optional<Long> getPropertyLong(String section, String propertyKey) {
168 Optional<Section> os = this.getSection(section);
169 if (os.isPresent()) {
170 return os.get().getLong(propertyKey);
172 LOG.debug("Unknown configuration section {}", section);
173 return Optional.empty();
177 public synchronized boolean isPropertyAvailable(String section, String propertyKey) {
178 Optional<Section> s = this.getSection(section);
179 return s.isPresent() && s.get().hasKey(propertyKey);
182 public synchronized void setPropertyIfNotAvailable(String section, String propertyKey, Object propertyValue) {
183 if (!isPropertyAvailable(section, propertyKey)) {
184 setProperty(section, propertyKey, propertyValue.toString());
188 public synchronized boolean getPropertyBoolean(String section, String propertyKey) {
189 return getProperty(section, propertyKey).equalsIgnoreCase("true");
195 private synchronized void load() {
196 LOG.debug("loading file {}", getMFileName());
197 String curSectionName = SECTIONNAME_ROOT;
198 Optional<Section> sectionOptional = this.getSection(curSectionName);
199 Section curSection = sectionOptional.isPresent() ? sectionOptional.get() : this.addSection(curSectionName);
200 BufferedReader br = null;
202 br = new BufferedReader(new FileReader(this.mFile));
203 for (String line; (line = br.readLine()) != null;) {
205 if (line.isEmpty()) {
208 if (line.startsWith("[") && line.endsWith("]")) {
209 curSectionName = line.substring(1, line.length() - 1);
210 curSection = this.addSection(curSectionName);
212 curSection.addLine(line);
216 } catch (Exception e) {
217 LOG.info("Problem loading configuration file. {} {}", getMFileName(), e);
223 } catch (IOException e) {
226 LOG.debug("finished loading file");
227 LOG.debug("start parsing sections");
228 for (Section section : this.sections.values()) {
229 section.parseLines();
231 LOG.debug("finished parsing " + this.sections.size() + " sections");
234 private String getMFileName() {
235 return mFile.getAbsolutePath();