View Javadoc

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()) { // xs:element inside complex type
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 }