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.HashSet; 25 import java.util.Map; 26 import java.util.Set; 27 import java.util.TreeSet; 28 import java.util.regex.Pattern; 29 import java.util.regex.PatternSyntaxException; 30 31 import org.apache.openoffice.ooxml.schema.misc.Log; 32 import org.apache.openoffice.ooxml.schema.model.simple.BuiltInType; 33 import org.apache.openoffice.ooxml.schema.model.simple.Restriction; 34 35 public class StringNode 36 implements ISimpleTypeNode 37 { StringNode( final BuiltInType eType)38 public StringNode ( 39 final BuiltInType eType) 40 { 41 meType = eType; 42 mbIsList = false; 43 } 44 45 46 47 48 @Override ApplyRestriction( final Restriction aRestriction, final Map<String,Integer> aValueToIdMap)49 public void ApplyRestriction ( 50 final Restriction aRestriction, 51 final Map<String,Integer> aValueToIdMap) 52 { 53 assert( ! aRestriction.HasFeature( 54 Restriction.MinExclusiveBit 55 | Restriction.MinInclusiveBit 56 | Restriction.MaxExclusiveBit 57 | Restriction.MaxInclusiveBit)); 58 59 if (aRestriction.HasFeature(Restriction.EnumerationBit)) 60 { 61 if (aRestriction.HasFeature(Restriction.LengthBit|Restriction.MinLengthBit|Restriction.MaxLengthBit)) 62 for (final String sValue : aRestriction.GetEnumeration()) 63 assert(CheckLengthRestriction(sValue, aRestriction)); 64 maEnumerationValues = new TreeSet<>(); 65 maEnumerationValueIds = new HashSet<>(); 66 for (final String sValue : aRestriction.GetEnumeration()) 67 { 68 if ( ! aValueToIdMap.containsKey(sValue)) 69 aValueToIdMap.put(sValue, aValueToIdMap.size()); 70 maEnumerationValues.add(sValue); 71 maEnumerationValueIds.add(aValueToIdMap.get(sValue)); 72 } 73 } 74 else if (aRestriction.HasFeature(Restriction.PatternBit)) 75 { 76 msPattern = aRestriction.GetPattern(); 77 // Make the regular expression understandable by Java (by replacing 78 // character class names like IsBasicLatin to InBasicLatin). 79 try 80 { 81 maPattern = Pattern.compile(msPattern.replace("\\p{Is", "\\p{In"), Pattern.UNICODE_CHARACTER_CLASS); 82 } 83 catch (PatternSyntaxException aException) 84 { 85 aException.printStackTrace(); 86 } 87 } 88 else if (aRestriction.HasFeature(Restriction.LengthBit|Restriction.MinLengthBit|Restriction.MaxLengthBit)) 89 { 90 if (aRestriction.HasFeature(Restriction.LengthBit)) 91 mnMinimumLength = mnMaximumLength = aRestriction.GetLength(); 92 if (aRestriction.HasFeature(Restriction.MinLengthBit)) 93 mnMinimumLength = aRestriction.GetMinimumLength(); 94 if (aRestriction.HasFeature(Restriction.MaxLengthBit)) 95 mnMaximumLength = aRestriction.GetMaximumLength(); 96 } 97 else 98 { 99 // no restriction. 100 assert(aRestriction.GetFeatureBits() == 0); 101 } 102 } 103 104 105 106 107 @Override Print(final Log aLog)108 public void Print (final Log aLog) 109 { 110 aLog.println(toString()); 111 } 112 113 114 115 116 @Override toString()117 public String toString () 118 { 119 final StringBuffer aBuffer = new StringBuffer(); 120 aBuffer.append(String.format("string (%s)", meType)); 121 if (maEnumerationValueIds != null) 122 { 123 aBuffer.append(" ["); 124 boolean bIsFirst = true; 125 for (final String sValue : maEnumerationValues) 126 { 127 if (bIsFirst) 128 bIsFirst = false; 129 else 130 aBuffer.append(", "); 131 aBuffer.append(sValue); 132 } 133 aBuffer.append("]"); 134 } 135 else if (maPattern != null) 136 { 137 aBuffer.append("pattern=\""); 138 aBuffer.append(maPattern); 139 aBuffer.append("\""); 140 } 141 return aBuffer.toString(); 142 } 143 144 145 146 147 @Override IsList()148 public boolean IsList () 149 { 150 return mbIsList; 151 } 152 153 154 155 156 @Override SetIsList()157 public void SetIsList () 158 { 159 mbIsList = true; 160 } 161 162 163 164 165 /** Try to join the called and the given string types. 166 * If that is possible then return the resulting type. 167 * Otherwise return null. 168 */ Join(final StringNode aType)169 public ISimpleTypeNode Join (final StringNode aType) 170 { 171 if (maEnumerationValues!=null && aType.maEnumerationValues!=null) 172 { 173 // Join the enumeration values. 174 maEnumerationValues.addAll(aType.maEnumerationValues); 175 maEnumerationValueIds.addAll(aType.maEnumerationValueIds); 176 return this; 177 } 178 else 179 return null; 180 } 181 182 183 public enum RestrictionType 184 { 185 Pattern, 186 Enumeration, 187 Length, 188 None 189 } GetRestrictionType()190 public RestrictionType GetRestrictionType () 191 { 192 if (maEnumerationValueIds != null) 193 return RestrictionType.Enumeration; 194 else if (maPattern != null) 195 return RestrictionType.Pattern; 196 else if (mnMinimumLength != null) 197 return RestrictionType.Length; 198 else 199 return RestrictionType.None; 200 } 201 202 203 204 GetEnumerationRestriction()205 public Set<Integer> GetEnumerationRestriction () 206 { 207 final Set<Integer> aSortedIds = new TreeSet<>(); 208 aSortedIds.addAll(maEnumerationValueIds); 209 return aSortedIds; 210 } 211 212 213 214 GetPatternRestriction()215 public String GetPatternRestriction () 216 { 217 return msPattern; 218 } 219 220 221 222 GetLengthRestriction()223 public int[] GetLengthRestriction () 224 { 225 return new int[]{mnMinimumLength, mnMaximumLength}; 226 } 227 228 229 230 CheckLengthRestriction( final String sValue, final Restriction aRestriction)231 private boolean CheckLengthRestriction ( 232 final String sValue, 233 final Restriction aRestriction) 234 { 235 final int nValueLength = sValue.length(); 236 if (aRestriction.HasFeature(Restriction.LengthBit)) 237 return nValueLength == aRestriction.GetLength(); 238 else if (aRestriction.HasFeature(Restriction.MinLengthBit | Restriction.MaxLengthBit)) 239 return nValueLength>=aRestriction.GetMinimumLength() 240 && nValueLength<=aRestriction.GetMaximumLength(); 241 else if (aRestriction.HasFeature(Restriction.MinLengthBit)) 242 return nValueLength>=aRestriction.GetMinimumLength(); 243 else if (aRestriction.HasFeature(Restriction.MaxLengthBit)) 244 return nValueLength<=aRestriction.GetMaximumLength(); 245 else 246 throw new RuntimeException(); 247 } 248 249 250 251 252 @Override AcceptVisitor(final ISimpleTypeNodeVisitor aVisitor)253 public void AcceptVisitor (final ISimpleTypeNodeVisitor aVisitor) 254 { 255 aVisitor.Visit(this); 256 } 257 258 259 260 261 private final BuiltInType meType; 262 private Set<String> maEnumerationValues; 263 private Set<Integer> maEnumerationValueIds; 264 private Pattern maPattern; 265 private String msPattern; 266 private Integer mnMinimumLength; 267 private Integer mnMaximumLength; 268 private boolean mbIsList; 269 } 270