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