View Javadoc
1   /*
2    * Licensed under the Apache License, Version 2.0 (the "License");
3    * you may not use this file except in compliance with the License.
4    * You may obtain a copy of the License at
5    *
6    * http://www.apache.org/licenses/LICENSE-2.0
7    *
8    * Unless required by applicable law or agreed to in writing, software
9    * distributed under the License is distributed on an "AS IS" BASIS,
10   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11   * See the License for the specific language governing permissions and
12   * limitations under the License.
13   */
14  
15  package org.basepom.mojo.propertyhelper.definitions;
16  
17  import static com.google.common.base.Preconditions.checkState;
18  
19  import org.basepom.mojo.propertyhelper.Field;
20  import org.basepom.mojo.propertyhelper.FieldContext;
21  import org.basepom.mojo.propertyhelper.IgnoreWarnFail;
22  import org.basepom.mojo.propertyhelper.IgnoreWarnFailCreate;
23  import org.basepom.mojo.propertyhelper.ValueCache;
24  
25  import java.io.File;
26  import java.io.IOException;
27  import java.util.List;
28  import java.util.Objects;
29  import java.util.Optional;
30  import java.util.StringJoiner;
31  import java.util.function.Function;
32  import java.util.regex.Matcher;
33  import java.util.regex.Pattern;
34  
35  import com.google.common.annotations.VisibleForTesting;
36  import com.google.common.base.Splitter;
37  
38  /**
39   * Common properties for a field.
40   */
41  public abstract class FieldDefinition<T> {
42  
43      protected FieldDefinition() {
44      }
45  
46      @VisibleForTesting
47      protected FieldDefinition(String id) {
48          this.id = id;
49      }
50  
51      /**
52       * Name of the build property to define. Field injected by Maven.
53       */
54      String id = null;
55  
56      /**
57       * <code>True</code> skips the parsing of this definition. Field injected by Maven.
58       */
59      boolean skip = false;
60  
61      /**
62       * Whether to export this number directly. Field injected by Maven.
63       */
64      boolean export = false;
65  
66      /**
67       * Name of the property from the properties file. Field injected by Maven.
68       */
69      String propertyNameInFile = null;
70  
71      /**
72       * Name of the properties file to persist the count. Field injected by Maven.
73       */
74      File propertyFile = null;
75  
76      /**
77       * What to do when the property is missing from the file.
78       */
79      private IgnoreWarnFailCreate onMissingFile = IgnoreWarnFailCreate.FAIL;
80  
81      public void setOnMissingFile(String onMissingFile) {
82          this.onMissingFile = IgnoreWarnFailCreate.forString(onMissingFile);
83      }
84  
85      /**
86       * What to do when the property is missing from the file.
87       */
88      private IgnoreWarnFailCreate onMissingFileProperty = IgnoreWarnFailCreate.FAIL;
89  
90      public void setOnMissingFileProperty(String onMissingFileProperty) {
91          this.onMissingFileProperty = IgnoreWarnFailCreate.forString(onMissingFileProperty);
92      }
93  
94      /**
95       * What to do when a referenced property can not be resolved.
96       */
97      private IgnoreWarnFail onMissingProperty = IgnoreWarnFail.FAIL;
98  
99      public void setOnMissingProperty(String onMissingProperty) {
100         this.onMissingProperty = IgnoreWarnFail.forString(onMissingProperty);
101     }
102 
103     /**
104      * The initial value for this field. Field injected by Maven.
105      */
106     String initialValue = null;
107 
108     /**
109      * Regular expression matcher. Field injected by Maven.
110      */
111     private Pattern regexp = null;
112 
113     public void setRegexp(String regexp) {
114         checkState(regexp.startsWith("^"), "regular expression must start with '^'!");
115         checkState(regexp.endsWith("$"), "regular expression must end with '$'!");
116 
117         this.regexp = Pattern.compile(regexp);
118     }
119 
120     /**
121      * Format for this element. Field injected by Maven.
122      */
123     String format = null;
124 
125     /**
126      * Comma separated list of String transformers.
127      */
128     private List<String> transformers = List.of();
129 
130     public void setTransformers(String transformers) {
131         this.transformers = Splitter.on(",")
132             .omitEmptyStrings()
133             .trimResults()
134             .splitToList(transformers);
135     }
136 
137     public abstract <U extends Field<?, ?>> U createField(FieldContext context, ValueCache valueCache) throws IOException;
138 
139     public String getId() {
140         return id;
141     }
142 
143     public boolean isSkip() {
144         return skip;
145     }
146 
147     public List<String> getTransformers() {
148         return transformers;
149     }
150 
151     public Optional<String> getInitialValue() {
152         return Optional.ofNullable(initialValue);
153     }
154 
155     public boolean isExport() {
156         return export;
157     }
158 
159     public String getPropertyNameInFile() {
160         return Objects.requireNonNullElse(propertyNameInFile, id);
161     }
162 
163     public Optional<File> getPropertyFile() {
164         return Optional.ofNullable(propertyFile);
165     }
166 
167     public IgnoreWarnFailCreate getOnMissingFile() {
168         return onMissingFile;
169     }
170 
171     public IgnoreWarnFailCreate getOnMissingFileProperty() {
172         return onMissingFileProperty;
173     }
174 
175     public IgnoreWarnFail getOnMissingProperty() {
176         return onMissingProperty;
177     }
178 
179     public Function<String, String> getRegexp() {
180         return regexp == null ? Function.identity() : v -> {
181             Matcher matcher = regexp.matcher(v);
182             return matcher.matches() ? matcher.group(1) : "";
183         };
184     }
185 
186     public Function<T, String> getPreFormat() {
187         return v -> v == null ? "" : String.valueOf(v);
188     }
189 
190     public Function<String, String> getPostFormat() {
191         return format == null ? String::valueOf : v -> String.format(format, v);
192     }
193 
194     public void check() {
195         checkState(id != null, "the id element must not be empty!");
196 
197         if (propertyNameInFile != null) {
198             checkState(propertyFile != null, "can not define <propertyNameInFile> without defining <propertyFile>!");
199         }
200     }
201 
202     @Override
203     public String toString() {
204         return new StringJoiner(", ", FieldDefinition.class.getSimpleName() + "[", "]")
205             .add("id='" + id + "'")
206             .add("skip=" + skip)
207             .add("export=" + export)
208             .add("propertyNameInFile='" + propertyNameInFile + "'")
209             .add("propertyFile=" + propertyFile)
210             .add("onMissingFile=" + onMissingFile)
211             .add("onMissingFileProperty=" + onMissingFileProperty)
212             .add("onMissingProperty=" + onMissingProperty)
213             .add("initialValue='" + initialValue + "'")
214             .add("format='" + format + "'")
215             .add("transformers=" + transformers)
216             .toString();
217     }
218 
219     @Override
220     public boolean equals(Object o) {
221         if (this == o) {
222             return true;
223         }
224         if (o == null || getClass() != o.getClass()) {
225             return false;
226         }
227         FieldDefinition<?> that = (FieldDefinition<?>) o;
228         return skip == that.skip && export == that.export && Objects.equals(id, that.id) && Objects.equals(propertyNameInFile,
229             that.propertyNameInFile) && Objects.equals(propertyFile, that.propertyFile) && onMissingFile == that.onMissingFile
230             && onMissingFileProperty == that.onMissingFileProperty && onMissingProperty == that.onMissingProperty && Objects.equals(initialValue,
231             that.initialValue) && Objects.equals(format, that.format) && Objects.equals(transformers, that.transformers);
232     }
233 
234     @Override
235     public int hashCode() {
236         return Objects.hash(id, skip, export, propertyNameInFile, propertyFile, onMissingFile, onMissingFileProperty, onMissingProperty, initialValue, format,
237             transformers);
238     }
239 }