Package org.apache.solr.core

Source Code of org.apache.solr.core.Config

/**
* 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.core;

import org.apache.lucene.util.Version;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.DOMUtil;
import org.apache.solr.common.util.SystemIdResolver;
import org.apache.solr.common.util.XMLErrorLogger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.apache.commons.io.IOUtils;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;

/**
* @version $Id: Config.java 1075090 2011-02-27 17:20:30Z uschindler $
*/
public class Config {
  public static final Logger log = LoggerFactory.getLogger(Config.class);
  private static final XMLErrorLogger xmllog = new XMLErrorLogger(log);

  static final XPathFactory xpathFactory = XPathFactory.newInstance();

  private final Document doc;
  private final String prefix;
  private final String name;
  private final SolrResourceLoader loader;

  /**
   * @deprecated Use {@link #Config(SolrResourceLoader, String, InputSource, String)} instead.
   */
  @Deprecated
  public Config(String name, InputStream is, String prefix) throws ParserConfigurationException, IOException, SAXException
  {
    this( null, name, new InputSource(is), prefix );
  }

  /**
   * Builds a config from a resource name with no xpath prefix.
   * @param loader
   * @param name
   * @throws javax.xml.parsers.ParserConfigurationException
   * @throws java.io.IOException
   * @throws org.xml.sax.SAXException
   */
  public Config(SolrResourceLoader loader, String name) throws ParserConfigurationException, IOException, SAXException
  {
    this( loader, name, (InputSource) null, null );
  }
 
  /**
   * Builds a config:
   * <p>
   * Note that the 'name' parameter is used to obtain a valid input stream if no valid one is provided through 'is'.
   * If no valid stream is provided, a valid SolrResourceLoader instance should be provided through 'loader' so
   * the resource can be opened (@see SolrResourceLoader#openResource); if no SolrResourceLoader instance is provided, a default one
   * will be created.
   * </p>
   * <p>
   * Consider passing a non-null 'name' parameter in all use-cases since it is used for logging & exception reporting.
   * </p>
   * @param loader the resource loader used to obtain an input stream if 'is' is null
   * @param name the resource name used if the input stream 'is' is null
   * @param is the resource as a stream
   * @param prefix an optional prefix that will be preprended to all non-absolute xpath expressions
   * @throws javax.xml.parsers.ParserConfigurationException
   * @throws java.io.IOException
   * @throws org.xml.sax.SAXException
   * @deprecated Use {@link #Config(SolrResourceLoader, String, InputSource, String)} instead.
   */
  @Deprecated
  public Config(SolrResourceLoader loader, String name, InputStream is, String prefix) throws ParserConfigurationException, IOException, SAXException
  {
   this(loader, name, (is == null) ? null : new InputSource(is), prefix);
  }
 
  /**
   * Builds a config:
   * <p>
   * Note that the 'name' parameter is used to obtain a valid input stream if no valid one is provided through 'is'.
   * If no valid stream is provided, a valid SolrResourceLoader instance should be provided through 'loader' so
   * the resource can be opened (@see SolrResourceLoader#openResource); if no SolrResourceLoader instance is provided, a default one
   * will be created.
   * </p>
   * <p>
   * Consider passing a non-null 'name' parameter in all use-cases since it is used for logging & exception reporting.
   * </p>
   * @param loader the resource loader used to obtain an input stream if 'is' is null
   * @param name the resource name used if the input stream 'is' is null
   * @param is the resource as a SAX InputSource
   * @param prefix an optional prefix that will be preprended to all non-absolute xpath expressions
   * @throws javax.xml.parsers.ParserConfigurationException
   * @throws java.io.IOException
   * @throws org.xml.sax.SAXException
   */
  public Config(SolrResourceLoader loader, String name, InputSource is, String prefix) throws ParserConfigurationException, IOException, SAXException
  {
    if( loader == null ) {
      loader = new SolrResourceLoader( null );
    }
    this.loader = loader;
    this.name = name;
    this.prefix = (prefix != null && !prefix.endsWith("/"))? prefix + '/' : prefix;
    try {
      javax.xml.parsers.DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
     
      if (is == null) {
        is = new InputSource(loader.openConfig(name));
        is.setSystemId(SystemIdResolver.createSystemIdFromResourceName(name));
      }

      // only enable xinclude, if a SystemId is available
      if (is.getSystemId() != null) {
        try {
          dbf.setXIncludeAware(true);
          dbf.setNamespaceAware(true);
        } catch(UnsupportedOperationException e) {
          log.warn(name + " XML parser doesn't support XInclude option");
        }
      }
     
      final DocumentBuilder db = dbf.newDocumentBuilder();
      db.setEntityResolver(new SystemIdResolver(loader));
      db.setErrorHandler(xmllog);
      try {
        doc = db.parse(is);
      } finally {
        // some XML parsers are broken and don't close the byte stream (but they should according to spec)
        IOUtils.closeQuietly(is.getByteStream());
      }

      DOMUtil.substituteProperties(doc, loader.getCoreProperties());
    } catch (ParserConfigurationException e)  {
      SolrException.log(log, "Exception during parsing file: " + name, e);
      throw e;
    } catch (SAXException e)  {
      SolrException.log(log, "Exception during parsing file: " + name, e);
      throw e;
    } catch( SolrException e ){
      SolrException.log(log,"Error in "+name,e);
      throw e;
    }
  }

  /**
   * @since solr 1.3
   */
  public SolrResourceLoader getResourceLoader()
  {
    return loader;
  }

  /**
   * @since solr 1.3
   */
  public String getResourceName() {
    return name;
  }

  public String getName() {
    return name;
  }
 
  public Document getDocument() {
    return doc;
  }

  public XPath getXPath() {
    return xpathFactory.newXPath();
  }

  private String normalize(String path) {
    return (prefix==null || path.startsWith("/")) ? path : prefix+path;
  }


  public Object evaluate(String path, QName type) {
    XPath xpath = xpathFactory.newXPath();
    try {
      String xstr=normalize(path);

      // TODO: instead of prepending /prefix/, we could do the search rooted at /prefix...
      Object o = xpath.evaluate(xstr, doc, type);
      return o;

    } catch (XPathExpressionException e) {
      throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,"Error in xpath:" + path +" for " + name,e,false);
    }
  }

  public Node getNode(String path, boolean errIfMissing) {
   XPath xpath = xpathFactory.newXPath();
   Node nd = null;
   String xstr = normalize(path);

    try {
      nd = (Node)xpath.evaluate(xstr, doc, XPathConstants.NODE);

      if (nd==null) {
        if (errIfMissing) {
          throw new RuntimeException(name + " missing "+path);
        } else {
          log.debug(name + " missing optional " + path);
          return null;
        }
      }

      log.trace(name + ":" + path + "=" + nd);
      return nd;

    } catch (XPathExpressionException e) {
      SolrException.log(log,"Error in xpath",e);
      throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,"Error in xpath:" + xstr + " for " + name,e,false);
    } catch (SolrException e) {
      throw(e);
    } catch (Throwable e) {
      SolrException.log(log,"Error in xpath",e);
      throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,"Error in xpath:" + xstr+ " for " + name,e,false);
    }
  }

  public String getVal(String path, boolean errIfMissing) {
    Node nd = getNode(path,errIfMissing);
    if (nd==null) return null;

    String txt = DOMUtil.getText(nd);

    log.debug(name + ' '+path+'='+txt);
    return txt;

    /******
    short typ = nd.getNodeType();
    if (typ==Node.ATTRIBUTE_NODE || typ==Node.TEXT_NODE) {
      return nd.getNodeValue();
    }
    return nd.getTextContent();
    ******/
  }


  public String get(String path) {
    return getVal(path,true);
  }

  public String get(String path, String def) {
    String val = getVal(path, false);
    return val!=null ? val : def;
  }

  public int getInt(String path) {
    return Integer.parseInt(getVal(path, true));
  }

  public int getInt(String path, int def) {
    String val = getVal(path, false);
    return val!=null ? Integer.parseInt(val) : def;
  }

  public boolean getBool(String path) {
    return Boolean.parseBoolean(getVal(path, true));
  }

  public boolean getBool(String path, boolean def) {
    String val = getVal(path, false);
    return val!=null ? Boolean.parseBoolean(val) : def;
  }

  public float getFloat(String path) {
    return Float.parseFloat(getVal(path, true));
  }

  public float getFloat(String path, float def) {
    String val = getVal(path, false);
    return val!=null ? Float.parseFloat(val) : def;
  }


  public double getDouble(String path){
     return Double.parseDouble(getVal(path, true));
   }

   public double getDouble(String path, double def) {
     String val = getVal(path, false);
     return val!=null ? Double.parseDouble(val) : def;
   }
  
   public Version getLuceneVersion(String path) {
     return parseLuceneVersionString(getVal(path, true));
   }
  
   public Version getLuceneVersion(String path, Version def) {
     String val = getVal(path, false);
     if (val == null) {
       if (!versionWarningAlreadyLogged.getAndSet(true)) {
         log.warn(
           "the luceneMatchVersion is not specified, defaulting to " + def +
           " emulation. You should at some point declare and reindex to at least 3.0, " +
           "because 2.4 emulation is deprecated and will be removed in 4.0. " +
           "This parameter will be mandatory in 4.0."
         );
       }
       return def;
     } else {
       return parseLuceneVersionString(val);
     }
   }
 
  private static final AtomicBoolean versionWarningAlreadyLogged = new AtomicBoolean(false);
 
  public static final Version parseLuceneVersionString(final String matchVersion) {
    String parsedMatchVersion = matchVersion.toUpperCase(Locale.ENGLISH);
   
    // be lenient with the supplied version parameter
    parsedMatchVersion = parsedMatchVersion.replaceFirst("^(\\d)\\.(\\d)$", "LUCENE_$1$2");
   
    final Version version;
    try {
      version = Version.valueOf(parsedMatchVersion);
    } catch (IllegalArgumentException iae) {
      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
        "Invalid luceneMatchVersion '" + matchVersion +
        "', valid values are: " + Arrays.toString(Version.values()) +
        " or a string in format 'V.V'", iae, false);   
    }
   
    if (version == Version.LUCENE_CURRENT && !versionWarningAlreadyLogged.getAndSet(true)) {
      log.warn(
        "You should not use LUCENE_CURRENT as luceneMatchVersion property: "+
        "if you use this setting, and then Solr upgrades to a newer release of Lucene, "+
        "sizable changes may happen. If precise back compatibility is important "+
        "then you should instead explicitly specify an actual Lucene version."
      );
    }
   
    return version;
  }

  // The following functions were moved to ResourceLoader
  //-----------------------------------------------------------------------------
 
   /**
    * @deprecated Use {@link SolrResourceLoader#getConfigDir()} instead.
    */
  @Deprecated
  public String getConfigDir() {
    return loader.getConfigDir();
  }

  /**
   * @deprecated Use {@link SolrResourceLoader#openResource(String)} instead.
   */
  @Deprecated
  public InputStream openResource(String resource) {
    return loader.openResource(resource);
  }

  /**
   * @deprecated Use {@link SolrResourceLoader#getLines(String)} instead.
   */
  @Deprecated
  public List<String> getLines(String resource) throws IOException {
    return loader.getLines(resource);
  }

  /**
   * @deprecated Use {@link SolrResourceLoader#findClass(String, String[])} instead.
   */
  @Deprecated
  public Class findClass(String cname, String... subpackages) {
    return loader.findClass(cname, subpackages);
  }

  /**
   * @deprecated Use {@link SolrResourceLoader#newInstance(String, String[])} instead.
   */
  @Deprecated
  public Object newInstance(String cname, String ... subpackages) {
    return loader.newInstance(cname, subpackages);
  }
 
  /**
   * @deprecated Use {@link SolrResourceLoader#getInstanceDir()} instead.
   */
  @Deprecated
  public String getInstanceDir() {
    return loader.getInstanceDir();
  }
}
TOP

Related Classes of org.apache.solr.core.Config

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.