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.internal.StringUtils.*;
016import static org.apache.juneau.config.event.ConfigEventType.*;
017
018import java.util.*;
019
020import org.apache.juneau.annotation.*;
021import org.apache.juneau.internal.*;
022
023/**
024 * Represents a change to a config.
025 */
026@BeanIgnore
027public class ConfigEvent {
028
029   private final ConfigEventType type;
030   private final String config, section, key, value, comment;
031   private final List<String> preLines;
032   private final String modifiers;
033
034   private ConfigEvent(ConfigEventType type, String config, String section, String key, String value, String modifiers, String comment, List<String> preLines) {
035      this.type = type;
036      this.config = config;
037      this.section = section;
038      this.key = key;
039      this.value = value;
040      this.comment = comment;
041      this.preLines = preLines;
042      this.modifiers = modifiers;
043   }
044
045   //---------------------------------------------------------------------------------------------
046   // Static creators.
047   //---------------------------------------------------------------------------------------------
048
049   /**
050    * Sets or replaces a value in a configuration.
051    *
052    * @param config
053    *    The configuration name.
054    * @param section
055    *    The section name.
056    *    <br>Must not be <jk>null</jk>.
057    * @param key
058    *    The entry name.
059    *    <br>Must not be <jk>null</jk>.
060    * @param value
061    *    The entry value.
062    *    <br>Can be <jk>null</jk> to remove an entry.
063    * @param comment
064    *    Optional comment string to add on the same line as the entry.
065    * @param modifiers
066    *    Optional entry modifiers.
067    * @param prelines
068    *    Comment lines that occur before this entry.
069    *    <br>Must not be <jk>null</jk>.
070    * @return
071    *    A new {@link ConfigEvent} object.
072    */
073   public static ConfigEvent setEntry(String config, String section, String key, String value, String modifiers, String comment, List<String> prelines) {
074      return new ConfigEvent(SET_ENTRY, config, section, key, value, modifiers, comment, prelines);
075   }
076
077   /**
078    * Removes a value from a configuration.
079    *
080    * @param config
081    *    The configuration name.
082    * @param section
083    *    The section name.
084    *    <br>Must not be <jk>null</jk>.
085    * @param key
086    *    The entry name.
087    *    <br>Must not be <jk>null</jk>.
088    * @return
089    *    A new {@link ConfigEvent} object.
090    */
091   public static ConfigEvent removeEntry(String config, String section, String key) {
092      return new ConfigEvent(REMOVE_ENTRY, config, section, key, null, null, null, null);
093   }
094
095   /**
096    * Adds a new empty section to the config.
097    *
098    * @param config
099    *    The configuration name.
100    * @param section
101    *    The section name.
102    * @param prelines
103    *    Comment lines that occur before this section.
104    *    <br>Must not be <jk>null</jk>.
105    * @return
106    *    A new {@link ConfigEvent} object.
107    */
108   public static ConfigEvent setSection(String config, String section, List<String> prelines) {
109      return new ConfigEvent(SET_SECTION, config, section, null, null, null, null, prelines);
110   }
111
112   /**
113    * Removes a section from the config.
114    *
115    * @param config
116    *    The configuration name.
117    * @param section
118    *    The section name.
119    * @return
120    *    A new {@link ConfigEvent} object.
121    */
122   public static ConfigEvent removeSection(String config, String section) {
123      return new ConfigEvent(REMOVE_SECTION, config, section, null, null, null, null, null);
124   }
125
126
127   //---------------------------------------------------------------------------------------------
128   // Instance methods.
129   //---------------------------------------------------------------------------------------------
130
131   /**
132    * Returns the event type.
133    *
134    * @return The event type.
135    */
136   public ConfigEventType getType() {
137      return type;
138   }
139
140   /**
141    * Returns the configuration name.
142    *
143    * @return The configuration name.
144    */
145   public String getConfig() {
146      return config;
147   }
148
149   /**
150    * Returns the section name.
151    *
152    * @return The section name.
153    */
154   public String getSection() {
155      return section;
156   }
157
158   /**
159    * Returns the entry name.
160    *
161    * @return The entry name.
162    */
163   public String getKey() {
164      return key;
165   }
166
167   /**
168    * Returns the entry value.
169    *
170    * @return The entry value.
171    */
172   public String getValue() {
173      return value;
174   }
175
176   /**
177    * Returns the entry comment.
178    *
179    * @return The entry comment.
180    */
181   public String getComment() {
182      return comment;
183   }
184
185   /**
186    * Returns the section or entry lines.
187    *
188    * @return The section or entry lines.
189    */
190   public List<String> getPreLines() {
191      return preLines;
192   }
193
194   /**
195    * Returns the modifiers on this entry.
196    *
197    * @return
198    *    The modifier characters.
199    *    <br>Never <jk>null</jk>.
200    */
201   public String getModifiers() {
202      return modifiers;
203   }
204
205   @Override /* Object */
206   public String toString() {
207      switch(type) {
208         case REMOVE_SECTION:
209            return "REMOVE_SECTION("+section+")";
210         case REMOVE_ENTRY:
211            return "REMOVE_ENTRY("+section+(section.isEmpty() ? "" : "/")+key+")";
212         case SET_SECTION:
213            return "SET_SECTION("+section+", preLines="+StringUtils.join(preLines, '|')+")";
214         case SET_ENTRY:
215            StringBuilder out = new StringBuilder("SET(");
216            out.append(section+(section.isEmpty() ? "" : "/") + key);
217            if (modifiers != null)
218               out.append(modifiers);
219            out.append(" = ");
220            String val = value == null ? "null" : value;
221            if (val.indexOf('\n') != -1)
222               val = val.replaceAll("(\\r?\\n)", "$1\t");
223            if (val.indexOf('#') != -1)
224               val = val.replaceAll("#", "\\\\#");
225            out.append(val);
226            if (isNotEmpty(comment))
227               out.append(" # ").append(comment);
228            out.append(')');
229            return out.toString();
230         default:
231            return null;
232      }
233   }
234}