001 package com.croftsoft.core.text.sml; 002 003 import java.io.*; 004 import java.util.*; 005 import java.util.zip.*; 006 import javax.xml.parsers.*; 007 import org.xml.sax.*; 008 import org.xml.sax.helpers.*; 009 010 import com.croftsoft.core.lang.NullArgumentException; 011 import com.croftsoft.core.text.sml.SmlNode; 012 import com.croftsoft.core.util.consumer.Consumer; 013 014 /********************************************************************* 015 * Used to parse large SML files one data record at a time. 016 * 017 * <p> 018 * This class is similar to SmlNodeLoader except that is uses an XML 019 * parser instead of the SML parser. 020 * </p> 021 * 022 * @version 023 * 2002-09-24 024 * @since 025 * 2002-09-18 026 * @author 027 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 028 *********************************************************************/ 029 030 public final class SmlRecordLoader 031 extends DefaultHandler 032 ////////////////////////////////////////////////////////////////////// 033 ////////////////////////////////////////////////////////////////////// 034 { 035 036 private final Consumer smlRecordConsumer; 037 038 private final Stack parentNodeStack; 039 040 // 041 042 private int depth; 043 044 private SmlNode smlNode; 045 046 ////////////////////////////////////////////////////////////////////// 047 ////////////////////////////////////////////////////////////////////// 048 049 public static void main ( String [ ] args ) 050 throws Exception 051 ////////////////////////////////////////////////////////////////////// 052 { 053 parse ( 054 args [ 0 ], 055 new Consumer ( ) 056 { 057 public void consume ( Object o ) 058 { 059 System.out.println ( o ); 060 061 System.out.println ( "" ); 062 } 063 }, 064 args [ 0 ].toLowerCase ( ).endsWith ( ".zip" ), 065 args [ 0 ].toLowerCase ( ).endsWith ( ".gz" ) ); 066 } 067 068 ////////////////////////////////////////////////////////////////////// 069 ////////////////////////////////////////////////////////////////////// 070 071 public static void parse ( 072 InputSource inputSource, 073 Consumer smlRecordConsumer ) 074 throws IOException, ParserConfigurationException, SAXException 075 ////////////////////////////////////////////////////////////////////// 076 { 077 NullArgumentException.check ( inputSource ); 078 079 NullArgumentException.check ( smlRecordConsumer ); 080 081 SAXParserFactory saxParserFactory 082 = SAXParserFactory.newInstance ( ); 083 084 SAXParser saxParser = saxParserFactory.newSAXParser ( ); 085 086 saxParser.parse ( 087 inputSource, new SmlRecordLoader ( smlRecordConsumer ) ); 088 } 089 090 public static void parse ( 091 String smlDataFilename, 092 Consumer smlRecordConsumer, 093 boolean isZipFile, 094 boolean isGzipFile ) 095 throws IOException, ParserConfigurationException, SAXException 096 ////////////////////////////////////////////////////////////////////// 097 { 098 InputStream inputStream = null; 099 100 try 101 { 102 inputStream = new FileInputStream ( smlDataFilename ); 103 104 if ( isZipFile ) 105 { 106 ZipInputStream zipInputStream 107 = new ZipInputStream ( inputStream ); 108 109 zipInputStream.getNextEntry ( ); 110 111 inputStream = zipInputStream; 112 } 113 else if ( isGzipFile ) 114 { 115 inputStream = new GZIPInputStream ( inputStream ); 116 } 117 118 InputSource inputSource = new InputSource ( 119 new BufferedReader ( new InputStreamReader ( inputStream ) ) ); 120 121 parse ( inputSource, smlRecordConsumer ); 122 } 123 finally 124 { 125 if ( inputStream != null ) 126 { 127 inputStream.close ( ); 128 } 129 } 130 } 131 132 ////////////////////////////////////////////////////////////////////// 133 ////////////////////////////////////////////////////////////////////// 134 135 private SmlRecordLoader ( Consumer smlRecordConsumer ) 136 ////////////////////////////////////////////////////////////////////// 137 { 138 NullArgumentException.check ( 139 this.smlRecordConsumer = smlRecordConsumer ); 140 141 parentNodeStack = new Stack ( ); 142 } 143 144 ////////////////////////////////////////////////////////////////////// 145 ////////////////////////////////////////////////////////////////////// 146 147 public void startElement ( 148 String namespaceURI, 149 String localName, 150 String qName, 151 Attributes atts ) 152 ////////////////////////////////////////////////////////////////////// 153 { 154 depth++; 155 156 if ( depth == 2 ) 157 { 158 smlNode = new SmlNode ( qName ); 159 } 160 else if ( depth > 2 ) 161 { 162 SmlNode childNode = new SmlNode ( qName ); 163 164 Object firstChild = smlNode.getChild ( 0 ); 165 166 if ( firstChild instanceof String ) 167 { 168 smlNode.getChildren ( ) [ 0 ] = childNode; 169 } 170 else 171 { 172 smlNode.add ( childNode ); 173 } 174 175 parentNodeStack.push ( smlNode ); 176 177 smlNode = childNode; 178 } 179 } 180 181 public void characters ( 182 char [ ] ch, 183 int start, 184 int length ) 185 ////////////////////////////////////////////////////////////////////// 186 { 187 if ( smlNode != null ) 188 { 189 Object firstChild = smlNode.getChild ( 0 ); 190 191 if ( firstChild == null ) 192 { 193 smlNode.add ( new String ( ch, start, length ) ); 194 } 195 else if ( firstChild instanceof String ) 196 { 197 smlNode.getChildren ( ) [ 0 ] 198 = firstChild + new String ( ch, start, length ); 199 } 200 } 201 } 202 203 public void endElement ( 204 String namespaceURI, 205 String localName, 206 String qName ) 207 ////////////////////////////////////////////////////////////////////// 208 { 209 depth--; 210 211 if ( depth > 1 ) 212 { 213 smlNode = ( SmlNode ) parentNodeStack.pop ( ); 214 } 215 else if ( depth == 1 ) 216 { 217 smlRecordConsumer.consume ( smlNode ); 218 219 smlNode = null; 220 } 221 } 222 223 /* 224 public void error ( SAXParseException e ) 225 throws SAXException 226 ////////////////////////////////////////////////////////////////////// 227 { 228 System.out.println ( "Parse error on node " + smlNode ); 229 230 super.error ( e ); 231 } 232 233 public void fatalError ( SAXParseException e ) 234 throws SAXException 235 ////////////////////////////////////////////////////////////////////// 236 { 237 System.out.println ( "Fatal parse error on node " + smlNode ); 238 239 super.fatalError ( e ); 240 } 241 */ 242 243 ////////////////////////////////////////////////////////////////////// 244 ////////////////////////////////////////////////////////////////////// 245 }