package com.manning.hsia.dvdstore;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.hibernate.search.SearchException;
import org.hibernate.search.bridge.FieldBridge;
import org.hibernate.search.bridge.LuceneOptions;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.io.StringReader;
import java.util.*;
public class SaxExampleBridge extends DefaultHandler implements FieldBridge {
public void set( String name,
Object value,
Document document,
LuceneOptions options ) {
CD cd = (CD) value;
String xml = cd.getPriceData();
if ( xml == null ) {
return;
}
InputSource source = new InputSource( new StringReader( xml ) );
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
SaxHandler handler = new SaxHandler( options, document );
parser.parse( source, handler );
}
catch (SAXException s) {
throw ( new SearchException( "unable to read cd price data", s ) );
}
catch (ParserConfigurationException p) {
throw ( new SearchException( "unable to read cd price data", p ) );
}
catch (IOException i) {
throw ( new SearchException( "unable to read cd price data", i ) );
}
}
/**
* FieldBridge implementations must be thread safe. So it is necessary to
* parse the xml in its own instance of a handler to guarantee this.
*/
private class SaxHandler extends DefaultHandler {
Map<String, String> attrs;
List<Field> mFieldList = new ArrayList<Field>();
Field.Store mStore;
Field.Index mIndex;
Field.TermVector mVector;
Float mBoost;
Document mDocument;
StringBuilder text = new StringBuilder();
public SaxHandler( LuceneOptions options, Document document ) {
mStore = options.getStore();
mIndex = options.getIndex();
mVector = options.getTermVector();
mBoost = options.getBoost();
mDocument = document;
}
public void startElement( String uri, String localName, String qName, Attributes attributes ) {
text.delete( 0, text.length() );
if ( attributes.getLength() > 0 ) {
attrs = new HashMap<String, String>();
for (int x = 0; x < attributes.getLength(); x++) {
attrs.put( attributes.getQName( x ), attributes.getValue( x ) );
}
}
}
public void endElement( String uri, String localName, String qName ) {
if ( !qName.equals( "CD" ) ) {
Field field = new Field( qName.toLowerCase(), text.toString(), mStore, mIndex, mVector );
if ( mBoost != null ) field.setBoost( mBoost );
mFieldList.add( field );
if ( attrs.size() > 0 ) {
Set<String> keys = attrs.keySet();
for (String key : keys) {
String attrValue = attrs.get( key );
field = new Field( key.toLowerCase(), attrValue, mStore, mIndex, mVector );
mFieldList.add( field );
}
attrs.clear();
}
}
}
public void characters( char[] ch, int start, int length ) {
text.append( ch, start, length );
}
public void startDocument() {
mFieldList.clear();
}
public void endDocument() {
for (Field f : mFieldList) {
mDocument.add( f );
}
}
}
}