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