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