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