001/* 002 * Licensed under the Apache License, Version 2.0 (the "License"); 003 * you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at 005 * 006 * http://www.apache.org/licenses/LICENSE-2.0 007 * 008 * Unless required by applicable law or agreed to in writing, software 009 * distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and 012 * limitations under the License. 013 */ 014 015package org.basepom.mojo.propertyhelper.definitions; 016 017import static com.google.common.base.Preconditions.checkState; 018 019import org.basepom.mojo.propertyhelper.Field; 020import org.basepom.mojo.propertyhelper.FieldContext; 021import org.basepom.mojo.propertyhelper.IgnoreWarnFail; 022import org.basepom.mojo.propertyhelper.IgnoreWarnFailCreate; 023import org.basepom.mojo.propertyhelper.ValueCache; 024 025import java.io.File; 026import java.io.IOException; 027import java.util.List; 028import java.util.Objects; 029import java.util.Optional; 030import java.util.StringJoiner; 031import java.util.function.Function; 032import java.util.regex.Matcher; 033import java.util.regex.Pattern; 034 035import com.google.common.annotations.VisibleForTesting; 036import com.google.common.base.Splitter; 037 038/** 039 * Common properties for a field. 040 */ 041public abstract class FieldDefinition<T> { 042 043 protected FieldDefinition() { 044 } 045 046 @VisibleForTesting 047 protected FieldDefinition(String id) { 048 this.id = id; 049 } 050 051 /** 052 * Name of the build property to define. Field injected by Maven. 053 */ 054 String id = null; 055 056 /** 057 * <code>True</code> skips the parsing of this definition. Field injected by Maven. 058 */ 059 boolean skip = false; 060 061 /** 062 * Whether to export this number directly. Field injected by Maven. 063 */ 064 boolean export = false; 065 066 /** 067 * Name of the property from the properties file. Field injected by Maven. 068 */ 069 String propertyNameInFile = null; 070 071 /** 072 * Name of the properties file to persist the count. Field injected by Maven. 073 */ 074 File propertyFile = null; 075 076 /** 077 * What to do when the property is missing from the file. 078 */ 079 private IgnoreWarnFailCreate onMissingFile = IgnoreWarnFailCreate.FAIL; 080 081 public void setOnMissingFile(String onMissingFile) { 082 this.onMissingFile = IgnoreWarnFailCreate.forString(onMissingFile); 083 } 084 085 /** 086 * What to do when the property is missing from the file. 087 */ 088 private IgnoreWarnFailCreate onMissingFileProperty = IgnoreWarnFailCreate.FAIL; 089 090 public void setOnMissingFileProperty(String onMissingFileProperty) { 091 this.onMissingFileProperty = IgnoreWarnFailCreate.forString(onMissingFileProperty); 092 } 093 094 /** 095 * What to do when a referenced property can not be resolved. 096 */ 097 private IgnoreWarnFail onMissingProperty = IgnoreWarnFail.FAIL; 098 099 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}