1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.jackrabbit.lucene;
35
36 import java.io.File;
37 import java.util.ArrayList;
38 import java.util.Collection;
39 import java.util.List;
40 import java.util.Properties;
41
42 import javax.jcr.NamespaceException;
43
44 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
45 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistryListener;
46 import org.apache.jackrabbit.core.nodetype.xml.AdditionalNamespaceResolver;
47 import org.apache.jackrabbit.core.query.QueryHandlerContext;
48 import org.apache.jackrabbit.core.query.lucene.IndexingConfiguration;
49 import org.apache.jackrabbit.core.query.lucene.NamespaceMappings;
50 import org.apache.jackrabbit.spi.Name;
51 import org.apache.jackrabbit.spi.commons.conversion.IllegalNameException;
52 import org.apache.jackrabbit.spi.commons.conversion.NameResolver;
53 import org.apache.jackrabbit.spi.commons.conversion.ParsingNameResolver;
54 import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
55 import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58 import org.w3c.dom.Attr;
59 import org.w3c.dom.Element;
60 import org.w3c.dom.NamedNodeMap;
61 import org.w3c.dom.Node;
62 import org.w3c.dom.NodeList;
63
64
65
66
67 public class SearchIndex extends org.apache.jackrabbit.core.query.lucene.SearchIndex {
68
69 private static final Logger log = LoggerFactory.getLogger(SearchIndex.class);
70
71 static final String DEPRECATED_INDEXING_CONFIGURATION = "/info/magnolia/jackrabbit/indexing_configuration.xml";
72 static final String DEFAULT_INDEXING_CONFIGURATION = "/info/magnolia/jackrabbit/indexing_configuration_default.xml";
73 static final String WEBSITE_INDEXING_CONFIGURATION = "/info/magnolia/jackrabbit/indexing_configuration_website.xml";
74
75 @Override
76 public void setIndexingConfiguration(String path) {
77 if (DEPRECATED_INDEXING_CONFIGURATION.equals(path)) {
78 log.info("You are using deprecated indexing configuration {{}}. We suggest to use {{}} or {{}} instead.", DEPRECATED_INDEXING_CONFIGURATION, DEFAULT_INDEXING_CONFIGURATION, WEBSITE_INDEXING_CONFIGURATION);
79 }
80 String existingPath = path;
81 if (!new File(existingPath).exists() && getClass().getResourceAsStream(existingPath) == null) {
82 existingPath = DEFAULT_INDEXING_CONFIGURATION;
83 log.info("Workspace specific indexing configuration {{}} was not found. Will use {{}} instead.", path, existingPath);
84 }
85 super.setIndexingConfiguration(existingPath);
86 }
87
88
89
90
91
92
93 @Override
94 protected IndexingConfiguration createIndexingConfiguration(NamespaceMappings namespaceMappings) {
95 Element docElement = getIndexingConfigurationDOM();
96 if (docElement == null) {
97 return null;
98 }
99 try {
100 Class<?> indexingConfigurationClass = Class.forName(getIndexingConfigurationClass());
101 IndexingConfiguration idxCfg = (IndexingConfiguration)
102 indexingConfigurationClass.newInstance();
103 initIndexingConfiguration(idxCfg, docElement, getContext(), namespaceMappings);
104 return idxCfg;
105 } catch (Exception e) {
106 log.warn("Exception initializing indexing configuration from: "
107 + getIndexingConfiguration(), e);
108 }
109 log.warn(getIndexingConfiguration() + " ignored.");
110 return null;
111 }
112
113
114
115
116 private void initIndexingConfiguration(IndexingConfiguration indexingConfiguration, Element config, QueryHandlerContext context, NamespaceMappings namespaceMappings) throws Exception {
117 List<Name> unRegisteredNodeTypes = getUnRegisteredNodeTypes(config);
118 if (unRegisteredNodeTypes.isEmpty()) {
119 indexingConfiguration.init(config, context, namespaceMappings);
120 return;
121 }
122 context.getNodeTypeRegistry().addListener(
123 new NodeTypeRegistryListener() {
124 @Override
125 public void nodeTypeRegistered(Name ntName) {
126 if (unRegisteredNodeTypes.contains(ntName)) {
127 unRegisteredNodeTypes.remove(ntName);
128 }
129 if (unRegisteredNodeTypes.isEmpty()) {
130 context.getNodeTypeRegistry().removeListener(this);
131 try {
132 indexingConfiguration.init(config, context, namespaceMappings);
133 } catch (Exception e) {
134 log.warn("Exception initializing indexing configuration from: "
135 + getIndexingConfiguration(), e);
136 }
137 }
138 }
139
140 @Override
141 public void nodeTypeReRegistered(Name ntName) {
142
143 }
144
145 @Override
146 public void nodeTypesUnregistered(Collection<Name> names) {
147
148 }
149 }
150 );
151 }
152
153
154
155
156 private List<Name> getUnRegisteredNodeTypes(Element indexingConfiguration) throws
157 NamespaceException, IllegalNameException {
158 List<Name> unRegisteredNodeTypes = new ArrayList<>();
159 NamespaceResolver nsResolver = new AdditionalNamespaceResolver(getNamespaces(indexingConfiguration));
160 NameResolver resolver = new ParsingNameResolver(NameFactoryImpl.getInstance(), nsResolver);
161 NodeTypeRegistry ntReg = getContext().getNodeTypeRegistry();
162 NodeList indexingConfigs = indexingConfiguration.getChildNodes();
163 for (int i = 0; i < indexingConfigs.getLength(); i++) {
164 Node configNode = indexingConfigs.item(i);
165 if (configNode.getNodeName().equals("index-rule")) {
166 String ntString = configNode.getAttributes().getNamedItem("nodeType").getNodeValue();
167 Name nodeType = resolver.getQName(ntString);
168 if (!ntReg.isRegistered(nodeType)) {
169 unRegisteredNodeTypes.add(nodeType);
170 }
171 }
172 }
173 return unRegisteredNodeTypes;
174 }
175
176
177
178
179
180
181
182 private Properties getNamespaces(Node node) {
183 Properties namespaces = new Properties();
184 NamedNodeMap attributes = node.getAttributes();
185 for (int i = 0; i < attributes.getLength(); i++) {
186 Attr attribute = (Attr) attributes.item(i);
187 if (attribute.getName().startsWith("xmlns:")) {
188 namespaces.setProperty(
189 attribute.getName().substring(6), attribute.getValue());
190 }
191 }
192 return namespaces;
193 }
194 }