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;
16  
17  import static com.google.common.base.Preconditions.checkNotNull;
18  import static com.google.common.base.Preconditions.checkState;
19  
20  import org.basepom.mojo.propertyhelper.beans.NumberDefinition;
21  
22  import java.io.IOException;
23  import java.util.List;
24  import java.util.Optional;
25  import java.util.regex.Matcher;
26  import java.util.regex.Pattern;
27  
28  import com.google.common.base.Joiner;
29  import com.google.common.collect.Lists;
30  
31  public class NumberField
32          implements PropertyElement {
33  
34      private static final Pattern MATCH_GROUPS = Pattern.compile("\\d+|\\D+");
35  
36      private final NumberDefinition numberDefinition;
37      private final ValueProvider valueProvider;
38  
39      private final List<String> elements = Lists.newArrayList();
40      private final List<Integer> numberElements = Lists.newArrayList();
41  
42      public NumberField(final NumberDefinition numberDefinition, final ValueProvider valueProvider) {
43          this.numberDefinition = numberDefinition;
44          this.valueProvider = valueProvider;
45      }
46  
47      public static List<NumberField> createNumbers(final ValueCache valueCache, final NumberDefinition... numberDefinitions)
48              throws IOException {
49          checkNotNull(valueCache, "valueCache is null");
50  
51          final List<NumberField> result = Lists.newArrayList();
52  
53          for (NumberDefinition numberDefinition : numberDefinitions) {
54              numberDefinition.check();
55              final ValueProvider numberValue = valueCache.getValueProvider(numberDefinition);
56              final NumberField numberField = new NumberField(numberDefinition, numberValue);
57              result.add(numberField);
58          }
59  
60          return result;
61      }
62  
63      @Override
64      public String getPropertyName() {
65          // This is not the property name (because many definitions can map onto one prop)
66          // but the actual id.
67          return numberDefinition.getId();
68      }
69  
70      @Override
71      public Optional<String> getPropertyValue() {
72          parse();
73          final String value = Joiner.on("").join(elements);
74          return numberDefinition.formatResult(value);
75      }
76  
77      @Override
78      public boolean isExport() {
79          return numberDefinition.isExport();
80      }
81  
82      private void parse() {
83          final Optional<String> value = valueProvider.getValue();
84  
85          if (value.isPresent()) {
86              final Matcher m = MATCH_GROUPS.matcher(value.get());
87              elements.clear();
88              numberElements.clear();
89  
90              while (m.find()) {
91                  final String matchValue = m.group();
92                  elements.add(matchValue);
93                  if (isNumber(matchValue)) {
94                      numberElements.add(elements.size() - 1);
95                  }
96              }
97  
98              checkState(numberElements.size() > numberDefinition.getFieldNumber(), "Only %d fields in %s, field %d requested.", numberElements.size(), value,
99                      numberDefinition.getFieldNumber());
100         }
101     }
102 
103     private boolean isNumber(final CharSequence c) {
104         for (int i = 0; i < c.length(); i++) {
105             if (!Character.isDigit(c.charAt(i))) {
106                 return false;
107             }
108         }
109         return true;
110     }
111 
112     public void increment() {
113         final Long value = getNumberValue();
114         if (value != null) {
115             setNumberValue(value + numberDefinition.getIncrement());
116         }
117     }
118 
119     public Long getNumberValue() {
120         parse();
121         return numberElements.isEmpty() ? null : Long.valueOf(elements.get(numberElements.get(numberDefinition.getFieldNumber())));
122     }
123 
124     public void setNumberValue(final Long value) {
125         parse();
126         if (!numberElements.isEmpty()) {
127             elements.set(numberElements.get(numberDefinition.getFieldNumber()), value.toString());
128             valueProvider.setValue(Joiner.on("").join(elements));
129         }
130     }
131 
132     @Override
133     public String toString() {
134         return getPropertyValue().orElse("");
135     }
136 }