001    package org.apache.myfaces.tobago.layout;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one or more
005     * contributor license agreements.  See the NOTICE file distributed with
006     * this work for additional information regarding copyright ownership.
007     * The ASF licenses this file to You under the Apache License, Version 2.0
008     * (the "License"); you may not use this file except in compliance with
009     * the License.  You may obtain a copy of the License at
010     *
011     *      http://www.apache.org/licenses/LICENSE-2.0
012     *
013     * Unless required by applicable law or agreed to in writing, software
014     * distributed under the License is distributed on an "AS IS" BASIS,
015     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016     * See the License for the specific language governing permissions and
017     * limitations under the License.
018     */
019    
020    import org.apache.commons.lang.StringUtils;
021    import org.slf4j.Logger;
022    import org.slf4j.LoggerFactory;
023    
024    import java.io.Serializable;
025    import java.util.List;
026    
027    public abstract class Measure implements Serializable {
028    
029      private static final long serialVersionUID = 1L;
030    
031      private static final Logger LOG = LoggerFactory.getLogger(Measure.class);
032    
033      public static final Measure ZERO = valueOf(0);
034      public static final Measure MAX = valueOf(Integer.MAX_VALUE);
035    
036      // todo: refactor and consolidate with LayoutToken
037      
038      public static Measure valueOf(Measure value) {
039        if (value == null) {
040          return ZERO;
041        }
042        return value;
043      }
044    
045      public static Measure valueOf(int value) {
046        return PixelMeasure.pixelValueOf(value);
047      }
048    
049      public static Measure valueOf(Integer value) {
050        if (value == null) {
051          return ZERO;
052        }
053        return valueOf(value.intValue());
054      }
055    
056      public static Measure valueOf(Number value) {
057        if (value == null) {
058          return ZERO;
059        }
060        return valueOf(value.intValue());
061      }
062    
063      public static Measure valueOf(String value) {
064        if (StringUtils.isEmpty(value)) {
065          return ZERO;
066        }
067        try {
068          if (value.endsWith("px")) {
069            return Measure.valueOf(Integer.parseInt(value.substring(0, value.length() - 2)));
070          }
071          return Measure.valueOf(Integer.parseInt(value));
072    
073        } catch (NumberFormatException e) {
074          throw new IllegalArgumentException("Can't parse to any measure: '" + value + "'", e);
075        }
076      }
077    
078      public static Measure valueOf(Object object) {
079        if (object instanceof Measure) {
080          return valueOf((Measure) object);
081        }
082        if (object instanceof Number) {
083          return valueOf((Number) object);
084        }
085        if (object instanceof String) {
086          return valueOf((String) object);
087        }
088        if (object == null) {
089          return ZERO;
090        }
091        return valueOf(object.toString());
092      }
093    
094      /**
095       * @deprecated since 1.5.0, please use valueOf()
096       */
097      @Deprecated
098      public static Measure parse(String value) {
099        return valueOf(value);
100      }
101    
102      public abstract Measure add(Measure m);
103    
104      public abstract Measure add(int m);
105    
106      public abstract Measure multiply(int times);
107    
108      public abstract Measure divide(int times);
109    
110      /**
111       * @deprecated since 1.5.0, please use subtractNotNegative
112       */
113      @Deprecated
114      public Measure substractNotNegative(Measure m) {
115        return subtractNotNegative(m);
116      }
117    
118      public abstract Measure subtractNotNegative(Measure m);
119    
120      public abstract Measure subtract(Measure m);
121    
122      public abstract Measure subtract(int m);
123    
124      public boolean greaterThan(Measure measure) {
125        return measure != null && getPixel() > measure.getPixel();
126      }
127    
128      public boolean greaterOrEqualThan(Measure measure) {
129        return measure != null && getPixel() >= measure.getPixel();
130      }
131    
132      public boolean lessThan(Measure measure) {
133        return measure != null && getPixel() < measure.getPixel();
134      }
135    
136      public boolean lessOrEqualThan(Measure measure) {
137        return measure != null && getPixel() <= measure.getPixel();
138      }
139    
140      public abstract int getPixel();
141    
142      /**
143       * Returns the maximum. If all parameters are null, than the result is {@value #ZERO}.
144       */
145      public static Measure max(List<Measure> list) {
146        Measure max = ZERO;
147        for (Measure measure : list) {
148          if (max.lessThan(measure)) {
149            max = measure;
150          }
151        }
152        return max;
153      }
154    
155      /**
156       * Returns the minimum. If all parameters are null, than the result is {@value #MAX}.
157       */
158      public static Measure min(List<Measure> list) {
159        Measure min = MAX;
160        for (Measure measure : list) {
161          if (min.greaterThan(measure)) {
162            min = measure;
163          }
164        }
165        return min;
166      }
167    
168      /**
169       * Returns the maximum. If all parameters are null, than the result is {@value #ZERO}.
170       */
171      public static Measure max(Measure m1, Measure m2) {
172        if (m1 != null) {
173          return m1.lessThan(m2) ? m2 : m1;
174        } else {
175          return m2 != null ? m2 : ZERO;
176        }
177      }
178    
179      /**
180       * Returns the minimum. If all parameters are null, than the result is {@value #MAX}.
181       */
182      public static Measure min(Measure m1, Measure m2) {
183        if (m1 != null) {
184          return m1.greaterThan(m2) ? m2 : m1;
185        } else {
186          return m2 != null ? m2 : MAX;
187        }
188      }
189    }