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