View Javadoc

1   /*
2    * Copyright (c) 2003 by Atlassian Software Systems Pty. Ltd.
3    * All rights reserved.
4    */
5   package com.atlassian.bonnie.search.extractor;
6   
7   import org.dom4j.io.SAXReader;
8   import org.dom4j.*;
9   import org.slf4j.LoggerFactory;
10  import org.slf4j.Logger;
11  
12  import java.io.InputStream;
13  import java.util.*;
14  
15  import com.atlassian.bonnie.LuceneException;
16  
17  final class XmlClassConfigurations
18  {
19      private static final Logger log = LoggerFactory.getLogger(XmlClassConfigurations.class);
20      //~ Static variables/initializers ----------------------------------------------------------------------------------
21  
22      private static Map<String, ClassConfiguration> classConfigurations = new HashMap<String, ClassConfiguration>();
23      private static List<Class<?>> unconfiguredClasses = new ArrayList<Class<?>>();
24  
25      //~ Methods --------------------------------------------------------------------------------------------------------
26  
27      private static void addClassConfiguration(Class<?> clazz, ClassConfiguration classConfiguration)
28      {
29          classConfigurations.put(clazz.getName(), classConfiguration);
30      }
31  
32      @SuppressWarnings("unchecked")
33      private static ClassConfiguration loadClassConfiguration(Class<?> clazz)
34      {
35          InputStream configXml = loadConfigFile(clazz);
36  
37          if (configXml == null)
38          {
39              unconfiguredClasses.add(clazz);
40              log.debug("Lucene configuration file not found for class: " + clazz.toString());
41              return null;
42          }
43  
44          ClassConfiguration newClassConfig = new ClassConfiguration();
45  
46          try
47          {
48              SAXReader reader = new SAXReader();
49              Document doc = reader.read(configXml);
50              XPath mapXPath = DocumentHelper.createXPath("/configuration/field");
51              List<Element> mappings = (List<Element>) mapXPath.selectNodes(doc);
52              for (Element mappingNode : mappings)
53              {
54                  FieldConfiguration mapping = new FieldConfiguration();
55                  mapping.setType(safeStringAttributeGet(mappingNode, "type"));
56                  mapping.setFieldName(safeStringAttributeGet(mappingNode, "fieldName"));
57                  mapping.setAttributeName(safeStringAttributeGet(mappingNode, "attributeName"));
58                  mapping.setAppendToDefaultSearchableText(safeBooleanAttributeGet(mappingNode,
59                          "appendToDefaultSearchableText"));
60                  newClassConfig.addFieldConfiguration(mapping);
61              }
62  
63              addClassConfiguration(clazz, newClassConfig);
64  
65              return newClassConfig;
66          }
67          catch (Exception e)
68          {
69              throw new LuceneException("Couldn't load lucene config file successfully, file=" + clazz, e);
70          }
71      }
72  
73      private static String safeStringAttributeGet(Element mappingNode, String attributeName)
74      {
75          Attribute attribute = mappingNode.attribute(attributeName);
76          if (attribute != null && attribute.getValue() != null && !"".equals(attribute.getValue()))
77              return attribute.getValue();
78          else
79              return null;
80      }
81  
82      /**
83       * 
84       * @param mappingNode the element to extract attribute values from
85       * @param attributeName the name of the attribute who's value is required.
86       * @return the value of the specified attributeName as a boolean. If the attribute doesn't exist or has any value
87       *         other than true/TRUE then false will be returned.
88       */
89      private static boolean safeBooleanAttributeGet(Element mappingNode, String attributeName)
90      {
91          Attribute attribute = mappingNode.attribute(attributeName);
92          if (attribute == null)
93              return false;
94  
95          return Boolean.valueOf(attribute.getValue());
96      }
97  
98      private static InputStream loadConfigFile(Class<?> clazz)
99      {
100         String configFileName = clazz.getName().replace('.', '/') + ".lucene.xml";
101         return Thread.currentThread().getContextClassLoader().getResourceAsStream(configFileName);
102     }
103 
104     public static ClassConfiguration getClassConfiguration(Class<?> clazz)
105     {
106         ClassConfiguration classConfig;
107 
108         synchronized (classConfigurations)
109         {
110             classConfig = (ClassConfiguration) classConfigurations.get(clazz.getName());
111 
112             if (classConfig == null && !unconfiguredClasses.contains(clazz))
113                 classConfig = loadClassConfiguration(clazz);
114         }
115 
116         return classConfig;
117     }
118 
119     //~ Classes --------------------------------------------------------------------------------------------------------
120 
121     public static final class ClassConfiguration
122     {
123         private List<FieldConfiguration> fieldConfigurations = new ArrayList<FieldConfiguration>();
124 
125         public void addFieldConfiguration(FieldConfiguration fieldConfiguration)
126         {
127             fieldConfigurations.add(fieldConfiguration);
128         }
129 
130         public List<FieldConfiguration> getFieldConfigurations()
131         {
132             return fieldConfigurations;
133         }
134     }
135 
136     public static final class FieldConfiguration
137     {
138         public static final String TYPE_TEXT = "Text";
139         public static final String TYPE_KEYWORD = "Keyword";
140         public static final String TYPE_UNINDEXED = "UnIndexed";
141         public static final String TYPE_UNSTORED = "UnStored";
142         private String type;
143         private String fieldName;
144         private String attributeName;
145         private boolean appendToDefaultSearchableText;
146 
147         public String getType()
148         {
149             return type;
150         }
151 
152         public void setType(String type)
153         {
154             this.type = type;
155         }
156 
157         public String getFieldName()
158         {
159             return fieldName;
160         }
161 
162         public void setFieldName(String fieldName)
163         {
164             this.fieldName = fieldName;
165         }
166 
167         public String getAttributeName()
168         {
169             return attributeName;
170         }
171 
172         public void setAttributeName(String attributeName)
173         {
174             this.attributeName = attributeName;
175         }
176 
177         /**
178          * @return true if the attribute(s) specified should be appended to the default searchable text. Note that if
179          *         you specify multiple attributes then just as all will be added to the same document field, they will
180          *         also all be added to the default searchable text if this is true.
181          */
182         public boolean isAppendToDefaultSearchableText()
183         {
184             return appendToDefaultSearchableText;
185         }
186 
187         public void setAppendToDefaultSearchableText(boolean appendToDefaultContent)
188         {
189             this.appendToDefaultSearchableText = appendToDefaultContent;
190         }
191     }
192 }