001     /*
002     * Copyright 2001,2004 The Apache Software Foundation.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.apache.commons.scaffold.lucene;
018    
019    
020    import java.util.ArrayList;
021    import java.util.Collection;
022    import java.util.Enumeration;
023    import java.util.HashMap;
024    
025    import org.apache.commons.beanutils.BeanUtils;
026    import org.apache.commons.scaffold.lang.PopulateException;
027    
028    import org.apache.lucene.document.Document;
029    import org.apache.lucene.document.Field;
030    import org.apache.lucene.search.Hits;
031    
032    
033     /**
034      * General purpose utility methods related to Hits
035      *
036      * @author Craig R. McClanahan
037      * @author Ted Husted
038      * @version $Revision: 155464 $ $Date: 2005-02-26 13:26:54 +0000 (Sat, 26 Feb 2005) $
039      */
040     public class SearchUtils {
041    
042        /**
043         * Populate the properties of the specified JavaBean from the specified
044         * Lucene document, based on matching each parameter name against the
045         * corresponding JavaBeans "property setter" methods in the bean's class.
046         * See <code>BeanUtils.CopyProperites</code> for more about automatic 
047         * conversion between types.
048         *
049         * @param bean The JavaBean whose properties are to be set
050         * @param document The Lucene document whose parameters are to be used
051         * to populate bean properties
052         * @exception PopulateException if an exception is thrown while setting
053         * property values
054         */
055        public static void populate(
056                Object bean,
057                Document document)
058            throws PopulateException {
059    
060            // Build a list of relevant fields and values
061            HashMap properties = new HashMap();
062    
063            // Iterator of field names
064            Enumeration fields = document.fields();
065    
066            while (fields.hasMoreElements()) {
067                Field field = (Field) fields.nextElement();
068                properties.put(field.name(),field.stringValue());
069            }
070    
071            // Set the corresponding properties of our bean
072            try {
073                BeanUtils.copyProperties(bean, properties);
074            } catch (Throwable t) {
075                throw new PopulateException(t);
076            }
077    
078        } // end populate()
079    
080    
081        /**
082          * Return a ArrayList of hits by looping and calling populate.
083          * No assumptions are made about fields in document. Each is
084          * processed with a separate call to populate. Whatever fields
085          * in each document that match the target bean will be
086          * transferred.
087          *
088          * @param hits The Hits whose documents are to be used
089          * to populate bean properties
090          * @param target An instance of the bean to populate
091          * @exception PopulateException if an exception is thrown while setting
092          * property values, populating the bean, or accessing the Hits
093          */
094         public static Collection getCollection(
095                Object target,
096                Hits hits)
097            throws PopulateException {
098    
099            // Use ArrayList to maintain sequence
100            ArrayList list = new ArrayList();
101    
102            // Acquire target class
103            Class factory = target.getClass();
104    
105            try {
106                // Scroll to each document; populate bean, and add to list
107                for (int i=0; i<hits.length(); ++i) {
108                    Object bean = factory.newInstance();
109                    Document doc = hits.doc(i);
110                    populate(bean,doc);
111                    list.add(bean);
112                }
113            } catch (Throwable t) {
114                throw new PopulateException(t);
115            }
116            return ((Collection) list);
117    
118        } // end getCollection()
119    
120    } // end SearchUtils
121