mirror of https://github.com/apache/lucene.git
SOLR-716 -- Added support for properties in configuration files.
git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@688359 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b355f57d80
commit
cc32fc4d32
|
@ -345,6 +345,10 @@ New Features
|
|||
|
||||
69. SOLR-506: Emitting HTTP Cache headers can be enabled or disabled through configuration
|
||||
on a per-handler basis (shalin)
|
||||
|
||||
70. SOLR-716: Added support for properties in configuration files. Properties can be specified in solr.xml
|
||||
and can be used in solrconfig.xml and schema.xml
|
||||
(Henri Biestro, hossman, ryan, shalin)
|
||||
|
||||
Changes in runtime behavior
|
||||
1. SOLR-559: use Lucene updateDocument, deleteDocuments methods. This
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.apache.solr.client.solrj.embedded;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.request.CoreAdminRequest;
|
||||
import org.apache.solr.client.solrj.request.QueryRequest;
|
||||
import org.apache.solr.client.solrj.request.UpdateRequest;
|
||||
import org.apache.solr.client.solrj.request.UpdateRequest.ACTION;
|
||||
import org.apache.solr.client.solrj.response.CoreAdminResponse;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
import org.apache.solr.core.CoreContainer;
|
||||
import org.apache.solr.util.AbstractSolrTestCase;
|
||||
import org.junit.After;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* @version $Id$
|
||||
* @since solr 1.3
|
||||
*/
|
||||
public class TestSolrProperties {
|
||||
protected static Logger log = Logger.getLogger(TestSolrProperties.class.getName());
|
||||
protected CoreContainer cores = null;
|
||||
|
||||
public String getSolrHome() {
|
||||
return "solr/shared";
|
||||
}
|
||||
|
||||
public String getSolrXml() {
|
||||
return "solr.xml";
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
System.setProperty("solr.solr.home", getSolrHome());
|
||||
|
||||
log.info("pwd: " + (new File(".")).getAbsolutePath());
|
||||
File home = new File(getSolrHome());
|
||||
File f = new File(home, "solr.xml");
|
||||
cores = new CoreContainer(getSolrHome(), f);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (cores != null)
|
||||
cores.shutdown();
|
||||
File dataDir = new File(getSolrHome() + "/data");
|
||||
String skip = System.getProperty("solr.test.leavedatadir");
|
||||
if (null != skip && 0 != skip.trim().length()) {
|
||||
log.info("NOTE: per solr.test.leavedatadir, dataDir will not be removed: " + dataDir.getAbsolutePath());
|
||||
} else {
|
||||
if (!AbstractSolrTestCase.recurseDelete(dataDir)) {
|
||||
log.warning("!!!! WARNING: best effort to remove " + dataDir.getAbsolutePath() + " FAILED !!!!!");
|
||||
}
|
||||
}
|
||||
File persistedFile = new File("solr-persist.xml");
|
||||
persistedFile.delete();
|
||||
}
|
||||
|
||||
protected SolrServer getSolrCore0() {
|
||||
return new EmbeddedSolrServer(cores, "core0");
|
||||
}
|
||||
|
||||
|
||||
protected SolrServer getSolrCore1() {
|
||||
return new EmbeddedSolrServer(cores, "core1");
|
||||
}
|
||||
|
||||
protected SolrServer getSolrAdmin() {
|
||||
return new EmbeddedSolrServer(cores, "core0");
|
||||
}
|
||||
|
||||
protected SolrServer getSolrCore(String name) {
|
||||
return new EmbeddedSolrServer(cores, name);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProperties() throws Exception {
|
||||
UpdateRequest up = new UpdateRequest();
|
||||
up.setAction(ACTION.COMMIT, true, true);
|
||||
up.deleteByQuery("*:*");
|
||||
up.process(getSolrCore0());
|
||||
up.process(getSolrCore1());
|
||||
up.clear();
|
||||
|
||||
// Add something to each core
|
||||
SolrInputDocument doc = new SolrInputDocument();
|
||||
doc.setField("id", "AAA");
|
||||
doc.setField("core0", "yup stopfra stopfrb stopena stopenb");
|
||||
|
||||
// Add to core0
|
||||
up.add(doc);
|
||||
up.process(getSolrCore0());
|
||||
|
||||
// You can't add it to core1
|
||||
try {
|
||||
up.process(getSolrCore1());
|
||||
fail("Can't add core0 field to core1!");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
}
|
||||
|
||||
// Add to core1
|
||||
doc.setField("id", "BBB");
|
||||
doc.setField("core1", "yup stopfra stopfrb stopena stopenb");
|
||||
doc.removeField("core0");
|
||||
up.add(doc);
|
||||
up.process(getSolrCore1());
|
||||
|
||||
// You can't add it to core1
|
||||
try {
|
||||
up.process(getSolrCore0());
|
||||
fail("Can't add core1 field to core0!");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
}
|
||||
|
||||
// now Make sure AAA is in 0 and BBB in 1
|
||||
SolrQuery q = new SolrQuery();
|
||||
QueryRequest r = new QueryRequest(q);
|
||||
q.setQuery("id:AAA");
|
||||
assertEquals(1, r.process(getSolrCore0()).getResults().size());
|
||||
assertEquals(0, r.process(getSolrCore1()).getResults().size());
|
||||
|
||||
// Now test Changing the default core
|
||||
assertEquals(1, getSolrCore0().query(new SolrQuery("id:AAA")).getResults().size());
|
||||
assertEquals(0, getSolrCore0().query(new SolrQuery("id:BBB")).getResults().size());
|
||||
|
||||
assertEquals(0, getSolrCore1().query(new SolrQuery("id:AAA")).getResults().size());
|
||||
assertEquals(1, getSolrCore1().query(new SolrQuery("id:BBB")).getResults().size());
|
||||
|
||||
// Now test reloading it should have a newer open time
|
||||
String name = "core0";
|
||||
SolrServer coreadmin = getSolrAdmin();
|
||||
CoreAdminResponse mcr = CoreAdminRequest.getStatus(name, coreadmin);
|
||||
long before = mcr.getStartTime(name).getTime();
|
||||
CoreAdminRequest.reloadCore(name, coreadmin);
|
||||
|
||||
mcr = CoreAdminRequest.getStatus(name, coreadmin);
|
||||
long after = mcr.getStartTime(name).getTime();
|
||||
assertTrue("should have more recent time: " + after + "," + before, after > before);
|
||||
|
||||
mcr = CoreAdminRequest.persist("solr-persist.xml", coreadmin);
|
||||
}
|
||||
}
|
|
@ -17,11 +17,7 @@
|
|||
|
||||
package org.apache.solr.common.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
@ -205,17 +201,17 @@ public class DOMUtil {
|
|||
break;
|
||||
|
||||
case Node.ATTRIBUTE_NODE: /* fall through */
|
||||
/* Putting Attribute nodes in this section does not exactly
|
||||
match the definition of how textContent should behave
|
||||
according to the DOM Level-3 Core documentation - which
|
||||
specifies that the Attr's children should have their
|
||||
textContent concated (Attr's can have a single child which
|
||||
/* Putting Attribute nodes in this section does not exactly
|
||||
match the definition of how textContent should behave
|
||||
according to the DOM Level-3 Core documentation - which
|
||||
specifies that the Attr's children should have their
|
||||
textContent concated (Attr's can have a single child which
|
||||
is either Text node or an EntityRefrence). In practice,
|
||||
DOM implementations do not seem to use child nodes of
|
||||
DOM implementations do not seem to use child nodes of
|
||||
Attributes, storing the "text" directly as the nodeValue.
|
||||
Fortunately, the DOM Spec indicates that when Attr.nodeValue
|
||||
is read, it should return the nodeValue from the child Node,
|
||||
so this approach should work both for strict implementations,
|
||||
Fortunately, the DOM Spec indicates that when Attr.nodeValue
|
||||
is read, it should return the nodeValue from the child Node,
|
||||
so this approach should work both for strict implementations,
|
||||
and implementations actually encountered.
|
||||
*/
|
||||
case Node.TEXT_NODE: /* fall through */
|
||||
|
@ -242,6 +238,19 @@ public class DOMUtil {
|
|||
* @param node DOM node to walk for substitutions
|
||||
*/
|
||||
public static void substituteSystemProperties(Node node) {
|
||||
substituteProperties(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces ${property[:default value]} references in all attributes
|
||||
* and text nodes of supplied node. If the property is not defined neither in the
|
||||
* given Properties instance nor in System.getProperty and no
|
||||
* default value is provided, a runtime exception is thrown.
|
||||
*
|
||||
* @param node DOM node to walk for substitutions
|
||||
* @param properties the Properties instance from which a value can be looked up
|
||||
*/
|
||||
public static void substituteProperties(Node node, Properties properties) {
|
||||
// loop through child nodes
|
||||
Node child;
|
||||
Node next = node.getFirstChild();
|
||||
|
@ -252,15 +261,15 @@ public class DOMUtil {
|
|||
|
||||
// handle child by node type
|
||||
if (child.getNodeType() == Node.TEXT_NODE) {
|
||||
child.setNodeValue(substituteSystemProperty(child.getNodeValue()));
|
||||
child.setNodeValue(substituteProperty(child.getNodeValue(), properties));
|
||||
} else if (child.getNodeType() == Node.ELEMENT_NODE) {
|
||||
// handle child elements with recursive call
|
||||
NamedNodeMap attributes = child.getAttributes();
|
||||
for (int i = 0; i < attributes.getLength(); i++) {
|
||||
Node attribute = attributes.item(i);
|
||||
attribute.setNodeValue(substituteSystemProperty(attribute.getNodeValue()));
|
||||
attribute.setNodeValue(substituteProperty(attribute.getNodeValue(), properties));
|
||||
}
|
||||
substituteSystemProperties(child);
|
||||
substituteProperties(child, properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +278,7 @@ public class DOMUtil {
|
|||
* This method borrowed from Ant's PropertyHelper.replaceProperties:
|
||||
* http://svn.apache.org/repos/asf/ant/core/trunk/src/main/org/apache/tools/ant/PropertyHelper.java
|
||||
*/
|
||||
private static String substituteSystemProperty(String value) {
|
||||
private static String substituteProperty(String value, Properties coreProperties) {
|
||||
if (value == null || value.indexOf('$') == -1) {
|
||||
return value;
|
||||
}
|
||||
|
@ -292,7 +301,12 @@ public class DOMUtil {
|
|||
defaultValue = propertyName.substring(colon_index + 1);
|
||||
propertyName = propertyName.substring(0,colon_index);
|
||||
}
|
||||
fragment = System.getProperty(propertyName,defaultValue);
|
||||
if (coreProperties != null) {
|
||||
fragment = coreProperties.getProperty(propertyName);
|
||||
}
|
||||
if (fragment == null) {
|
||||
fragment = System.getProperty(propertyName, defaultValue);
|
||||
}
|
||||
if (fragment == null) {
|
||||
throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, "No system property or default value specified for " + propertyName);
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ public class Config {
|
|||
javax.xml.parsers.DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
doc = builder.parse(lis);
|
||||
|
||||
DOMUtil.substituteSystemProperties(doc);
|
||||
DOMUtil.substituteProperties(doc, loader.getCoreProperties());
|
||||
} catch( SolrException e ){
|
||||
SolrException.log(log,"Error in "+name,e);
|
||||
throw e;
|
||||
|
@ -111,7 +111,7 @@ public class Config {
|
|||
if (lis != is) lis.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @since solr 1.3
|
||||
*/
|
||||
|
|
|
@ -30,6 +30,8 @@ import java.util.logging.Logger;
|
|||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.util.DOMUtil;
|
||||
|
@ -60,9 +62,14 @@ public class CoreContainer
|
|||
protected ClassLoader libLoader = null;
|
||||
protected SolrResourceLoader loader = null;
|
||||
protected java.lang.ref.WeakReference<SolrCore> adminCore = null;
|
||||
protected Properties containerProperties;
|
||||
|
||||
public CoreContainer() {
|
||||
}
|
||||
|
||||
public Properties getContainerProperties() {
|
||||
return containerProperties;
|
||||
}
|
||||
|
||||
// Helper class to initialize the CoreContainer
|
||||
public static class Initializer {
|
||||
|
@ -178,6 +185,13 @@ public class CoreContainer
|
|||
coreAdminHandler = this.createMultiCoreHandler();
|
||||
}
|
||||
|
||||
try {
|
||||
containerProperties = readProperties(cfg, ((NodeList) cfg.evaluate("solr", XPathConstants.NODESET)).item(0));
|
||||
} catch (Throwable e) {
|
||||
SolrConfig.severeErrors.add(e);
|
||||
SolrException.logOnce(log,null,e);
|
||||
}
|
||||
|
||||
NodeList nodes = (NodeList)cfg.evaluate("solr/cores/core", XPathConstants.NODESET);
|
||||
|
||||
for (int i=0; i<nodes.getLength(); i++) {
|
||||
|
@ -187,6 +201,7 @@ public class CoreContainer
|
|||
List<String> aliases = StrUtils.splitSmart(names,',');
|
||||
String name = aliases.get(0);
|
||||
CoreDescriptor p = new CoreDescriptor(this, name, DOMUtil.getAttr(node, "instanceDir", null));
|
||||
p.setCoreProperties(readProperties(cfg, node));
|
||||
|
||||
// deal with optional settings
|
||||
String opt = DOMUtil.getAttr(node, "config", null);
|
||||
|
@ -220,7 +235,18 @@ public class CoreContainer
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Properties readProperties(Config cfg, Node node) throws XPathExpressionException {
|
||||
XPath xpath = cfg.getXPath();
|
||||
NodeList props = (NodeList) xpath.evaluate("property", node, XPathConstants.NODESET);
|
||||
Properties properties = new Properties();
|
||||
for (int i=0; i<props.getLength(); i++) {
|
||||
Node prop = props.item(i);
|
||||
properties.setProperty(DOMUtil.getAttr(prop, "name"), DOMUtil.getAttr(prop, "value"));
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops all cores.
|
||||
*/
|
||||
|
@ -291,7 +317,7 @@ public class CoreContainer
|
|||
String instanceDir = idir.getPath();
|
||||
|
||||
// Initialize the solr config
|
||||
SolrResourceLoader solrLoader = new SolrResourceLoader(instanceDir, libLoader);
|
||||
SolrResourceLoader solrLoader = new SolrResourceLoader(instanceDir, libLoader, dcore.getCoreProperties());
|
||||
SolrConfig config = new SolrConfig(solrLoader, dcore.getConfigName(), null);
|
||||
IndexSchema schema = new IndexSchema(config, dcore.getSchemaName(), null);
|
||||
SolrCore core = new SolrCore(dcore.getName(), null, config, schema, dcore);
|
||||
|
@ -395,7 +421,8 @@ public class CoreContainer
|
|||
|
||||
|
||||
/** Gets a core by name and increase its refcount.
|
||||
* @see SolrCore.open() @see SolrCore.close()
|
||||
* @see SolrCore#open()
|
||||
* @see SolrCore#close()
|
||||
* @param name the core name
|
||||
* @return the core if found
|
||||
*/
|
||||
|
@ -563,6 +590,10 @@ public class CoreContainer
|
|||
writer.write('\'');
|
||||
writer.write(">\n");
|
||||
|
||||
if (containerProperties != null && !containerProperties.isEmpty()) {
|
||||
writeProperties(writer, containerProperties);
|
||||
}
|
||||
|
||||
Map<SolrCore, LinkedList<String>> aliases = new HashMap<SolrCore,LinkedList<String>>();
|
||||
|
||||
synchronized(cores) {
|
||||
|
@ -609,9 +640,25 @@ public class CoreContainer
|
|||
XML.escapeAttributeValue(opt, writer);
|
||||
writer.write('\'');
|
||||
}
|
||||
writer.write("/>\n"); // core
|
||||
if (dcore.getCoreProperties() == null || dcore.getCoreProperties().isEmpty())
|
||||
writer.write("/>\n"); // core
|
||||
else {
|
||||
writer.write(">\n");
|
||||
writeProperties(writer, dcore.getCoreProperties());
|
||||
writer.write("</core>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void writeProperties(Writer writer, Properties props) throws IOException {
|
||||
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
||||
writer.write("<property name='");
|
||||
XML.escapeAttributeValue(entry.getKey().toString(), writer);
|
||||
writer.write("' value='");
|
||||
XML.escapeAttributeValue(entry.getValue().toString(), writer);
|
||||
writer.write("' />\n");
|
||||
}
|
||||
}
|
||||
|
||||
/** Copies a src file to a dest file:
|
||||
* used to circumvent the platform discrepancies regarding renaming files.
|
||||
*/
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.solr.core;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* A Solr core descriptor
|
||||
|
@ -29,6 +30,7 @@ public class CoreDescriptor implements Cloneable {
|
|||
protected String configName;
|
||||
protected String schemaName;
|
||||
private final CoreContainer coreContainer;
|
||||
private Properties coreProperties;
|
||||
|
||||
public CoreDescriptor(CoreContainer coreContainer, String name, String instanceDir) {
|
||||
this.coreContainer = coreContainer;
|
||||
|
@ -52,6 +54,15 @@ public class CoreDescriptor implements Cloneable {
|
|||
this.name = descr.name;
|
||||
coreContainer = descr.coreContainer;
|
||||
}
|
||||
|
||||
private Properties initImplicitProperties() {
|
||||
Properties implicitProperties = new Properties(coreContainer.getContainerProperties());
|
||||
implicitProperties.setProperty("solr.core.name", name);
|
||||
implicitProperties.setProperty("solr.core.instanceDir", instanceDir);
|
||||
implicitProperties.setProperty("solr.core.configName", configName);
|
||||
implicitProperties.setProperty("solr.core.schemaName", schemaName);
|
||||
return implicitProperties;
|
||||
}
|
||||
|
||||
/**@return the default config name. */
|
||||
public String getDefaultConfigName() {
|
||||
|
@ -105,4 +116,32 @@ public class CoreDescriptor implements Cloneable {
|
|||
public CoreContainer getCoreContainer() {
|
||||
return coreContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this core's properties
|
||||
*
|
||||
* @return a shallow copy of this core's properties
|
||||
*/
|
||||
public Properties getCoreProperties() {
|
||||
Properties p = new Properties();
|
||||
if (coreProperties != null)
|
||||
p.putAll(coreProperties);
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this core's properties. Please note that some implicit values will be added to the
|
||||
* Properties instance passed into this method. This means that the Properties instance
|
||||
* set to this method will have different (less) key/value pairs than the Properties
|
||||
* instance returned by #getCoreProperties method.
|
||||
*
|
||||
* @param coreProperties
|
||||
*/
|
||||
public void setCoreProperties(Properties coreProperties) {
|
||||
if (this.coreProperties == null) {
|
||||
Properties p = initImplicitProperties();
|
||||
this.coreProperties = new Properties(p);
|
||||
this.coreProperties.putAll(coreProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,7 @@ import java.io.UnsupportedEncodingException;
|
|||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
|
@ -71,6 +68,28 @@ public class SolrResourceLoader implements ResourceLoader
|
|||
private final List<ResourceLoaderAware> waitingForResources = new ArrayList<ResourceLoaderAware>();
|
||||
private static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||
|
||||
private final Properties coreProperties;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This loader will delegate to the context classloader when possible,
|
||||
* otherwise it will attempt to resolve resources using any jar files
|
||||
* found in the "lib/" directory in the specified instance directory.
|
||||
* If the instance directory is not specified (=null), SolrResourceLoader#locateInstanceDir will provide one.
|
||||
* <p>
|
||||
*/
|
||||
public SolrResourceLoader( String instanceDir, ClassLoader parent, Properties coreProperties )
|
||||
{
|
||||
if( instanceDir == null ) {
|
||||
this.instanceDir = SolrResourceLoader.locateInstanceDir();
|
||||
} else{
|
||||
this.instanceDir = normalizeDir(instanceDir);
|
||||
}
|
||||
log.info("Solr home set to '" + this.instanceDir + "'");
|
||||
this.classLoader = createClassLoader(new File(this.instanceDir + "lib/"), parent);
|
||||
this.coreProperties = coreProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This loader will delegate to the context classloader when possible,
|
||||
|
@ -81,13 +100,7 @@ public class SolrResourceLoader implements ResourceLoader
|
|||
*/
|
||||
public SolrResourceLoader( String instanceDir, ClassLoader parent )
|
||||
{
|
||||
if( instanceDir == null ) {
|
||||
this.instanceDir = SolrResourceLoader.locateInstanceDir();
|
||||
} else{
|
||||
this.instanceDir = normalizeDir(instanceDir);
|
||||
}
|
||||
log.info("Solr home set to '" + this.instanceDir + "'");
|
||||
this.classLoader = createClassLoader(new File(this.instanceDir + "lib/"), parent);
|
||||
this(instanceDir, parent, null);
|
||||
}
|
||||
|
||||
static ClassLoader createClassLoader(File f, ClassLoader loader) {
|
||||
|
@ -113,7 +126,7 @@ public class SolrResourceLoader implements ResourceLoader
|
|||
|
||||
public SolrResourceLoader( String instanceDir )
|
||||
{
|
||||
this( instanceDir, null );
|
||||
this( instanceDir, null, null );
|
||||
}
|
||||
|
||||
/** Ensures a directory name allways ends with a '/'. */
|
||||
|
@ -129,6 +142,10 @@ public class SolrResourceLoader implements ResourceLoader
|
|||
return dataDir;
|
||||
}
|
||||
|
||||
public Properties getCoreProperties() {
|
||||
return coreProperties;
|
||||
}
|
||||
|
||||
/** Opens a schema resource by its name.
|
||||
* Override this method to customize loading schema resources.
|
||||
*@return the stream for the named schema
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" ?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
<schema name="example core ${l10n}" version="1.1">
|
||||
<types>
|
||||
<fieldtype name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
|
||||
<fieldType name="text-FR" class="solr.TextField" positionIncrementGap="100">
|
||||
<analyzer type="index">
|
||||
<tokenizer class="solr.StandardTokenizerFactory"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords-fr.txt"/>
|
||||
<filter class="solr.StandardFilterFactory"/>
|
||||
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.StandardTokenizerFactory"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords-fr.txt"/>
|
||||
<filter class="solr.StandardFilterFactory"/>
|
||||
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
<fieldType name="text-EN" class="solr.TextField" positionIncrementGap="100">
|
||||
<analyzer type="index">
|
||||
<tokenizer class="solr.StandardTokenizerFactory"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords-en.txt"/>
|
||||
<filter class="solr.StandardFilterFactory"/>
|
||||
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.StandardTokenizerFactory"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords-en.txt"/>
|
||||
<filter class="solr.StandardFilterFactory"/>
|
||||
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
</types>
|
||||
|
||||
<fields>
|
||||
<!-- general -->
|
||||
<field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
|
||||
<field name="type" type="string" indexed="true" stored="true" multiValued="false"/>
|
||||
<field name="name" type="string" indexed="true" stored="true" multiValued="false"/>
|
||||
<field name="${ctlField}" type="text-${l10n}" indexed="true" stored="true" multiValued="true"/>
|
||||
</fields>
|
||||
|
||||
<!-- field to use to determine and enforce document uniqueness. -->
|
||||
<uniqueKey>id</uniqueKey>
|
||||
|
||||
<!-- field for the QueryParser to use when an explicit fieldname is absent -->
|
||||
<defaultSearchField>name</defaultSearchField>
|
||||
|
||||
<!-- SolrQueryParser configuration: defaultOperator="AND|OR" -->
|
||||
<solrQueryParser defaultOperator="OR"/>
|
||||
</schema>
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
This is a stripped down config file used for a simple example...
|
||||
It is *not* a good example to work from.
|
||||
-->
|
||||
<config>
|
||||
<dataDir>${solr.solr.home}/data/${l10n}-${version}</dataDir>
|
||||
|
||||
|
||||
<updateHandler class="solr.DirectUpdateHandler2" />
|
||||
|
||||
<requestDispatcher handleSelect="true" >
|
||||
<requestParsers enableRemoteStreaming="false" multipartUploadLimitInKB="2048" />
|
||||
</requestDispatcher>
|
||||
|
||||
<requestHandler name="standard" class="solr.StandardRequestHandler" default="true" />
|
||||
<requestHandler name="/update" class="solr.XmlUpdateRequestHandler" />
|
||||
<requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" />
|
||||
|
||||
<!-- config for the admin interface -->
|
||||
<admin>
|
||||
<defaultQuery>solr</defaultQuery>
|
||||
</admin>
|
||||
|
||||
</config>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
stopena
|
||||
stopenb
|
|
@ -0,0 +1,16 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
stopfra
|
||||
stopfrb
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
All (relative) paths are relative to the installation path
|
||||
|
||||
persistent: Save changes made via the API to this file
|
||||
sharedLib: path to a lib directory that will be shared across all cores
|
||||
-->
|
||||
<solr persistent="true">
|
||||
<property name="version" value="1.3"/>
|
||||
<property name="lang" value="english, french"/>
|
||||
|
||||
<!--
|
||||
adminPath: RequestHandler path to manage cores.
|
||||
If 'null' (or absent), cores will not be manageable via REST
|
||||
-->
|
||||
<cores adminPath="/admin/cores">
|
||||
<core name="core0" instanceDir="./">
|
||||
<property name="version" value="3.5"/>
|
||||
<property name="l10n" value="EN"/>
|
||||
<property name="ctlField" value="core0"/>
|
||||
<property name="comment" value="This is a sample"/>
|
||||
</core>
|
||||
<core name="core1" instanceDir="./">
|
||||
<property name="version" value="2.4"/>
|
||||
<property name="l10n" value="FR"/>
|
||||
<property name="ctlField" value="core1"/>
|
||||
<property name="comment" value="Ceci est un exemple"/>
|
||||
</core>
|
||||
</cores>
|
||||
</solr>
|
Loading…
Reference in New Issue