1 /***
2 * Copyright 2003-2010 Terracotta, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package net.sf.ehcache.config.generator.xsom;
18
19 import java.io.InputStream;
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.Iterator;
23 import java.util.List;
24
25 import net.sf.ehcache.config.generator.model.NodeElement;
26 import net.sf.ehcache.config.generator.model.SimpleNodeElement;
27
28 import com.sun.xml.xsom.XSAttributeDecl;
29 import com.sun.xml.xsom.XSAttributeUse;
30 import com.sun.xml.xsom.XSContentType;
31 import com.sun.xml.xsom.XSElementDecl;
32 import com.sun.xml.xsom.XSModelGroup;
33 import com.sun.xml.xsom.XSParticle;
34 import com.sun.xml.xsom.XSSchema;
35 import com.sun.xml.xsom.XSSchemaSet;
36 import com.sun.xml.xsom.XSTerm;
37 import com.sun.xml.xsom.XSType;
38 import com.sun.xml.xsom.XmlString;
39 import com.sun.xml.xsom.parser.XSOMParser;
40
41 public class XSOMHelper {
42 private XSDAttributeValueFactory attributeValueFactory;
43
44 public XSOMHelper(XSDAttributeValueFactory attributeValueFactory) {
45 this.attributeValueFactory = attributeValueFactory;
46 }
47
48 public XSDAttributeValueFactory getAttributeValueFactory() {
49 return attributeValueFactory;
50 }
51
52 public void setAttributeValueFactory(XSDAttributeValueFactory attributeValueFactory) {
53 this.attributeValueFactory = attributeValueFactory;
54 }
55
56 public NodeElement createRootElement(InputStream xsdInputStream, String rootName) throws Exception {
57 XSOMParser parser = new XSOMParser();
58 parser.parse(xsdInputStream);
59 XSSchemaSet schemaSet = parser.getResult();
60
61 Iterator<XSSchema> schemaIterator = schemaSet.iterateSchema();
62 XSElementDecl rootElementDecl = null;
63 while (schemaIterator.hasNext()) {
64 XSSchema schema = schemaIterator.next();
65 rootElementDecl = schema.getElementDecl(rootName);
66 if (rootElementDecl != null)
67 break;
68 }
69 if (rootElementDecl == null) {
70 throw new Exception("Root Element not found - " + rootName);
71 }
72
73 return createElement(null, rootElementDecl);
74 }
75
76 private XSDElement createElement(SimpleNodeElement parent, XSElementDecl elementDecl) throws Exception {
77 XSDElement element = new XSDElement(parent, elementDecl.getName());
78 List<XSAttributeUse> attrs = getXSAttributeUses(elementDecl);
79 for (XSAttributeUse attrUse : attrs) {
80 XSDAttribute attribute = createXSDAttribute(element, attrUse);
81 if (attribute != null) {
82 element.addAttribute(attribute);
83 }
84 }
85 for (XSElementDeclWrapper childXSElementDeclWrapper : getChildElements(elementDecl)) {
86 XSDElement childElement = createElement(element, childXSElementDeclWrapper.getXsElementDecl());
87 childElement.setMinOccurs(childXSElementDeclWrapper.getMinOccurs());
88 childElement.setMaxOccurs(childXSElementDeclWrapper.getMaxOccurs());
89 element.addChildElement(childElement);
90 }
91 return element;
92 }
93
94 private List<XSAttributeUse> getXSAttributeUses(XSElementDecl element) {
95 if (!element.getType().isComplexType()) {
96 return Collections.EMPTY_LIST;
97 }
98 return new ArrayList<XSAttributeUse>(element.getType().asComplexType().getAttributeUses());
99 }
100
101 private XSDAttribute createXSDAttribute(NodeElement element, XSAttributeUse attributeUse) throws Exception {
102 XSAttributeDecl attributeDecl = attributeUse.getDecl();
103 XSDAttribute attribute = new XSDAttribute(attributeDecl.getName());
104 XSDAttributeValueType attributeValueType = XSDAttributeValueTypeFactory.createType(attributeDecl);
105 attribute.setAttributeValueType(attributeValueType);
106
107 String attributeValue = attributeValueFactory.createValueForAttribute(element, attribute, attributeValueType);
108 if (attributeValue == null) {
109 return null;
110 }
111 attribute.setValue(attributeValue);
112
113 attribute.setOptional(!attributeUse.isRequired());
114 XmlString defaultValue = attributeUse.getDefaultValue();
115 if (defaultValue != null) {
116 attribute.setDefaultValue(defaultValue.value);
117 }
118 return attribute;
119 }
120
121 private List<XSElementDeclWrapper> getChildElements(XSElementDecl element) {
122 XSType type = element.getType();
123 if (!type.isComplexType()) {
124 return Collections.EMPTY_LIST;
125 }
126 List<XSElementDeclWrapper> rv = new ArrayList<XSElementDeclWrapper>();
127 XSContentType xsContentType = type.asComplexType().getContentType();
128 XSParticle particle = xsContentType.asParticle();
129 if (particle != null) {
130 XSTerm term = particle.getTerm();
131 if (term.isModelGroup()) {
132 XSModelGroup xsModelGroup = term.asModelGroup();
133 XSParticle[] particles = xsModelGroup.getChildren();
134 for (XSParticle p : particles) {
135 XSTerm pterm = p.getTerm();
136 if (pterm.isElementDecl()) {
137 XSElementDecl childElementDecl = (XSElementDecl) pterm;
138 XSElementDeclWrapper wrapper = new XSElementDeclWrapper(childElementDecl, p.getMinOccurs(), p.getMaxOccurs());
139 rv.add(wrapper);
140 }
141 }
142 }
143 }
144 return rv;
145 }
146
147 private static class XSElementDeclWrapper {
148 private final XSElementDecl xsElementDecl;
149 private final int minOccurs;
150 private final int maxOccurs;
151
152 public XSElementDeclWrapper(XSElementDecl xsElementDecl, int minOccurs, int maxOccurs) {
153 this.xsElementDecl = xsElementDecl;
154 this.minOccurs = minOccurs;
155 this.maxOccurs = maxOccurs;
156 }
157
158 public XSElementDecl getXsElementDecl() {
159 return xsElementDecl;
160 }
161
162 public int getMinOccurs() {
163 return minOccurs;
164 }
165
166 public int getMaxOccurs() {
167 return maxOccurs;
168 }
169
170 }
171
172 }