View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.jexl3.jexl342;
18  
19  import java.lang.ref.Reference;
20  import java.math.BigDecimal;
21  import java.math.BigInteger;
22  import java.util.Optional;
23  import java.util.concurrent.atomic.AtomicReference;
24  
25  import org.apache.commons.jexl3.JexlArithmetic;
26  
27  /**
28   * Unwraps Optional/Reference/AtomicReference on public and key methods.
29   */
30  public class OptionalArithmetic extends JexlArithmetic {
31      public OptionalArithmetic(final boolean astrict) {
32          super(astrict);
33      }
34  
35      @Override
36      public Object add(final Object lhs, final Object rhs) {
37          return super.add(star(lhs), star(rhs));
38      }
39  
40      @Override
41      public Object and(final Object left, final Object right) { return super.and(star(left), star(right)); }
42      @Override
43      public ArrayBuilder arrayBuilder(final int size, final boolean extended) {
44          return new org.apache.commons.jexl3.internal.ArrayBuilder(size, extended) {
45              @Override
46              public void add(final Object value) {
47                  super.add(star(value));
48              }
49          };
50      }
51  
52      @Override
53      public Object complement(final Object o) {
54          return super.complement(star(o));
55      }
56  
57      @Override
58      public Boolean contains(final Object lhs, final Object rhs) {
59          return super.contains(star(lhs), star(rhs));
60      }
61  
62      @Override
63      public Object controlReturn(final Object returned) {
64          return star(returned);
65      }
66  
67      @Override
68      public Object divide(final Object lhs, final Object rhs) {
69          return super.divide(star(lhs), star(rhs));
70      }
71  
72      @Override
73      public Boolean empty(final Object o) {
74          return super.empty(star(o));
75      }
76  
77      @Override
78      public Boolean endsWith(final Object left, final Object right) {
79          return super.endsWith(star(left), star(right));
80      }
81  
82      @Override
83      public boolean equals(final Object left, final Object right) {
84          return equals(star(left), star(right));
85      }
86  
87      @Override
88      public boolean greaterThan(final Object left, final Object right) {
89          return greaterThan(star(left), star(right));
90      }
91  
92      @Override
93      public boolean greaterThanOrEqual(final Object left, final Object right) {
94          return greaterThanOrEqual(star(left), star(right));
95      }
96  
97      @Override
98      public Boolean isEmpty(final Object object, final Boolean def) {
99          return super.isEmpty(star(object), def);
100     }
101 
102     @Override
103     protected boolean isNullOperand(final Object val) {
104         return super.isNullOperand(star(val));
105     }
106 
107     @Override
108     public boolean lessThan(final Object left, final Object right) {
109         return lessThan(star(left), star(right));
110     }
111 
112     @Override
113     public boolean lessThanOrEqual(final Object left, final Object right) {
114         return lessThanOrEqual(star(left), star(right));
115     }
116 
117     @Override
118     public MapBuilder mapBuilder(final int size, final boolean extended) {
119         return new org.apache.commons.jexl3.internal.MapBuilder(size, extended) {
120             @Override
121             public void put(final Object key, final Object value) {
122                 super.put(key, star(value));
123             }
124         };
125     }
126 
127     @Override
128     public Object mod(final Object lhs, final Object rhs) {
129         return super.mod(star(lhs), star(rhs));
130     }
131 
132     @Override
133     public Object multiply(final Object lhs, final Object rhs) {
134         return super.multiply(star(lhs), star(rhs));
135     }
136 
137     @Override
138     public boolean narrowArguments(final Object[] args) {
139         boolean narrowed = false;
140         if (args != null) {
141             for (int a = 0; a < args.length; ++a) {
142                 final Object arg = args[a];
143                 final Object sarg = star(arg);
144                 if (sarg != arg) {
145                     narrowed = true;
146                 }
147                 if (arg instanceof Number) {
148                     final Number narg = (Number) arg;
149                     final Number narrow = narrow(narg);
150                     if (!narg.equals(narrow)) {
151                         args[a] = narrow;
152                         narrowed = true;
153                     }
154                 }
155             }
156         }
157         return narrowed;
158     }
159 
160     @Override
161     public Object negate(final Object o) {
162         return super.negate(star(o));
163     }
164 
165     @Override
166     public Object or(final Object left, final Object right) { return super.or(star(left), star(right)); }
167 
168     @Override
169     public Object positivize(final Object o) {
170         return super.positivize(star(o));
171     }
172 
173     @Override
174     public SetBuilder setBuilder(final int size, final boolean extended) {
175         return new org.apache.commons.jexl3.internal.SetBuilder(size, extended) {
176             @Override
177             public void add(final Object value) {
178                 super.add(star(value));
179             }
180         };
181     }
182 
183     @Override
184     public Object shiftLeft(final Object left, final Object right) { return super.shiftLeft(star(left), star(right)); }
185 
186     @Override
187     public Object shiftRight(final Object left, final Object right) { return super.shiftRight(star(left), star(right)); }
188 
189     @Override
190     public Object shiftRightUnsigned(final Object left, final Object right) { return super.shiftRightUnsigned(star(left), star(right)); }
191 
192     @Override
193     public Integer size(final Object object, final Integer def) {
194         return super.size(star(object), def);
195     }
196 
197     /**
198      * Dereferences an Optional, a Reference or an AtomicReference, leave other as is.
199      * @param ref the reference
200      * @return the referenced object
201      */
202     protected Object star(final Object ref) {
203         if (ref instanceof Optional<?>) {
204             final Optional<?> o = (Optional<?>) ref;
205             return o.orElse(null);
206         }
207         if (ref instanceof Reference<?>) {
208             final Optional<?> r = (Optional<?>) ref;
209             return r.get();
210         }
211         if (ref instanceof AtomicReference<?>) {
212             final AtomicReference<?> r = (AtomicReference<?>) ref;
213             return r.get();
214         }
215         return ref;
216     }
217 
218     @Override
219     public Boolean startsWith(final Object left, final Object right) {
220         return super.startsWith(star(left), star(right));
221     }
222 
223     @Override
224     public Object subtract(final Object lhs, final Object rhs) {
225         return super.subtract(star(lhs), star(rhs));
226     }
227 
228     @Override
229     public BigDecimal toBigDecimal(final Object val) {
230         return super.toBigDecimal(star(val));
231     }
232 
233     @Override
234     public BigInteger toBigInteger(final Object val) {
235         return super.toBigInteger(star(val));
236     }
237 
238     @Override
239     public boolean toBoolean(final Object val) {
240         return super.toBoolean(star(val));
241     }
242 
243     @Override
244     public double toDouble(final Object val) {
245         return super.toDouble(star(val));
246     }
247 
248     @Override
249     public int toInteger(final Object val) {
250         return super.toInteger(star(val));
251     }
252 
253     @Override
254     public long toLong(final Object val) {
255         return super.toLong(star(val));
256     }
257 
258     @Override
259     public String toString(final Object val) {
260         return super.toString(star(val));
261     }
262 
263     @Override
264     public Object xor(final Object left, final Object right) { return super.xor(star(left), star(right)); }
265 }