/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springmodules.lucene.index.document.handler.object; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.Set; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.beans.factory.InitializingBean; import org.springframework.core.io.Resource; import org.springmodules.lucene.util.IOUtils; /** * Implementation of the DocumentHandler interface which allows to index an * object based on a configuration in a properties file. * * In order to make participate a bean in the indexing, the following line must * be present in the properties file: * MyClass.indexable=true * * Then, for each field of the class, the different properties must be set: * MyClass.field.myField.indexable=true * MyClass.field.myField.type=Text * MyClass.field.myField.indexable=true * * @author Thierry Templier */ public class PropertiesDocumentHandler extends AbstractAttributeObjectDocumentHandler implements InitializingBean { private static final String ELEMENT_SEPARATOR = "."; private static final String FIELD_SEPARATOR = "field"; private static final String FIELD_ELEMENT_SEPARATOR = ".field."; private Properties properties; private Resource propertiesFileName; private void loadPropertiesIfNecessary() { if( properties==null ) { properties=IOUtils.loadPropertiesFromResource(propertiesFileName); } } /** * Returns all the properties found for the given method. */ protected Collection findAllAttributes(Method method) { loadPropertiesIfNecessary(); Collection attributes=new ArrayList(); Set keys=properties.keySet(); for(Iterator i=keys.iterator();i.hasNext();) { String key=(String)i.next(); String fieldName=method.getName(); if( fieldName.startsWith(PREFIX_ACCESSOR) ) { fieldName=constructFieldName(fieldName); } if( key.startsWith(method.getDeclaringClass().getName()) && key.indexOf(ELEMENT_SEPARATOR+fieldName+ELEMENT_SEPARATOR)!=-1 ) { String value=(String)properties.get(key); attributes.add(new AttributeData(key,value)); } } return attributes; } /** * Returns all the properties found for the given class. */ protected Collection findAllAttributes(Class clazz) { loadPropertiesIfNecessary(); Collection attributes=new ArrayList(); Set keys=properties.keySet(); for(Iterator i=keys.iterator();i.hasNext();) { String key=(String)i.next(); if( key.startsWith(clazz.getName()) && key.indexOf(FIELD_ELEMENT_SEPARATOR)==-1 ) { String value=(String)properties.get(key); attributes.add(new AttributeData(key,value)); } } return attributes; } protected IndexAttribute findIndexAttribute(Collection atts) { if (atts == null) { return null; } Map attsMap=new HashMap(); for (Iterator i=atts.iterator();i.hasNext();) { AttributeData data=(AttributeData)i.next(); String attributeName=data.getAttributeName(); int indice=-1; if( (indice=attributeName.indexOf(FIELD_SEPARATOR))!=-1 ) { attributeName=attributeName.substring(indice+7); if( (indice=attributeName.indexOf(ELEMENT_SEPARATOR))!=-1 ) { attributeName=attributeName.substring(indice+1); } } attsMap.put(attributeName,data.getAttributeValue()); } if( attsMap.size()==0 ) { return null; } else { DefaultIndexAttribute dia = new DefaultIndexAttribute(); String name=(String)attsMap.get("name"); if( name==null ) { name=""; } dia.setName(name); String type=(String)attsMap.get("type"); if( type==null ) { type="Text"; } if( type!=null ) { type=type.toLowerCase(); } dia.setType(type); String exclude=(String)attsMap.get("exclude"); if( exclude!=null ) { dia.setExcluded(exclude.equals("true")); } return dia; } } protected Object findIndexClassProperty(Class clazz) { loadPropertiesIfNecessary(); String value=(String)properties.get(clazz.getName()+".indexable"); if( value!=null && "true".equals(value) ) { return INDEXABLE_CLASS; } else { return NON_INDEXABLE_CLASS; } } public Resource getPropertiesFileName() { return propertiesFileName; } public void setPropertiesFileName(Resource propertiesFileName) { this.propertiesFileName = propertiesFileName; } private class AttributeData { private String attributeName; private String attributeValue; public AttributeData(String attributeName, String attributeValue) { this.attributeName=attributeName; this.attributeValue=attributeValue; } public String getAttributeName() { return attributeName; } public void setAttributeName(String attributeName) { this.attributeName = attributeName; } public String getAttributeValue() { return attributeValue; } public void setAttributeValue(String attributeValue) { this.attributeValue = attributeValue; } } public void afterPropertiesSet() throws Exception { if (propertiesFileName == null) { throw new BeanInitializationException( "Must specify a name of a property file"); } } }