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.parser.type; 23 24 import java.util.HashSet; 25 import java.util.Set; 26 27 import org.apache.openoffice.ooxml.parser.NameMap; 28 29 public class NumberParser implements ISimpleTypeParser 30 { NumberParser(final String[] aLine)31 public NumberParser (final String[] aLine) 32 { 33 switch(aLine[5]) 34 { 35 case "u1": 36 meNumberType = NumberType.Boolean; 37 meJavaNumberType = JavaNumberType.Boolean; 38 break; 39 case "s8": 40 meNumberType = NumberType.Byte; 41 meJavaNumberType = JavaNumberType.Byte; 42 break; 43 case "u8": 44 meNumberType = NumberType.UnsignedByte; 45 meJavaNumberType = JavaNumberType.Short; 46 break; 47 case "s16": 48 meNumberType = NumberType.Short; 49 meJavaNumberType = JavaNumberType.Short; 50 break; 51 case "u16": 52 meNumberType = NumberType.UnsignedShort; 53 meJavaNumberType = JavaNumberType.Integer; 54 break; 55 case "s32": 56 meNumberType = NumberType.Int; 57 meJavaNumberType = JavaNumberType.Integer; 58 break; 59 case "u32": 60 meNumberType = NumberType.UnsignedInt; 61 meJavaNumberType = JavaNumberType.Long; 62 break; 63 case "s64": 64 meNumberType = NumberType.Long; 65 meJavaNumberType = JavaNumberType.Long; 66 break; 67 case "u64": 68 meNumberType = NumberType.UnsignedLong; 69 meJavaNumberType = JavaNumberType.Long; 70 break; 71 case "s*": 72 meNumberType = NumberType.Integer; 73 meJavaNumberType = JavaNumberType.Long; 74 break; 75 case "f": 76 meNumberType = NumberType.Float; 77 meJavaNumberType = JavaNumberType.Float; 78 break; 79 case "d": 80 meNumberType = NumberType.Double; 81 meJavaNumberType = JavaNumberType.Double; 82 break; 83 default: 84 throw new RuntimeException("unsupported numerical type "+aLine[5]); 85 } 86 87 switch(aLine[6]) 88 { 89 case "E": 90 meRestrictionType = RestrictionType.Enumeration; 91 maEnumeration = new HashSet<>(); 92 for (int nIndex=7; nIndex<aLine.length; ++nIndex) 93 maEnumeration.add(ParseNumber(aLine[nIndex])); 94 break; 95 96 case "S": 97 meRestrictionType = RestrictionType.Size; 98 for (int nIndex=7; nIndex<=9; nIndex+=2) 99 if (nIndex<aLine.length) 100 switch (aLine[nIndex]) 101 { 102 case "<=": 103 maMaximumValue = ParseNumber(aLine[nIndex+1]); 104 mbIsMaximumInclusive = true; 105 break; 106 case "<": 107 maMaximumValue = ParseNumber(aLine[nIndex+1]); 108 mbIsMaximumInclusive = false; 109 break; 110 case ">=": 111 maMinimumValue = ParseNumber(aLine[nIndex+1]); 112 mbIsMinimumInclusive = true; 113 break; 114 case ">": 115 maMinimumValue = ParseNumber(aLine[nIndex+1]); 116 mbIsMinimumInclusive = false; 117 break; 118 } 119 break; 120 121 case "N": 122 meRestrictionType = RestrictionType.None; 123 break; 124 125 default: 126 throw new RuntimeException("unsupported numerical restriction "+aLine[6]); 127 } 128 } 129 130 131 132 133 @Override Parse( final String sRawValue, final NameMap aAttributeValueMap)134 public Object Parse( 135 final String sRawValue, 136 final NameMap aAttributeValueMap) 137 { 138 final Object aNumber = ParseNumber(sRawValue); 139 switch(meRestrictionType) 140 { 141 case Enumeration: 142 if (maEnumeration.contains(aNumber)) 143 return aNumber; 144 else 145 return null; 146 147 case Size: 148 if (maMinimumValue != null) 149 if (mbIsMinimumInclusive) 150 { 151 if (CompareTo(aNumber, maMinimumValue, meJavaNumberType) < 0) 152 return null; 153 } 154 else 155 { 156 if (CompareTo(aNumber, maMinimumValue, meJavaNumberType) <= 0) 157 return null; 158 } 159 if (maMaximumValue != null) 160 if (mbIsMaximumInclusive) 161 { 162 if (CompareTo(aNumber, maMaximumValue, meJavaNumberType) > 0) 163 return null; 164 } 165 else 166 { 167 if (CompareTo(aNumber, maMaximumValue, meJavaNumberType) >= 0) 168 return null; 169 } 170 return aNumber; 171 172 case None: 173 return aNumber; 174 175 default: 176 throw new RuntimeException(); 177 } 178 } 179 180 181 182 ParseNumber(final String sNumber)183 Object ParseNumber (final String sNumber) 184 { 185 switch(meJavaNumberType) 186 { 187 case Boolean: return Boolean.parseBoolean(sNumber); 188 case Byte: return Byte.parseByte(sNumber); 189 case Short: return Short.parseShort(sNumber); 190 case Integer: return Integer.parseInt(sNumber); 191 case Long: return Long.parseLong(sNumber); 192 case Float: return Float.parseFloat(sNumber); 193 case Double: return Double.parseDouble(sNumber); 194 default: 195 throw new RuntimeException(); 196 } 197 } 198 199 200 201 CompareTo( final Object aLeft, final Object aRight, final JavaNumberType eType)202 private static int CompareTo ( 203 final Object aLeft, 204 final Object aRight, 205 final JavaNumberType eType) 206 { 207 switch(eType) 208 { 209 case Boolean: 210 return ((Boolean)aLeft).compareTo((Boolean)aRight); 211 case Byte: 212 return ((Byte)aLeft).compareTo((Byte)aRight); 213 case Short: 214 return ((Short)aLeft).compareTo((Short)aRight); 215 case Integer: 216 return ((Integer)aLeft).compareTo((Integer)aRight); 217 case Long: 218 return ((Long)aLeft).compareTo((Long)aRight); 219 case Float: 220 return ((Float)aLeft).compareTo((Float)aRight); 221 case Double: 222 return ((Double)aLeft).compareTo((Double)aRight); 223 default: 224 throw new RuntimeException(); 225 } 226 } 227 228 229 230 231 enum NumberType 232 { 233 Boolean, 234 Byte, 235 UnsignedByte, 236 Short, 237 UnsignedShort, 238 Int, 239 UnsignedInt, 240 Long, 241 UnsignedLong, 242 Integer, 243 Float, 244 Double 245 } 246 enum JavaNumberType 247 { 248 Boolean, 249 Byte, 250 Short, 251 Integer, 252 Long, 253 Float, 254 Double 255 } 256 enum RestrictionType 257 { 258 Enumeration, 259 Size, 260 None 261 } 262 private final NumberType meNumberType; 263 private final JavaNumberType meJavaNumberType; 264 private final RestrictionType meRestrictionType; 265 private Set<Object> maEnumeration; 266 private Object maMinimumValue; 267 private boolean mbIsMinimumInclusive; 268 private Object maMaximumValue; 269 private boolean mbIsMaximumInclusive; 270 } 271