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