/** * */ package com.sdyc.ndcls2.solr; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.SolrCore; import org.xml.sax.SAXException; /** * *

* 该类是一个静态工厂方法.属于单利模式,在多线程环境下各个线程安全是安全的.

* * Solr的CoreContainer在初始化的时候默认需要solr.solr.home的System.Property信息, * 所以你需要在得到 {@link #getInstance()}前显式的指定一个solr.solr.home. * 或者使用 {@link #getInstance(String)} 初始化,当使用 {@link #getInstance(String)} * 进行初始化时,如果已经在System.getProperties()中加入solr.solr.home, * Factory会优先使用solr.solr.home信息进行初始化, * 并把solrHome覆盖为solr.solr.home的值

* * * 初始化该类时,Solr配置中的所有Core并不会立即发生初始化(defaultCore除外). * *

* defaultCore在初始化时有一个复杂的过程,具体有以下几种情况:
* 1.当在Solr配置文件中的solr.xml文件中没有配置defaultCoreName节点信息. * 那么在Factory中你有必要指定一个defaultCoreName(并且defaultCoreName必须满足一些规定). * 则默认的defaultCore是以defaultCoreName为Core的SolrServer.
* 2.当在Solr配置文件中的solr.xml文件中已经配置了defaultCoreName. * 那么即时你手动的设置Factory的defaultCoreName也是无效的. * 也就是说,defaultCoreName永远会以Solr中的配置为优先的原则.

*

* * *

* 传入的coreName必须是一个有效的Java 标示符名称.在内部的实现使用了Map字典, * 这个字典的Key是所有Solr Core内有效的coreName,因此你必须保证字典中的所有key满足Java * 标示符的命名规则.在这里传入null, "", OR " "都是不允许的. * *

* * *

* 在没有特别指定的情况下,任何需要传入参数的方法,当传入null值时, * 会发生NullPointException异常. *

* @author ZhenQin * * @since 2.0 * */ public final class SolrServerFactory { /** * Solr.home */ private static String solrHome = null; /** * 默认的defaultCoreName,该参数默认是defaultCoreName = "" */ private static String defaultCoreName = ""; /** * 初始化的solrCoreContainer * */ private static CoreContainer solrCoreContainer = null; /** * 默认的defaultSolrServer * */ private static SolrServer defaultSolrServer = null; /** * * 保存这的SolrServer,对应多个solrServer的时候,保存的SolrServer * */ private final Map solrServerCache = new HashMap(); /** * 锁 */ private java.util.concurrent.locks.ReentrantLock lock = new java.util.concurrent.locks.ReentrantLock(); /** * 日志 */ private static Log log = LogFactory.getLog(SolrServerFactory.class); /** * * 静态工厂方法,单例模式.SolrServerFactory只能有一个对象实例 * */ private static SolrServerFactory instance = null; /** * 私有化构造方法 */ private SolrServerFactory() { initBuild(); } /** * 初始化时的Build,该方法只能被初始化的时候执行一次 * */ private void initBuild() { try { setSolrCoreContainer(new CoreContainer.Initializer().initialize()); } catch (IOException e) { throw new RuntimeException(e); } catch (ParserConfigurationException e) { throw new RuntimeException(e); } catch (SAXException e) { throw new RuntimeException(e); } String defaultCoreName = SolrServerFactory.getSolrCoreContainer().getDefaultCoreName(); if(defaultCoreName == null){ if(validate(SolrServerFactory.getDefaultCoreName())){ setDefaultSolrServer(new EmbeddedSolrServer(SolrServerFactory.getSolrCoreContainer(), SolrServerFactory.getDefaultCoreName())); } } if(defaultCoreName.equals("")){ setDefaultCoreName(defaultCoreName); setDefaultSolrServer(new EmbeddedSolrServer(SolrServerFactory.getSolrCoreContainer(), SolrServerFactory.getDefaultCoreName())); } else if(defaultCoreName.trim().length() > 0){ setDefaultCoreName(defaultCoreName); setDefaultSolrServer(new EmbeddedSolrServer(SolrServerFactory.getSolrCoreContainer(), SolrServerFactory.getDefaultCoreName())); } lock.lock(); try { if(StringUtils.isNotBlank(getDefaultCoreName())){ this.solrServerCache.put(getDefaultCoreName(), getDefaultSolrServer()); } } finally { lock.unlock(); } } /** * * 通过静态工厂方法获得类的实例 * @throws java.lang.RuntimeException 当没有查找到System.getProperty("solr.solr.home")的参数时, * 发生该异常.如果需要显式的传入SolrHome,请使用:{@link #getInstance(String)} * @return 返回SolrServerFactory唯一实例 */ public static SolrServerFactory getInstance() { if(instance != null){ return instance; } synchronized (SolrServerFactory.class) { if(instance == null) { String solrHome = System.getProperty("solr.solr.home"); if(StringUtils.isNotBlank(solrHome)){ SolrServerFactory.solrHome = solrHome; instance = new SolrServerFactory(); } else if(StringUtils.isNotBlank(SolrServerFactory.solrHome)) { System.setProperty("solr.solr.home", SolrServerFactory.solrHome); instance = new SolrServerFactory(); } else { throw new RuntimeException("not fount System.getProperty(\"solr.solr.home\") attr."); } } } return instance; } /** * * 通过静态工厂方法获得类的实例 * * @return 返回SolrServerFactory唯一实例 */ public static SolrServerFactory getInstance(String solrHome) { if(StringUtils.isNotBlank(solrHome)){ SolrServerFactory.solrHome = solrHome; return getInstance(); } throw new RuntimeException("solrHome is an invalid ${solr.solr.home}."); } /** * @return * @see org.apache.solr.core.CoreContainer#getSolrHome() */ public String getSolrHome() { return solrCoreContainer.getSolrHome(); } /** * * @see org.apache.solr.core.CoreContainer#persist() */ public void persist() { solrCoreContainer.persist(); } /** * @param core * @param returnPrev * @return * @see org.apache.solr.core.CoreContainer#register(org.apache.solr.core.SolrCore, boolean) */ public SolrCore register(SolrCore core, boolean returnPrev) { return solrCoreContainer.register(core, returnPrev); } /** * @param name * @param core * @param returnPrevNotClosed * @return * @see org.apache.solr.core.CoreContainer#register(java.lang.String, org.apache.solr.core.SolrCore, boolean) */ public SolrCore register(String name, SolrCore core, boolean returnPrevNotClosed) { return solrCoreContainer.register(name, core, returnPrevNotClosed); } /** * * @see org.apache.solr.core.CoreContainer#shutdown() */ public void shutdown() { solrCoreContainer.shutdown(); } /** * @return the defaultSolrCoreContainer */ public static CoreContainer getSolrCoreContainer(){ if(SolrServerFactory.solrCoreContainer == null){ SolrServerFactory.getInstance(); } return SolrServerFactory.solrCoreContainer; } /** * * 返回一个SolrCore对象,这个对象可以允许使用Lucene原生API进行编程. * @param coreName Solr的一个coreName, * 这个coreName需要 {@link #validate(String)}验证通过.否则返回null * @return the Solr Lucene API */ public SolrCore getSolrCore(String coreName){ if(validate(coreName)){ return SolrServerFactory.solrCoreContainer.getCore(coreName); } return null; } /** * * @param solrCoreContainer the defaultSolrCoreContainer to set */ protected void setSolrCoreContainer(CoreContainer solrCoreContainer) { SolrServerFactory.solrCoreContainer = solrCoreContainer; } /** *

* 取得默认的SolrServer对象.

* 注意:
* 返回的SolrServer有可能是null值,这取决着你是否在Solr的solr.xml * 是否配置了defaultCoreName信息或者显式的设置Factory的defaultCoreName信息. *

* @return 返回Solr的SolrServer */ public static SolrServer getDefaultSolrServer(){ if(SolrServerFactory.solrCoreContainer == null){ SolrServerFactory.getInstance(); } return SolrServerFactory.defaultSolrServer; } /** * 检验一个CoreName是否是Solr核心配置所支持的 * * @param coreName Solr core,具体见${solr.solr.home}/solr.xml中的cor.name属性 * * @return 返回是否是合法的Solr coreName. */ public static boolean validate(String coreName) { return coreName.equals(defaultCoreName) ? true : SolrServerFactory.getSolrCoreContainer().getCoreNames().contains(coreName); } /** *

* 根据名称取得一个SolrServer.
* 传入的coreName必须是一个有效的Java 标示符名称.在内部的实现使用了Map字典, * 这个字典的Key是所有Solr Core内有效的coreName,因此你必须保证字典中的所有key满足Java * 标示符的命名规则.在这里传入null, "", OR " "都是不允许的. *

* *

* 注意:
* SolrServerFactory在初始化的时候并不会自动注册每一个SolrCore(除了defaultSolrCore). * 具体见:{@link com.sdyc.ndcls2.solr.SolrServerFactory} *

* * @param coreName 这个coreName需要 {@link #validate(String)}验证通过.否则返回null * @return 返回SolrServer,当coreName不满足必要的条件则返回null */ public SolrServer getSolrServer(String coreName){ if(StringUtils.isNotBlank(coreName) && validate(coreName)){ SolrServer tmpSolrServer = solrServerCache.get(coreName); if(tmpSolrServer == null){ lock.lock(); try { tmpSolrServer = new EmbeddedSolrServer(getSolrCoreContainer(), coreName); solrServerCache.put(coreName, tmpSolrServer); } catch(Exception e){ log.error(e); } finally { lock.unlock(); } } return tmpSolrServer; } return null; } /** * @param defaultSolrServer the defaultSolrServer to set */ protected void setDefaultSolrServer(SolrServer defaultSolrServer) { SolrServerFactory.defaultSolrServer = defaultSolrServer; } /** * @param defaultCoreName the defaultCoreName to set */ public static void setDefaultCoreName(String defaultCoreName) { SolrServerFactory.defaultCoreName = defaultCoreName; } /** * @return the defaultCoreName */ public static String getDefaultCoreName() { return defaultCoreName; } }