1 package org.apache.torque.engine.database.transform;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.io.BufferedReader;
20 import java.io.File;
21 import java.io.FileReader;
22 import java.io.IOException;
23 import java.net.MalformedURLException;
24 import java.net.URL;
25 import java.util.ArrayList;
26 import java.util.List;
27
28 import javax.xml.parsers.SAXParser;
29 import javax.xml.parsers.SAXParserFactory;
30
31 import org.apache.commons.lang.StringUtils;
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.torque.engine.database.model.Column;
35 import org.apache.torque.engine.database.model.Database;
36 import org.apache.torque.engine.database.model.Table;
37 import org.xml.sax.Attributes;
38 import org.xml.sax.EntityResolver;
39 import org.xml.sax.InputSource;
40 import org.xml.sax.SAXException;
41 import org.xml.sax.helpers.DefaultHandler;
42
43 /***
44 * A Class that is used to parse an input xml schema file and creates and
45 * AppData java structure.
46 *
47 * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a>
48 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
49 * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
50 * @author <a href="mailto:fedor.karpelevitch@home.com">Fedor Karpelevitch</a>
51 * @version $Id: XmlToData.java 239626 2005-08-24 12:19:51Z henning $
52 */
53 public class XmlToData extends DefaultHandler implements EntityResolver
54 {
55 /*** Logging class from commons.logging */
56 private static Log log = LogFactory.getLog(XmlToData.class);
57 private Database database;
58 private List data;
59 private String dtdFileName;
60 private File dtdFile;
61 private InputSource dataDTD;
62
63 private static SAXParserFactory saxFactory;
64
65 static
66 {
67 saxFactory = SAXParserFactory.newInstance();
68 saxFactory.setValidating(true);
69 }
70
71 /***
72 * Default custructor
73 */
74 public XmlToData(Database database, String dtdFilePath)
75 throws MalformedURLException, IOException
76 {
77 this.database = database;
78 dtdFile = new File(dtdFilePath);
79 this.dtdFileName = "file://" + dtdFile.getName();
80 dataDTD = new InputSource(dtdFile.toURL().openStream());
81 }
82
83 /***
84 *
85 */
86 public List parseFile(String xmlFile)
87 throws Exception
88 {
89 data = new ArrayList();
90
91 SAXParser parser = saxFactory.newSAXParser();
92
93 FileReader fr = new FileReader (xmlFile);
94 BufferedReader br = new BufferedReader (fr);
95 try
96 {
97 InputSource is = new InputSource (br);
98 parser.parse(is, this);
99 }
100 finally
101 {
102 br.close();
103 }
104 return data;
105 }
106
107 /***
108 * Handles opening elements of the xml file.
109 */
110 public void startElement(String uri, String localName, String rawName,
111 Attributes attributes)
112 throws SAXException
113 {
114 try
115 {
116 if (rawName.equals("dataset"))
117 {
118
119 }
120 else
121 {
122 Table table = database.getTableByJavaName(rawName);
123
124 if (table == null)
125 {
126 throw new SAXException("Table '" + rawName + "' unknown");
127 }
128 List columnValues = new ArrayList();
129 for (int i = 0; i < attributes.getLength(); i++)
130 {
131 Column col = table
132 .getColumnByJavaName(attributes.getQName(i));
133
134 if (col == null)
135 {
136 throw new SAXException("Column "
137 + attributes.getQName(i) + " in table "
138 + rawName + " unknown.");
139 }
140
141 String value = attributes.getValue(i);
142 columnValues.add(new ColumnValue(col, value));
143 }
144 data.add(new DataRow(table, columnValues));
145 }
146 }
147 catch (Exception e)
148 {
149 throw new SAXException(e);
150 }
151 }
152
153 /***
154 * called by the XML parser
155 *
156 * @return an InputSource for the database.dtd file
157 */
158 public InputSource resolveEntity(String publicId, String systemId)
159 throws SAXException
160 {
161 try
162 {
163 if (dataDTD != null && dtdFileName.equals(systemId))
164 {
165 log.info("Resolver: used " + dtdFile.getPath());
166 return dataDTD;
167 }
168 else
169 {
170 log.info("Resolver: used " + systemId);
171 return getInputSource(systemId);
172 }
173 }
174 catch (IOException e)
175 {
176 throw new SAXException(e);
177 }
178 }
179
180 /***
181 * get an InputSource for an URL String
182 *
183 * @param urlString
184 * @return an InputSource for the URL String
185 */
186 public InputSource getInputSource(String urlString)
187 throws IOException
188 {
189 URL url = new URL(urlString);
190 InputSource src = new InputSource(url.openStream());
191 return src;
192 }
193
194 /***
195 *
196 */
197 public class DataRow
198 {
199 private Table table;
200 private List columnValues;
201
202 public DataRow(Table table, List columnValues)
203 {
204 this.table = table;
205 this.columnValues = columnValues;
206 }
207
208 public Table getTable()
209 {
210 return table;
211 }
212
213 public List getColumnValues()
214 {
215 return columnValues;
216 }
217 }
218
219 /***
220 *
221 */
222 public class ColumnValue
223 {
224 private Column col;
225 private String val;
226
227 public ColumnValue(Column col, String val)
228 {
229 this.col = col;
230 this.val = val;
231 }
232
233 public Column getColumn()
234 {
235 return col;
236 }
237
238 public String getValue()
239 {
240 return val;
241 }
242
243 public String getEscapedValue()
244 {
245 StringBuffer sb = new StringBuffer();
246 sb.append("'");
247 sb.append(StringUtils.replace(val, "'", "''"));
248 sb.append("'");
249 return sb.toString();
250 }
251 }
252 }