1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements.  See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership.  The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License.  You may obtain a copy of the License at
10 *
11 *   http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied.  See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21 
22 package org.apache.openoffice.ooxml.schema.simple;
23 
24 import java.util.Map;
25 import java.util.Vector;
26 
27 import org.apache.openoffice.ooxml.schema.misc.Log;
28 import org.apache.openoffice.ooxml.schema.model.simple.BuiltInType;
29 import org.apache.openoffice.ooxml.schema.model.simple.Restriction;
30 
31 public class NumberNode<T extends Comparable<T>>
32     implements ISimpleTypeNode
33 {
NumberNode(final BuiltInType eType)34     NumberNode (final BuiltInType eType)
35     {
36         meType = eType;
37         mbIsList = false;
38     }
39 
40 
41 
42 
GetNumberType()43     public BuiltInType GetNumberType ()
44     {
45         return meType;
46     }
47 
48 
49 
50 
ParseString(final String sValue)51     T ParseString (final String sValue)
52     {
53         switch(meType)
54         {
55             case Float:
56                 return (T)(Float)Float.parseFloat(sValue);
57 
58             case Double:
59                 return (T)(Double)Double.parseDouble(sValue);
60 
61             case Byte:
62                 return (T)(Byte)Byte.parseByte(sValue);
63 
64             case Int:
65             case UnsignedShort:
66                 return (T)(Integer)Integer.parseInt(sValue);
67 
68             case Short:
69             case UnsignedByte:
70                 return (T)(Short)Short.parseShort(sValue);
71 
72             case Long:
73             case UnsignedInt:
74             case Integer:
75                 return (T)(Long)Long.parseLong(sValue);
76 
77             default:
78                 throw new RuntimeException("unsupported type "+meType);
79         }
80     }
81 
82 
83 
84 
85     @Override
ApplyRestriction( final Restriction aNode, final Map<String,Integer> aValueToIdMap)86     public void ApplyRestriction (
87         final Restriction aNode,
88         final Map<String,Integer> aValueToIdMap)
89     {
90         if (aNode.HasFeature(Restriction.MinExclusiveBit))
91             ApplyMinimum(ParseString(aNode.GetMinExclusive()), false);
92         if (aNode.HasFeature(Restriction.MinInclusiveBit))
93             ApplyMinimum(ParseString(aNode.GetMinInclusive()), true);
94 
95         if (aNode.HasFeature(Restriction.MaxExclusiveBit))
96             ApplyMaximum(ParseString(aNode.GetMaxExclusive()), false);
97         if (aNode.HasFeature(Restriction.MaxInclusiveBit))
98             ApplyMaximum(ParseString(aNode.GetMaxInclusive()), true);
99 
100         if (aNode.HasFeature(Restriction.EnumerationBit))
101         {
102             final Vector<T> aValues = new Vector<>();
103             for (final String sEnumerationValue : aNode.GetEnumeration())
104                 aValues.add(ParseString(sEnumerationValue));
105             ApplyEnumeration(aValues);
106         }
107     }
108 
109 
110 
111 
112     @Override
Print(final Log aLog)113     public void Print (final Log aLog)
114     {
115         aLog.printf("%s\n", toString());
116     }
117 
118 
119 
120 
121     @Override
toString()122     public String toString ()
123     {
124         final StringBuffer sMessage = new StringBuffer();
125         sMessage.append(meType);
126         if (maEnumeration != null)
127         {
128             sMessage.append(", restricted to values");
129             for (final T nValue : maEnumeration)
130             {
131                 sMessage.append(' ');
132                 sMessage.append(nValue);
133             }
134         }
135         else if (maMinimumValue!=null || maMaximumValue!=null)
136         {
137             sMessage.append(" restricted to ");
138 
139             if (maMinimumValue != null)
140             {
141                 sMessage.append(maMinimumValue);
142                 if (mbIsMinimumInclusive)
143                     sMessage.append(" <= ");
144                 else
145                     sMessage.append(" < ");
146             }
147             sMessage.append("value");
148             if (maMaximumValue != null)
149             {
150                 if (mbIsMaximumInclusive)
151                     sMessage.append(" <= ");
152                 else
153                     sMessage.append(" < ");
154                 sMessage.append(maMaximumValue);
155             }
156         }
157         else
158             sMessage.append(", not restricted");
159 
160         return sMessage.toString();
161     }
162 
163 
164 
165 
ApplyMinimum( final T nValue, final boolean bIsInclusive)166     private void ApplyMinimum (
167         final T nValue,
168         final boolean bIsInclusive)
169     {
170         if (maEnumeration != null)
171             throw new RuntimeException("minimum can not be applied to an enumeration");
172         else if (maMinimumValue != null)
173         {
174             final int nComparison = maMinimumValue.compareTo(nValue);
175             if (nComparison > 0)
176                 throw new RuntimeException("second restriction tries to enlarge value space");
177             else if (nComparison == 0)
178                 if (mbIsMinimumInclusive && ! bIsInclusive)
179                     throw new RuntimeException("second restriction tries to enlarge value space");
180         }
181         maMinimumValue = nValue;
182         mbIsMinimumInclusive = bIsInclusive;
183     }
184 
185 
186 
187 
188 
ApplyMaximum( final T nValue, final boolean bIsInclusive)189     private void ApplyMaximum (
190         final T nValue,
191         final boolean bIsInclusive)
192     {
193         if (maEnumeration != null)
194             throw new RuntimeException("maximum can not be applied to an enumeration");
195         else if (maMaximumValue != null)
196         {
197             final int nComparison = maMaximumValue.compareTo(nValue);
198             if (nComparison < 0)
199                 throw new RuntimeException("second restriction tries to enlarge value space");
200             else if (nComparison == 0)
201                 if ( ! mbIsMaximumInclusive && bIsInclusive)
202                     throw new RuntimeException("second restriction tries to enlarge value space");
203         }
204         maMaximumValue = nValue;
205         mbIsMaximumInclusive = bIsInclusive;
206     }
207 
208 
209 
210 
ApplyEnumeration(final Vector<T> aValues)211     private void ApplyEnumeration (final Vector<T> aValues)
212     {
213         if (maEnumeration!=null || maMaximumValue!=null || maMinimumValue!=null)
214             throw new RuntimeException("can not apply enumeration to existing restriction");
215         maEnumeration = aValues;
216     }
217 
218 
219 
220 
221     @Override
IsList()222     public boolean IsList ()
223     {
224         return mbIsList;
225     }
226 
227 
228 
229 
230     @Override
SetIsList()231     public void SetIsList ()
232     {
233         mbIsList = true;
234     }
235 
236 
237 
238 
239     @Override
AcceptVisitor(final ISimpleTypeNodeVisitor aVisitor)240     public void AcceptVisitor (final ISimpleTypeNodeVisitor aVisitor)
241     {
242         aVisitor.Visit(this);
243     }
244 
245 
246     public enum RestrictionType
247     {
248         Size,
249         Enumeration,
250         None
251     }
GetRestrictionType()252     public RestrictionType GetRestrictionType ()
253     {
254         if (maEnumeration != null)
255             return RestrictionType.Enumeration;
256         else if (maMinimumValue!=null || maMaximumValue!=null)
257             return RestrictionType.Size;
258         else
259             return RestrictionType.None;
260     }
261 
262 
263 
GetEnumerationRestriction()264     public Iterable<T> GetEnumerationRestriction ()
265     {
266         return maEnumeration;
267     }
268 
269 
270 
271 
GetMinimum()272     public T GetMinimum ()
273     {
274         return maMinimumValue;
275     }
276 
277 
278 
279 
GetMaximum()280     public T GetMaximum ()
281     {
282         return maMaximumValue;
283     }
284 
285 
286 
IsMinimumInclusive()287     public boolean IsMinimumInclusive ()
288     {
289         return mbIsMinimumInclusive;
290     }
291 
292 
293 
294 
IsMaximumInclusive()295     public boolean IsMaximumInclusive ()
296     {
297         return mbIsMaximumInclusive;
298     }
299 
300 
301 
302 
303     private final BuiltInType meType;
304     private T maMinimumValue;
305     private boolean mbIsMinimumInclusive;
306     private T maMaximumValue;
307     private boolean mbIsMaximumInclusive;
308     private Vector<T> maEnumeration;
309     private boolean mbIsList;
310 }
311