View Javadoc

1   package org.apache.torque.engine.database.transform;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.BufferedInputStream;
23  import java.io.BufferedReader;
24  import java.io.File;
25  import java.io.FileInputStream;
26  import java.io.FileReader;
27  import java.io.IOException;
28  import java.io.Reader;
29  import java.net.MalformedURLException;
30  import java.net.URL;
31  import java.util.ArrayList;
32  import java.util.List;
33  
34  import javax.xml.parsers.SAXParser;
35  import javax.xml.parsers.SAXParserFactory;
36  
37  import org.apache.commons.lang.StringUtils;
38  import org.apache.commons.logging.Log;
39  import org.apache.commons.logging.LogFactory;
40  import org.apache.torque.engine.database.model.Column;
41  import org.apache.torque.engine.database.model.Database;
42  import org.apache.torque.engine.database.model.Table;
43  import org.xml.sax.Attributes;
44  import org.xml.sax.EntityResolver;
45  import org.xml.sax.InputSource;
46  import org.xml.sax.SAXException;
47  import org.xml.sax.helpers.DefaultHandler;
48  
49  /**
50   * A Class that is used to parse an input xml schema file and creates and AppData java structure.
51   * 
52   * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a>
53   * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
54   * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
55   * @author <a href="mailto:fedor.karpelevitch@home.com">Fedor Karpelevitch</a>
56   * @version $Id: XmlToData.java,v 1.1 2007-10-21 07:57:26 abyrne Exp $
57   */
58  public class XmlToData extends DefaultHandler implements EntityResolver {
59  	/** Logging class from commons.logging */
60  	private static Log log = LogFactory.getLog(XmlToData.class);
61  	private Database database;
62  	private List<Object> data;
63  	private File dtdFile;
64  
65  	private static SAXParserFactory saxFactory;
66  
67  	static {
68  		saxFactory = SAXParserFactory.newInstance();
69  		saxFactory.setValidating(true);
70  	}
71  
72  	/**
73  	 * Default custructor
74  	 */
75  	public XmlToData(Database database, String dtdFilePath) throws MalformedURLException, IOException {
76  		this.database = database;
77  		this.dtdFile = new File(dtdFilePath);
78  	}
79  
80  	/**
81       *
82       */
83  	public List<?> parseFile(String xmlFile) throws Exception {
84  		data = new ArrayList<Object>();
85  
86  		SAXParser parser = saxFactory.newSAXParser();
87  
88  		Reader r = new BufferedReader(new FileReader(xmlFile));
89  		try {
90  			InputSource is = new InputSource(r);
91  			is.setSystemId(dtdFile.getAbsolutePath());
92  			parser.parse(is, this);
93  		} finally {
94  			r.close();
95  		}
96  		return data;
97  	}
98  
99  	/**
100 	 * Handles opening elements of the xml file.
101 	 */
102 	public void startElement(String uri, String localName, String rawName, Attributes attributes) throws SAXException {
103 		try {
104 			if (rawName.equals("dataset")) {
105 				// ignore <dataset> for now.
106 			} else {
107 				Table table = database.getTableByJavaName(rawName);
108 
109 				if (table == null) {
110 					throw new SAXException("Table '" + rawName + "' unknown");
111 				}
112 				List<ColumnValue> columnValues = new ArrayList<ColumnValue>();
113 				for (int i = 0; i < attributes.getLength(); i++) {
114 					Column col = table.getColumnByJavaName(attributes.getQName(i));
115 
116 					if (col == null) {
117 						throw new SAXException("Column " + attributes.getQName(i) + " in table " + rawName + " unknown.");
118 					}
119 
120 					String value = attributes.getValue(i);
121 					columnValues.add(new ColumnValue(col, value));
122 				}
123 				data.add(new DataRow(table, columnValues));
124 			}
125 		} catch (Exception e) {
126 			throw new SAXException(e);
127 		}
128 	}
129 
130 	/**
131 	 * called by the XML parser
132 	 * 
133 	 * @return an InputSource for the database.dtd file
134 	 */
135 	public InputSource resolveEntity(String publicId, String systemId) throws SAXException {
136 		try {
137 			File systemIdFile = new File(systemId);
138 			if (dtdFile.equals(systemIdFile)) {
139 				log.debug("Resolver: -> used " + dtdFile.getPath());
140 				return new InputSource(new BufferedInputStream(new FileInputStream(dtdFile)));
141 			} else {
142 				log.debug("Resolver: -> used " + systemId);
143 				return getInputSource(systemId);
144 			}
145 		} catch (IOException e) {
146 			throw new SAXException(e);
147 		}
148 	}
149 
150 	/**
151 	 * get an InputSource for an URL String
152 	 * 
153 	 * @param urlString
154 	 * @return an InputSource for the URL String
155 	 */
156 	public InputSource getInputSource(String urlString) throws IOException {
157 		URL url = new URL(urlString);
158 		InputSource src = new InputSource(url.openStream());
159 		return src;
160 	}
161 
162 	/**
163      *
164      */
165 	public class DataRow {
166 		private Table table;
167 		private List<ColumnValue> columnValues;
168 
169 		public DataRow(Table table, List<ColumnValue> columnValues) {
170 			this.table = table;
171 			this.columnValues = columnValues;
172 		}
173 
174 		public Table getTable() {
175 			return table;
176 		}
177 
178 		public List<?> getColumnValues() {
179 			return columnValues;
180 		}
181 	}
182 
183 	/**
184      *
185      */
186 	public class ColumnValue {
187 		private Column col;
188 		private String val;
189 
190 		public ColumnValue(Column col, String val) {
191 			this.col = col;
192 			this.val = val;
193 		}
194 
195 		public Column getColumn() {
196 			return col;
197 		}
198 
199 		public String getValue() {
200 			return val;
201 		}
202 
203 		public String getEscapedValue() {
204 			StringBuffer sb = new StringBuffer();
205 			sb.append("'");
206 			sb.append(StringUtils.replace(val, "'", "''"));
207 			sb.append("'");
208 			return sb.toString();
209 		}
210 	}
211 }