Source code: org/jdbf/engine/xml/XPathManager.java
1 /*
2 * 03/14/2002 - 23:15:57
3 * XPathManager.java - JDBF Object Relational mapping system
4 * Copyright (C) 2002 Giovanni Martone
5 * giovannimartone@hotmail.com
6 * http://jdbf.sourceforge.net
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22 package org.jdbf.engine.xml;
23
24 import java.io.*;
25 import java.util.ArrayList;
26
27 import javax.xml.transform.TransformerException;
28 import javax.xml.parsers.*;
29
30 import org.apache.xpath.XPathAPI;
31 import org.w3c.dom.*;
32 import org.xml.sax.*;
33
34 import org.jdbf.engine.mapping.*;
35 import org.jdbf.engine.repository.*;
36
37
38 /**
39 * <code>XPathManager</code> is the class that parses the informations on the
40 * repository and finally it creates an RepositoryView.
41 * To create a RepositoryView, XPathManager uses the XPath that specifies the
42 * path the repositoryView on the repository file.
43 * XPath is express as /repository/repositoryView/[name='repositoryName'], where
44 * repositoryName is the name of repository which needs to return the informations.
45 * These informations are: <br>
46 * <li>BeanDescriptor</li><br>
47 * <li>ItemDescriptor</li><br>
48 *
49 * @see <a href=http://www.w3.org/TR/xpath>XPath Specification</a>
50 * @see org.jdbf.engine.repository.RepositoryView,
51 * org.jdbf.engine.descriptor.BeanDescriptor,
52 * org.jdbf.engine.descriptor.ItemDescriptor
53 *
54 */
55 public class XPathManager implements GenericXPath {
56
57 /** name of repository file */
58 private String fileName;
59 /** XPath */
60 private String xPath;
61 /** Document object */
62 private Document document;
63 /** RepositoryFactory object */
64 private RepositoryFactory repFactory;
65
66
67 /**
68 * Creates the XPathManager object and it parses the repository file
69 * specified in fileName.
70 * @param fileName name of repository file
71 * @throws Exception
72 */
73 public XPathManager(String fileName) throws Exception{
74 this.fileName = fileName;
75 repFactory = new RepositoryFactory();
76 document = parse(this.fileName);
77 loadRepositoryFactory();
78 }
79
80
81 /**
82 * Creates the repositoryView.
83 * @param xPath path the repositoryView on the repository
84 * @return RepositoryView
85 * @throws MappingException
86 */
87 public Repository createRepositoryView(Element e)
88 throws MappingException{
89
90 RepositoryView repositoryView = new RepositoryView() ;
91 BeanDescriptor beanDescriptor = getBeanDescriptor(e);
92 xPath = "/repository/repositoryView[@name='"
93 + beanDescriptor.getRepositoryViewName() + "']/*";
94 ArrayList itemDescriptors = getItemDescriptor(xPath);
95 for(int i = 0 ; i < itemDescriptors.size(); i++){
96 ItemDescriptor item = (ItemDescriptor) itemDescriptors.get(i);
97 item.setClassName(beanDescriptor.getClassName());
98 item.setTableName(beanDescriptor.getTableName());
99 item.setRepositoryViewName(beanDescriptor.getRepositoryViewName());
100 itemDescriptors.set(i,item);
101 }
102 beanDescriptor.setItemDescriptors(itemDescriptors);
103 xPath = "/repository/repositoryView[@name='"
104 + beanDescriptor.getRepositoryViewName() + "']/key-generator";
105 beanDescriptor.setGeneratorMap(createGeneratorMap(xPath));
106 repositoryView.setBeanDescriptor(beanDescriptor);
107 return repositoryView;
108 }
109
110
111 /**
112 * Creates the repositoryView.
113 * @param xPath path the repositoryView on the repository
114 * @return GeneratorMap
115 * @exception MappingException
116 */
117 public GeneratorMap createGeneratorMap(String xPath)throws MappingException{
118 GeneratorMap generatorMap = null;
119 try{
120
121 Element e =(Element)XPathAPI.selectSingleNode(document, xPath);
122 String type = e.getAttribute("type");
123
124 if(type.equals("highlow")){
125 String tableName = e.getAttribute("table");
126 String keyColumn = e.getAttribute("keyColumn");
127 String nextColumn = e.getAttribute("nextColumn");
128 String tableColumn = e.getAttribute("tableColumn");
129 generatorMap = new HighLowMap(tableName,keyColumn,nextColumn,tableColumn);
130 }
131 if(type.equals("max") || type.equals("identity"))
132 generatorMap = new GeneratorMap(type);
133
134 if(type.equals("sequence")){
135 String sequenceName = e.getAttribute("sequenceName");
136 generatorMap = new SequenceMap(type,sequenceName);
137 }
138
139 }
140 catch(TransformerException e){
141 throw new MappingException(e);
142 }
143 finally{
144 return generatorMap;
145 }
146 }
147
148
149 /**
150 * Return name of repository
151 *
152 * @param xPath
153 * @return Object
154 * @throws MappingException
155 * @deprecated Method deprecated
156 */
157 public Object getValueOfAttribute(String xPath,String attribute,String value)
158 throws MappingException{
159
160 String name = "";
161 try{
162 this.xPath = xPath + "='" + value + "']" ;
163 NodeList node = XPathAPI.selectNodeList(document,xPath);
164
165 Element e = (Element)node.item(0);
166 name = e.getAttribute(attribute);
167 if(name == null || name.equals(""))
168 throw new MappingException("mapping.repositoryViewNameMissing");
169 }
170 catch(TransformerException e){
171 throw new MappingException(e);
172 }
173 finally{
174 return name;
175 }
176 }
177
178
179 /**
180 * Return the BeanDescriptor object.
181 *
182 * @param Element xml node in the repository
183 * @return BeanDescriptor
184 * @throws MappingException
185 */
186 protected BeanDescriptor getBeanDescriptor(Element e)
187 throws MappingException{
188
189 BeanDescriptor beanDescriptor = new BeanDescriptor();
190
191 String attribute = e.getAttribute("name");
192 if(attribute == null || attribute.equals(""))
193 throw new MappingException("mapping.repositoryViewNameMissing");
194 else
195 beanDescriptor.setRepositoryViewName(attribute);
196
197 attribute = e.getAttribute("table-name");
198 if(attribute == null || attribute.equals(""))
199 throw new MappingException("mapping.noTableName",xPath);
200 else
201 beanDescriptor.setTableName(attribute);
202
203 attribute = e.getAttribute("object-name");
204 if(attribute == null || attribute.equals(""))
205 throw new MappingException("mapping.classMapNotFound",xPath);
206 else
207 beanDescriptor.setClassName(attribute);
208
209 attribute = e.getAttribute("database-name");
210 if(attribute == null || attribute.equals(""))
211 throw new MappingException("mapping.databaseNameMissing");
212 else
213 beanDescriptor.setDatabaseName(attribute);
214 return beanDescriptor;
215 }
216
217
218 /**
219 * Return the ItemDescriptor object.
220 * If the xPath is incorrect TransformerException is throwed.
221 *
222 * @param xPath path the repositoryView on the repository
223 * @return BeanDescriptor
224 * @throws MappingException
225 *
226 */
227 protected ArrayList getItemDescriptor(String xPath)throws MappingException{
228
229 ArrayList itemDescriptors = new ArrayList();
230 try{
231
232 NodeList nl = XPathAPI.selectNodeList(document, xPath);
233 for (int i = 0 ; i < nl.getLength(); i++) {
234 ItemDescriptor itemDescriptor = new ItemDescriptor();
235 Element e =(Element)nl.item(i);
236
237 String primaryKey = e.getAttribute("primary-key");
238 if(primaryKey == null || primaryKey.equals(""))
239 throw new MappingException("mapping.primaryKeyMissing");
240 else{
241 //if item is unique key
242 if(primaryKey.equalsIgnoreCase("yes"))
243 itemDescriptor.setIsPrimaryKey(true);
244 else
245 itemDescriptor.setIsPrimaryKey(false);
246 }
247
248 String attribute = e.getAttribute("property-name");
249 if(attribute == null || attribute.equals(""))
250 throw new MappingException("mapping.propertyNameMissing");
251 else
252 itemDescriptor.setPropertyName(attribute);
253
254 attribute = e.getAttribute("data-type");
255 if(attribute == null || attribute.equals(""))
256 throw new MappingException("mapping.sqlTypeMissing");
257 else
258 itemDescriptor.setDataType(attribute);
259
260 attribute = e.getAttribute("column-name");
261 if(attribute == null || attribute.equals(""))
262 throw new MappingException("mapping.columnNameMissing");
263 else
264 itemDescriptor.setColumnTableName(attribute);
265 itemDescriptors.add(itemDescriptor);
266 }
267 }
268 catch(TransformerException e){
269 throw new MappingException(e);
270 }
271 finally{
272 return itemDescriptors;
273 }
274 }
275
276
277 /**
278 * Load all repositoryView object in RepositoryFactory.
279 *
280 * @throws MappingException if error occurs
281 */
282 protected void loadRepositoryFactory() throws MappingException {
283 try{
284 xPath = "/repository/*";
285 NodeList nl = XPathAPI.selectNodeList(document, xPath);
286 for(int i = 0 ; i < nl.getLength(); i++) {
287 Element node =(Element)nl.item(i);
288 RepositoryView repository =
289 (RepositoryView)createRepositoryView(node);
290 String repositoryViewName = repository.getBeanDescriptor().
291 getRepositoryViewName();
292 repFactory.addRepository(repositoryViewName,repository);
293 }
294 }
295 catch(TransformerException e){
296 e.printStackTrace();
297 }
298 }
299
300
301 /**
302 * Return RepositoryFactory
303 *
304 * @return RepositoryFactory
305 */
306 public RepositoryFactory getRepositoryFactory(){
307 return repFactory;
308 }
309
310
311 /**
312 * Parses the repository file specified in fileName
313 *
314 * @param fileName name of repository file
315 * @return document
316 * @throws MappingException,IOException,ParserConfigurationExcpetion,SAXException
317 */
318 protected Document parse(String fileName)
319 throws ParserConfigurationException,SAXException,MappingException{
320
321 DocumentBuilderFactory dfactory = null;
322 InputSource in = null;
323
324 try{
325 //Set up a DOM tree to query
326 in = new InputSource(new FileInputStream(fileName));
327 dfactory = DocumentBuilderFactory.newInstance();
328 dfactory.setNamespaceAware(true);
329 return dfactory.newDocumentBuilder().parse(in);
330 }
331 catch(FileNotFoundException e){
332 throw new MappingException("mapping.missingRepositoryConf",fileName);
333 }
334 catch(IOException e){
335 throw new MappingException("mapping.missingRepositoryConf",fileName);
336 }
337 }
338 }