View Javadoc

1   /*
2    * Copyright 2004-2005 The Apache Software Foundation or its licensors,
3    *                     as applicable.
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package net.sf.exorcist.midgard;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.util.Collections;
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.Map;
25  
26  import javax.xml.parsers.DocumentBuilder;
27  import javax.xml.parsers.DocumentBuilderFactory;
28  import javax.xml.parsers.ParserConfigurationException;
29  
30  import org.w3c.dom.Document;
31  import org.w3c.dom.Element;
32  import org.w3c.dom.Node;
33  import org.w3c.dom.NodeList;
34  import org.xml.sax.SAXException;
35  
36  public class MidgardSchema {
37  
38      private static final String NAMESPACE =
39          "http://www.midgard-project.org/repligard/1.4";
40  
41      private static final String TYPE = "type";
42  
43      private static final String PROPERTY = "property";
44  
45      private static final String NAME = "name";
46  
47      private static final String TABLE = "table";
48  
49      private static final String LINK = "link";
50  
51      private static final String TIMESTAMP = "timestamp";
52  
53      private static final String PRIMARYFIELD = "primaryfield";
54  
55      private static final String PARENTFIELD = "parentfield";
56  
57      private static final String UPFIELD = "upfield";
58  
59      private final Map types = new HashMap();
60  
61      private final Map tables = new HashMap();
62  
63      public void parse(InputStream schema) throws IOException, SAXException, ParserConfigurationException {
64          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
65          factory.setNamespaceAware(true);
66          DocumentBuilder builder = factory.newDocumentBuilder();
67          Document document = builder.parse(schema);
68          Element root = document.getDocumentElement();
69          NodeList typeNodes = root.getChildNodes();
70  
71          // pass 1
72          for (int i = 0; i < typeNodes.getLength(); i++) {
73              Node typeNode = typeNodes.item(i);
74              if (typeNode.getNodeType() == Node.ELEMENT_NODE
75                      && TYPE.equals(typeNode.getNodeName())) {
76                  Element element = (Element) typeNode;
77                  String name = element.getAttribute(NAME);
78                  String table = element.getAttribute(TABLE);
79                  if (name.length() > 0) {
80                      MidgardType type = new MidgardType();
81                      type.setName(name);
82                      type.setTable((table.length() > 0) ? table : name);
83                      addType(type);
84                  }
85              }
86          }
87  
88          // pass 2
89          for (int i = 0; i < typeNodes.getLength(); i++) {
90              Node typeNode = typeNodes.item(i);
91              if (typeNode.getNodeType() == Node.ELEMENT_NODE
92                      && TYPE.equals(typeNode.getNodeName())) {
93                  String typeName = ((Element) typeNode).getAttribute(NAME);
94                  MidgardType type = getTypeByName(typeName);
95                  if (type != null) {
96                      NodeList propertyNodes = typeNode.getChildNodes();
97                      for (int j = 0; j < propertyNodes.getLength(); j++) {
98                          Node propertyNode = propertyNodes.item(j);
99                          if (propertyNode.getNodeType() == Node.ELEMENT_NODE
100                                 && PROPERTY.equals(propertyNode.getNodeName())) {
101                             Element element = (Element) propertyNode;
102                             String name = element.getAttribute(NAME);
103                             String ptype = element.getAttribute(TYPE);
104                             String table = element.getAttribute(TABLE);
105                             if (name.length() > 0 && table.length() == 0) {
106                                 MidgardProperty property = new MidgardProperty();
107                                 property.setName(name);
108                                 property.setType((ptype.length() > 0) ? ptype : "text");
109                                 type.addProperty(property);
110                                 if (name.equals(element.getAttribute(PRIMARYFIELD))) {
111                                     type.setPrimary(property);
112                                 }
113                             }
114                         }
115                     }
116                 }
117             }
118         }
119         
120         // pass 3
121         for (int i = 0; i < typeNodes.getLength(); i++) {
122             Node typeNode = typeNodes.item(i);
123             if (typeNode.getNodeType() == Node.ELEMENT_NODE
124                     && TYPE.equals(typeNode.getNodeName())) {
125                 String typeName = ((Element) typeNode).getAttribute(NAME);
126                 MidgardType type = getTypeByName(typeName);
127                 if (type != null) {
128                     NodeList propertyNodes = typeNode.getChildNodes();
129                     for (int j = 0; j < propertyNodes.getLength(); j++) {
130                         Node propertyNode = propertyNodes.item(j);
131                         if (propertyNode.getNodeType() == Node.ELEMENT_NODE
132                                 && PROPERTY.equals(propertyNode.getNodeName())) {
133                             Element element = (Element) propertyNode;
134                             MidgardProperty property =
135                                 type.getProperty(element.getAttribute(NAME));
136                             if (property != null) {
137                                 String link = element.getAttribute(LINK);
138                                 int colon = link.indexOf(':');
139                                 if (colon != -1) {
140                                     MidgardType linkType = getTypeByName(link.substring(0, colon));
141                                     if (linkType != null) {
142                                         property.setLink(linkType);
143                                         String parentfield = element.getAttribute(PARENTFIELD);
144                                         if (property.getName().equals(parentfield)) {
145                                             type.setParent(property);
146                                         }
147                                     }
148                                 }
149                                 String upfield = element.getAttribute(UPFIELD);
150                                 if (property.getName().equals(upfield)) {
151                                     property.setLink(type);
152                                     type.setParent(property);
153                                 }
154                                 String timestamp = element.getAttribute(TIMESTAMP);
155                                 if (property.getName().equals(timestamp)) {
156                                     type.setTimestamp(property);
157                                 }
158                             }
159                         }
160                     }
161                 }
162             }
163         }
164     }
165     
166     public MidgardType getTypeByName(String name) {
167         return (MidgardType) types.get(name);
168     }
169 
170     public MidgardType getTypeByTable(String table) {
171         return (MidgardType) tables.get(table);
172     }
173 
174     public Iterator getTypes() {
175         return Collections.unmodifiableCollection(types.values()).iterator();
176     }
177 
178     public void addType(MidgardType type) {
179         types.put(type.getName(), type);
180         tables.put(type.getTable(), type);
181     }
182 
183 }