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.HashMap;
25 import java.util.Map;
26 
27 import org.apache.openoffice.ooxml.schema.misc.Log;
28 import org.apache.openoffice.ooxml.schema.model.base.INode;
29 import org.apache.openoffice.ooxml.schema.model.base.NodeType;
30 import org.apache.openoffice.ooxml.schema.model.base.NodeVisitorAdapter;
31 import org.apache.openoffice.ooxml.schema.model.schema.SchemaBase;
32 import org.apache.openoffice.ooxml.schema.model.simple.BuiltIn;
33 import org.apache.openoffice.ooxml.schema.model.simple.List;
34 import org.apache.openoffice.ooxml.schema.model.simple.Restriction;
35 import org.apache.openoffice.ooxml.schema.model.simple.SimpleType;
36 import org.apache.openoffice.ooxml.schema.model.simple.SimpleTypeReference;
37 import org.apache.openoffice.ooxml.schema.model.simple.Union;
38 
39 public class SimpleTypeDescriptorFactory
40     extends NodeVisitorAdapter
41 {
42     class TypeCounter
43         extends NodeVisitorAdapter
44     {
45         public final Map<NodeType,Integer> Counters;
TypeCounter()46         TypeCounter ()
47         {
48             Counters = new HashMap<>();
49             for (final NodeType eType : NodeType.values())
50                 Counters.put(eType, 0);
51         }
52         @Override
Default(final INode aNode)53         public void Default (final INode aNode)
54         {
55             Counters.put(aNode.GetNodeType(), Counters.get(aNode.GetNodeType())+1);
56         }
57     }
58 
59 
60 
61 
CreateSimpleTypeDescriptor( final SimpleType aSimpleType, final SchemaBase aSchemaBase, final Log aLog)62     public static SimpleTypeDescriptor CreateSimpleTypeDescriptor(
63         final SimpleType aSimpleType,
64         final SchemaBase aSchemaBase,
65         final Log aLog)
66     {
67         final SimpleTypeDescriptorFactory aFactory = new SimpleTypeDescriptorFactory(
68             aSchemaBase,
69             aLog);
70 
71         aLog.AddComment("Simple type %s, defined at %s",
72             aSimpleType.GetName(),
73             aSimpleType.GetLocation().toString());
74 
75         final ISimpleTypeNode aSubType = aFactory.ProcessSimpleType(aSimpleType);
76         final SimpleTypeDescriptor aDescriptor = new SimpleTypeDescriptor(aSimpleType.GetName());
77         aSubType.AcceptVisitor(new SimpleTypeNodeVisitorAdapter ()
78         {
79             @Override public void Visit (final UnionNode aType)
80             {
81                 aDescriptor.SetSubTypes(aType.GetChildren());
82             }
83 
84             @Override public void Default (final ISimpleTypeNode aType)
85             {
86                 aDescriptor.SetSubTypes(new ISimpleTypeNode[]{aSubType});
87             }
88         });
89 
90         aDescriptor.Print(aLog);
91         aLog.printf("\n");
92 
93         return aDescriptor;
94     }
95 
96 
97 
98 
SimpleTypeDescriptorFactory( final SchemaBase aSchemaBase, final Log aLog)99     private SimpleTypeDescriptorFactory (
100         final SchemaBase aSchemaBase,
101         final Log aLog)
102     {
103         maSchemaBase = aSchemaBase;
104         maLog = aLog;
105         maResult = null;
106     }
107 
108 
109 
110 
ProcessSimpleType(final SimpleType aSimpleType)111     ISimpleTypeNode ProcessSimpleType (final SimpleType aSimpleType)
112     {
113         return ApplyVisitor(aSimpleType);
114     }
115 
116 
117 
118 
119     @Override
Visit(final BuiltIn aNode)120     public void Visit (final BuiltIn aNode)
121     {
122         assert(aNode.GetChildCount() == 0);
123         assert(maResult == null);
124 
125         maLog.AddComment("builtin %s", aNode.toString());
126 
127         switch(aNode.GetBuiltInType())
128         {
129             case Double:
130                 maResult = new NumberNode<Double>(aNode.GetBuiltInType());
131                 break;
132             case Float:
133                 maResult = new NumberNode<Float>(aNode.GetBuiltInType());
134                 break;
135 
136             case Boolean:
137                 maResult = new NumberNode<Boolean>(aNode.GetBuiltInType());
138             case Integer:
139                 maResult = new NumberNode<Long>(aNode.GetBuiltInType());
140                 break;
141             case Byte:
142                 maResult = new NumberNode<Byte>(aNode.GetBuiltInType());
143             case Int:
144                 maResult = new NumberNode<Integer>(aNode.GetBuiltInType());
145             case Long:
146                 maResult = new NumberNode<Long>(aNode.GetBuiltInType());
147             case Short:
148                 maResult = new NumberNode<Short>(aNode.GetBuiltInType());
149             case UnsignedByte:
150                 maResult = new NumberNode<Integer>(aNode.GetBuiltInType());
151             case UnsignedInt:
152                 maResult = new NumberNode<Long>(aNode.GetBuiltInType());
153             case UnsignedLong:
154                 maResult = new NumberNode<Long>(aNode.GetBuiltInType());
155             case UnsignedShort:
156                 maResult = new NumberNode<Integer>(aNode.GetBuiltInType());
157                 break;
158 
159             case AnyURI:
160             case ID:
161             case NcName:
162             case String:
163             case Token:
164                 maResult = new StringNode(aNode.GetBuiltInType());
165                 break;
166 
167             case Base64Binary:
168             case HexBinary:
169                 maResult = new BlobNode(aNode.GetBuiltInType());
170                 break;
171 
172             case DateTime:
173                 maResult = new DateTimeNode(aNode.GetBuiltInType());
174                 break;
175 
176             default:
177                 throw new RuntimeException(aNode.toString()+" is not supported");
178         }
179     }
180 
181 
182 
183 
184     @Override
Visit(final List aNode)185     public void Visit (final List aNode)
186     {
187         maLog.AddComment("list of type %s", aNode.GetItemType().toString());
188         maLog.StartBlock();
189         final ISimpleTypeNode aItemType = ApplyVisitor(maSchemaBase.GetSimpleTypeForName(aNode.GetItemType()));
190         maLog.EndBlock();
191 
192         aItemType.SetIsList();
193         maResult = aItemType;
194     }
195 
196 
197 
198 
199     @Override
Visit(final Restriction aNode)200     public void Visit (final Restriction aNode)
201     {
202         assert(aNode.GetChildCount() == 0);
203 
204         maLog.AddComment("%s", aNode.toString());
205 
206         final INode aBaseType = maSchemaBase.GetSimpleTypeForName(aNode.GetBaseType());
207         if (aBaseType == null)
208             throw new RuntimeException("got no type for name "+aNode.GetBaseType());
209         maLog.StartBlock();
210         maResult = ApplyVisitor(aBaseType);
211         maLog.EndBlock();
212         maResult.ApplyRestriction(
213             aNode,
214             maSchemaBase.AttributeValueToIdMap);
215     }
216 
217 
218 
219 
220     @Override
Visit(final SimpleType aNode)221     public void Visit (final SimpleType aNode)
222     {
223         maLog.AddComment(aNode.toString());
224 
225         assert(aNode.GetChildCount() <= 1);
226         switch(aNode.GetChildCount())
227         {
228             case 0:
229                 maResult = null;
230                 break;
231             case 1:
232                 maLog.StartBlock();
233                 maResult = ApplyVisitor(aNode.GetOnlyChild());
234                 maLog.EndBlock();
235                 break;
236             default:
237                 throw new RuntimeException();
238         }
239     }
240 
241 
242 
243 
244     @Override
Visit(final SimpleTypeReference aNode)245     public void Visit (final SimpleTypeReference aNode)
246     {
247         maLog.AddComment("reference to %s", aNode.GetReferencedTypeName());
248 
249         maLog.StartBlock();
250         maResult = ApplyVisitor(aNode.GetReferencedNode(maSchemaBase));
251         maLog.EndBlock();
252     }
253 
254 
255 
256 
257     @Override
Visit(final Union aNode)258     public void Visit (final Union aNode)
259     {
260         maLog.AddComment("union");
261 
262         final UnionNode aUnion = new UnionNode();
263 
264         // Make sure that all children have compatible types and value sets.
265         maLog.StartBlock();
266 
267         for (final INode aChild : aNode.GetChildren())
268         {
269             aUnion.AddNode(ApplyVisitor(aChild));
270         }
271 
272         maLog.EndBlock();
273 
274         maResult = aUnion;
275     }
276 
277 
278 
279 
280     @Override
Default(final INode aNode)281     public void Default (final INode aNode)
282     {
283         switch(aNode.GetNodeType())
284         {
285             default:
286                 throw new RuntimeException(aNode.GetNodeType() +" is not yet supported");
287         }
288     }
289 
290 
291 
292 
ApplyVisitor(final INode aNode)293     ISimpleTypeNode ApplyVisitor (final INode aNode)
294     {
295         aNode.AcceptVisitor(this);
296         final ISimpleTypeNode aResult = maResult;
297         maResult = null;
298         return aResult;
299     }
300 
301 
302 
303 
304     private final SchemaBase maSchemaBase;
305     private final Log maLog;
306     private ISimpleTypeNode maResult;
307 }
308