View Javadoc

1   package org.apache.torque.engine.database.transform;
2   
3   /*
4    * Copyright 2001-2005 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License")
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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                 //ignore <dataset> for now.
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 }