View Javadoc

1   package org.apache.torque.engine.database.transform;
2   
3   /*
4    * Copyright 2001-2004 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. <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                 //ignore <dataset> for now.
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 }