001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.config.event;
014
015import static org.apache.juneau.common.internal.StringUtils.*;
016import static org.apache.juneau.config.event.ConfigEventType.*;
017
018import java.util.*;
019
020import org.apache.juneau.common.internal.*;
021
022/**
023 * Represents a change to a config.
024 */
025public class ConfigEvent {
026
027   private final ConfigEventType type;
028   private final String config, section, key, value, comment;
029   private final List<String> preLines;
030   private final String modifiers;
031
032   private ConfigEvent(ConfigEventType type, String config, String section, String key, String value, String modifiers, String comment, List<String> preLines) {
033      this.type = type;
034      this.config = config;
035      this.section = section;
036      this.key = key;
037      this.value = value;
038      this.comment = comment;
039      this.preLines = preLines;
040      this.modifiers = modifiers;
041   }
042
043   //---------------------------------------------------------------------------------------------
044   // Static
045   //---------------------------------------------------------------------------------------------
046
047   /**
048    * Sets or replaces a value in a configuration.
049    *
050    * @param config
051    *    The configuration name.
052    * @param section
053    *    The section name.
054    *    <br>Must not be <jk>null</jk>.
055    * @param key
056    *    The entry name.
057    *    <br>Must not be <jk>null</jk>.
058    * @param value
059    *    The entry value.
060    *    <br>Can be <jk>null</jk> to remove an entry.
061    * @param comment
062    *    Optional comment string to add on the same line as the entry.
063    * @param modifiers
064    *    Optional entry modifiers.
065    * @param prelines
066    *    Comment lines that occur before this entry.
067    *    <br>Must not be <jk>null</jk>.
068    * @return
069    *    A new {@link ConfigEvent} object.
070    */
071   public static ConfigEvent setEntry(String config, String section, String key, String value, String modifiers, String comment, List<String> prelines) {
072      return new ConfigEvent(SET_ENTRY, config, section, key, value, modifiers, comment, prelines);
073   }
074
075   /**
076    * Removes a value from a configuration.
077    *
078    * @param config
079    *    The configuration name.
080    * @param section
081    *    The section name.
082    *    <br>Must not be <jk>null</jk>.
083    * @param key
084    *    The entry name.
085    *    <br>Must not be <jk>null</jk>.
086    * @return
087    *    A new {@link ConfigEvent} object.
088    */
089   public static ConfigEvent removeEntry(String config, String section, String key) {
090      return new ConfigEvent(REMOVE_ENTRY, config, section, key, null, null, null, null);
091   }
092
093   /**
094    * Adds a new empty section to the config.
095    *
096    * @param config
097    *    The configuration name.
098    * @param section
099    *    The section name.
100    * @param prelines
101    *    Comment lines that occur before this section.
102    *    <br>Must not be <jk>null</jk>.
103    * @return
104    *    A new {@link ConfigEvent} object.
105    */
106   public static ConfigEvent setSection(String config, String section, List<String> prelines) {
107      return new ConfigEvent(SET_SECTION, config, section, null, null, null, null, prelines);
108   }
109
110   /**
111    * Removes a section from the config.
112    *
113    * @param config
114    *    The configuration name.
115    * @param section
116    *    The section name.
117    * @return
118    *    A new {@link ConfigEvent} object.
119    */
120   public static ConfigEvent removeSection(String config, String section) {
121      return new ConfigEvent(REMOVE_SECTION, config, section, null, null, null, null, null);
122   }
123
124
125   //---------------------------------------------------------------------------------------------
126   // Instance
127   //---------------------------------------------------------------------------------------------
128
129   /**
130    * Returns the event type.
131    *
132    * @return The event type.
133    */
134   public ConfigEventType getType() {
135      return type;
136   }
137
138   /**
139    * Returns the configuration name.
140    *
141    * @return The configuration name.
142    */
143   public String getConfig() {
144      return config;
145   }
146
147   /**
148    * Returns the section name.
149    *
150    * @return The section name.
151    */
152   public String getSection() {
153      return section;
154   }
155
156   /**
157    * Returns the entry name.
158    *
159    * @return The entry name.
160    */
161   public String getKey() {
162      return key;
163   }
164
165   /**
166    * Returns the entry value.
167    *
168    * @return The entry value.
169    */
170   public String getValue() {
171      return value;
172   }
173
174   /**
175    * Returns the entry comment.
176    *
177    * @return The entry comment.
178    */
179   public String getComment() {
180      return comment;
181   }
182
183   /**
184    * Returns the section or entry lines.
185    *
186    * @return The section or entry lines.
187    */
188   public List<String> getPreLines() {
189      return preLines;
190   }
191
192   /**
193    * Returns the modifiers on this entry.
194    *
195    * @return
196    *    The modifier characters.
197    *    <br>Never <jk>null</jk>.
198    */
199   public String getModifiers() {
200      return modifiers;
201   }
202
203   @Override /* Object */
204   public String toString() {
205      switch(type) {
206         case REMOVE_SECTION:
207            return "REMOVE_SECTION("+section+")";
208         case REMOVE_ENTRY:
209            return "REMOVE_ENTRY("+section+(section.isEmpty() ? "" : "/")+key+")";
210         case SET_SECTION:
211            return "SET_SECTION("+section+", preLines="+StringUtils.join(preLines, '|')+")";
212         case SET_ENTRY:
213            StringBuilder out = new StringBuilder("SET(");
214            out.append(section+(section.isEmpty() ? "" : "/") + key);
215            if (modifiers != null)
216               out.append(modifiers);
217            out.append(" = ");
218            String val = value == null ? "null" : value;
219            if (val.indexOf('\n') != -1)
220               val = val.replaceAll("(\\r?\\n)", "$1\t");
221            if (val.indexOf('#') != -1)
222               val = val.replaceAll("#", "\\\\#");
223            out.append(val);
224            if (isNotEmpty(comment))
225               out.append(" # ").append(comment);
226            out.append(')');
227            return out.toString();
228         default:
229            return null;
230      }
231   }
232}