lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mikemcc...@apache.org
Subject svn commit: r1700800 [16/24] - in /lucene/dev/branches/lucene6699: ./ dev-tools/ dev-tools/eclipse/ dev-tools/idea/.idea/ dev-tools/scripts/ lucene/ lucene/analysis/ lucene/analysis/common/ lucene/analysis/common/src/java/org/apache/lucene/analysis/ar/...
Date Wed, 02 Sep 2015 13:06:22 GMT
Modified: lucene/dev/branches/lucene6699/solr/server/solr/configsets/basic_configs/conf/schema.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/server/solr/configsets/basic_configs/conf/schema.xml?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/server/solr/configsets/basic_configs/conf/schema.xml (original)
+++ lucene/dev/branches/lucene6699/solr/server/solr/configsets/basic_configs/conf/schema.xml Wed Sep  2 13:06:13 2015
@@ -194,8 +194,8 @@
     <!-- sortMissingLast and sortMissingFirst attributes are optional attributes are
          currently supported on types that are sorted internally as strings
          and on numeric types.
-	     This includes "string","boolean", and, as of 3.5 (and 4.x),
-	     int, float, long, date, double, including the "Trie" variants.
+       This includes "string","boolean", and, as of 3.5 (and 4.x),
+       int, float, long, date, double, including the "Trie" variants.
        - If sortMissingLast="true", then a sort on this field will cause documents
          without the field to come after documents with the field,
          regardless of the requested sort order (asc or desc).
@@ -306,9 +306,9 @@
 
     <!-- A general text field that has reasonable, generic
          cross-language defaults: it tokenizes with StandardTokenizer,
-	 removes stop words from case-insensitive "stopwords.txt"
-	 (empty by default), and down cases.  At query time only, it
-	 also applies synonyms. -->
+   removes stop words from case-insensitive "stopwords.txt"
+   (empty by default), and down cases.  At query time only, it
+   also applies synonyms. -->
     <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
       <analyzer type="index">
         <tokenizer class="solr.StandardTokenizerFactory"/>
@@ -344,11 +344,11 @@
                 words="lang/stopwords_en.txt"
                 />
         <filter class="solr.LowerCaseFilterFactory"/>
-	<filter class="solr.EnglishPossessiveFilterFactory"/>
+  <filter class="solr.EnglishPossessiveFilterFactory"/>
         <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
-	<!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
+  <!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
         <filter class="solr.EnglishMinimalStemFilterFactory"/>
-	-->
+  -->
         <filter class="solr.PorterStemFilterFactory"/>
       </analyzer>
       <analyzer type="query">
@@ -359,23 +359,23 @@
                 words="lang/stopwords_en.txt"
                 />
         <filter class="solr.LowerCaseFilterFactory"/>
-	<filter class="solr.EnglishPossessiveFilterFactory"/>
+  <filter class="solr.EnglishPossessiveFilterFactory"/>
         <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
-	<!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
+  <!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
         <filter class="solr.EnglishMinimalStemFilterFactory"/>
-	-->
+  -->
         <filter class="solr.PorterStemFilterFactory"/>
       </analyzer>
     </fieldType>
 
     <!-- A text field with defaults appropriate for English, plus
-	 aggressive word-splitting and autophrase features enabled.
-	 This field is just like text_en, except it adds
-	 WordDelimiterFilter to enable splitting and matching of
-	 words on case-change, alpha numeric boundaries, and
-	 non-alphanumeric chars.  This means certain compound word
-	 cases will work, for example query "wi fi" will match
-	 document "WiFi" or "wi-fi".
+   aggressive word-splitting and autophrase features enabled.
+   This field is just like text_en, except it adds
+   WordDelimiterFilter to enable splitting and matching of
+   words on case-change, alpha numeric boundaries, and
+   non-alphanumeric chars.  This means certain compound word
+   cases will work, for example query "wi fi" will match
+   document "WiFi" or "wi-fi".
         -->
     <fieldType name="text_en_splitting" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">
       <analyzer type="index">
@@ -426,7 +426,7 @@
     </fieldType>
 
     <!-- Just like text_general except it reverses the characters of
-	 each token, to enable more efficient leading wildcard queries. -->
+   each token, to enable more efficient leading wildcard queries. -->
     <fieldType name="text_general_rev" class="solr.TextField" positionIncrementGap="100">
       <analyzer type="index">
         <tokenizer class="solr.StandardTokenizerFactory"/>

Modified: lucene/dev/branches/lucene6699/solr/server/solr/configsets/data_driven_schema_configs/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/server/solr/configsets/data_driven_schema_configs/conf/solrconfig.xml?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/server/solr/configsets/data_driven_schema_configs/conf/solrconfig.xml (original)
+++ lucene/dev/branches/lucene6699/solr/server/solr/configsets/data_driven_schema_configs/conf/solrconfig.xml Wed Sep  2 13:06:13 2015
@@ -1094,7 +1094,7 @@
       <!-- maximum threshold of documents a query term can appear to be considered for correction -->
       <float name="maxQueryFrequency">0.01</float>
       <!-- uncomment this to require suggestions to occur in 1% of the documents
-      	<float name="thresholdTokenFrequency">.01</float>
+        <float name="thresholdTokenFrequency">.01</float>
       -->
     </lst>
 
@@ -1542,6 +1542,8 @@
     -->
   <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy">
     <str name="template.base.dir">${velocity.template.base.dir:}</str>
+    <str name="solr.resource.loader.enabled">${velocity.solr.resource.loader.enabled:true}</str>
+    <str name="params.resource.loader.enabled">${velocity.params.resource.loader.enabled:false}</str>
   </queryResponseWriter>
 
   <!-- XSLT response writer transforms the XML output by any xslt file found

Modified: lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/schema.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/schema.xml?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/schema.xml (original)
+++ lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/schema.xml Wed Sep  2 13:06:13 2015
@@ -298,12 +298,12 @@
 
    <!-- Create a string version of author for faceting -->
    <copyField source="author" dest="author_s"/>
-	
+  
    <!-- Above, multiple source fields are copied to the [text] field. 
-	  Another way to map multiple source fields to the same 
-	  destination field is to use the dynamic field syntax. 
-	  copyField also supports a maxChars to copy setting.  -->
-	   
+    Another way to map multiple source fields to the same 
+    destination field is to use the dynamic field syntax. 
+    copyField also supports a maxChars to copy setting.  -->
+     
    <!-- <copyField source="*_t" dest="text" maxChars="3000"/> -->
 
    <!-- copy name to alphaNameSort, a field designed for sorting by name -->
@@ -330,8 +330,8 @@
     <!-- sortMissingLast and sortMissingFirst attributes are optional attributes are
          currently supported on types that are sorted internally as strings
          and on numeric types.
-	     This includes "string","boolean", and, as of 3.5 (and 4.x),
-	     int, float, long, date, double, including the "Trie" variants.
+       This includes "string","boolean", and, as of 3.5 (and 4.x),
+       int, float, long, date, double, including the "Trie" variants.
        - If sortMissingLast="true", then a sort on this field will cause documents
          without the field to come after documents with the field,
          regardless of the requested sort order (asc or desc).
@@ -451,9 +451,9 @@
 
     <!-- A general text field that has reasonable, generic
          cross-language defaults: it tokenizes with StandardTokenizer,
-	 removes stop words from case-insensitive "stopwords.txt"
-	 (empty by default), and down cases.  At query time only, it
-	 also applies synonyms. -->
+   removes stop words from case-insensitive "stopwords.txt"
+   (empty by default), and down cases.  At query time only, it
+   also applies synonyms. -->
     <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
       <analyzer type="index">
         <tokenizer class="solr.StandardTokenizerFactory"/>
@@ -489,11 +489,11 @@
                 words="lang/stopwords_en.txt"
                 />
         <filter class="solr.LowerCaseFilterFactory"/>
-	<filter class="solr.EnglishPossessiveFilterFactory"/>
+  <filter class="solr.EnglishPossessiveFilterFactory"/>
         <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
-	<!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
+  <!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
         <filter class="solr.EnglishMinimalStemFilterFactory"/>
-	-->
+  -->
         <filter class="solr.PorterStemFilterFactory"/>
       </analyzer>
       <analyzer type="query">
@@ -504,23 +504,23 @@
                 words="lang/stopwords_en.txt"
                 />
         <filter class="solr.LowerCaseFilterFactory"/>
-	<filter class="solr.EnglishPossessiveFilterFactory"/>
+  <filter class="solr.EnglishPossessiveFilterFactory"/>
         <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
-	<!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
+  <!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
         <filter class="solr.EnglishMinimalStemFilterFactory"/>
-	-->
+  -->
         <filter class="solr.PorterStemFilterFactory"/>
       </analyzer>
     </fieldType>
 
     <!-- A text field with defaults appropriate for English, plus
-	 aggressive word-splitting and autophrase features enabled.
-	 This field is just like text_en, except it adds
-	 WordDelimiterFilter to enable splitting and matching of
-	 words on case-change, alpha numeric boundaries, and
-	 non-alphanumeric chars.  This means certain compound word
-	 cases will work, for example query "wi fi" will match
-	 document "WiFi" or "wi-fi".
+   aggressive word-splitting and autophrase features enabled.
+   This field is just like text_en, except it adds
+   WordDelimiterFilter to enable splitting and matching of
+   words on case-change, alpha numeric boundaries, and
+   non-alphanumeric chars.  This means certain compound word
+   cases will work, for example query "wi fi" will match
+   document "WiFi" or "wi-fi".
         -->
     <fieldType name="text_en_splitting" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">
       <analyzer type="index">
@@ -571,7 +571,7 @@
     </fieldType>
 
     <!-- Just like text_general except it reverses the characters of
-	 each token, to enable more efficient leading wildcard queries. -->
+   each token, to enable more efficient leading wildcard queries. -->
     <fieldType name="text_general_rev" class="solr.TextField" positionIncrementGap="100">
       <analyzer type="index">
         <tokenizer class="solr.StandardTokenizerFactory"/>
@@ -646,10 +646,10 @@
         a token of "foo|1.4"  would be indexed as "foo" with a payload of 1.4f
         Attributes of the DelimitedPayloadTokenFilterFactory : 
          "delimiter" - a one character delimiter. Default is | (pipe)
-	 "encoder" - how to encode the following value into a playload
-	    float -> org.apache.lucene.analysis.payloads.FloatEncoder,
-	    integer -> o.a.l.a.p.IntegerEncoder
-	    identity -> o.a.l.a.p.IdentityEncoder
+   "encoder" - how to encode the following value into a playload
+      float -> org.apache.lucene.analysis.payloads.FloatEncoder,
+      integer -> o.a.l.a.p.IntegerEncoder
+      identity -> o.a.l.a.p.IdentityEncoder
             Fully Qualified class name implementing PayloadEncoder, Encoder must have a no arg constructor.
          -->
         <filter class="solr.DelimitedPayloadTokenFilterFactory" encoder="float"/>
@@ -670,10 +670,10 @@
     -->
     <fieldType name="descendent_path" class="solr.TextField">
       <analyzer type="index">
-	<tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/" />
+  <tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/" />
       </analyzer>
       <analyzer type="query">
-	<tokenizer class="solr.KeywordTokenizerFactory" />
+  <tokenizer class="solr.KeywordTokenizerFactory" />
       </analyzer>
     </fieldType>
     <!-- 
@@ -682,10 +682,10 @@
     -->
     <fieldType name="ancestor_path" class="solr.TextField">
       <analyzer type="index">
-	<tokenizer class="solr.KeywordTokenizerFactory" />
+  <tokenizer class="solr.KeywordTokenizerFactory" />
       </analyzer>
       <analyzer type="query">
-	<tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/" />
+  <tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/" />
       </analyzer>
     </fieldType>
 

Modified: lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml (original)
+++ lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml Wed Sep  2 13:06:13 2015
@@ -1212,7 +1212,7 @@
       <!-- maximum threshold of documents a query term can appear to be considered for correction -->
       <float name="maxQueryFrequency">0.01</float>
       <!-- uncomment this to require suggestions to occur in 1% of the documents
-      	<float name="thresholdTokenFrequency">.01</float>
+        <float name="thresholdTokenFrequency">.01</float>
       -->
     </lst>
     
@@ -1360,64 +1360,54 @@
 
        You'll need to set the solr.clustering.enabled system property
        when running solr to run with clustering enabled:
+       -Dsolr.clustering.enabled=true
 
-            java -Dsolr.clustering.enabled=true -jar start.jar
-
-       http://wiki.apache.org/solr/ClusteringComponent
-       http://carrot2.github.io/solr-integration-strategies/
+       https://cwiki.apache.org/confluence/display/solr/Result+Clustering
     -->
   <searchComponent name="clustering"
                    enable="${solr.clustering.enabled:false}"
                    class="solr.clustering.ClusteringComponent" >
-    <lst name="engine">
-      <str name="name">lingo</str>
-
-      <!-- Class name of a clustering algorithm compatible with the Carrot2 framework.
-
-           Currently available open source algorithms are:
-           * org.carrot2.clustering.lingo.LingoClusteringAlgorithm
-           * org.carrot2.clustering.stc.STCClusteringAlgorithm
-           * org.carrot2.clustering.kmeans.BisectingKMeansClusteringAlgorithm
-
-           See http://project.carrot2.org/algorithms.html for more information.
-
-           A commercial algorithm Lingo3G (needs to be installed separately) is defined as:
-           * com.carrotsearch.lingo3g.Lingo3GClusteringAlgorithm
-        -->
-      <str name="carrot.algorithm">org.carrot2.clustering.lingo.LingoClusteringAlgorithm</str>
+    <!--
+    Declaration of "engines" (clustering algorithms).
 
-      <!-- Override location of the clustering algorithm's resources 
-           (attribute definitions and lexical resources).
+    The open source algorithms from Carrot2.org project:
+      * org.carrot2.clustering.lingo.LingoClusteringAlgorithm
+      * org.carrot2.clustering.stc.STCClusteringAlgorithm
+      * org.carrot2.clustering.kmeans.BisectingKMeansClusteringAlgorithm
+    See http://project.carrot2.org/algorithms.html for more information.
 
-           A directory from which to load algorithm-specific stop words,
-           stop labels and attribute definition XMLs. 
+    Commercial algorithm Lingo3G (needs to be installed separately):
+      * com.carrotsearch.lingo3g.Lingo3GClusteringAlgorithm
+    -->
 
-           For an overview of Carrot2 lexical resources, see:
-           http://download.carrot2.org/head/manual/#chapter.lexical-resources
+    <lst name="engine">
+      <str name="name">lingo3g</str>
+      <bool name="optional">true</bool>
+      <str name="carrot.algorithm">com.carrotsearch.lingo3g.Lingo3GClusteringAlgorithm</str>
+      <str name="carrot.resourcesDir">clustering/carrot2</str>
+    </lst>
 
-           For an overview of Lingo3G lexical resources, see:
-           http://download.carrotsearch.com/lingo3g/manual/#chapter.lexical-resources
-       -->
+    <lst name="engine">
+      <str name="name">lingo</str>
+      <str name="carrot.algorithm">org.carrot2.clustering.lingo.LingoClusteringAlgorithm</str>
       <str name="carrot.resourcesDir">clustering/carrot2</str>
     </lst>
 
-    <!-- An example definition for the STC clustering algorithm. -->
     <lst name="engine">
       <str name="name">stc</str>
       <str name="carrot.algorithm">org.carrot2.clustering.stc.STCClusteringAlgorithm</str>
+      <str name="carrot.resourcesDir">clustering/carrot2</str>
     </lst>
 
-    <!-- An example definition for the bisecting kmeans clustering algorithm. -->
     <lst name="engine">
       <str name="name">kmeans</str>
       <str name="carrot.algorithm">org.carrot2.clustering.kmeans.BisectingKMeansClusteringAlgorithm</str>
+      <str name="carrot.resourcesDir">clustering/carrot2</str>
     </lst>
   </searchComponent>
 
-  <!-- A request handler for demonstrating the clustering component
-
-       This is purely as an example.
-
+  <!-- A request handler for demonstrating the clustering component.
+       This is meant as an example.
        In reality you will likely want to add the component to your 
        already specified request handlers. 
     -->
@@ -1447,14 +1437,14 @@
         text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4
       </str>
       <str name="q.alt">*:*</str>
-      <str name="rows">10</str>
+      <str name="rows">100</str>
       <str name="fl">*,score</str>
     </lst>
     <arr name="last-components">
       <str>clustering</str>
     </arr>
   </requestHandler>
-  
+
   <!-- Terms Component
 
        http://wiki.apache.org/solr/TermsComponent

Modified: lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/velocity/facet_ranges.vm
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/velocity/facet_ranges.vm?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/velocity/facet_ranges.vm (original)
+++ lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/velocity/facet_ranges.vm Wed Sep  2 13:06:13 2015
@@ -10,14 +10,14 @@
 #foreach ($field in $response.response.facet_counts.facet_ranges)
   ## Hide facets without value
   #if($field.value.counts.size() > 0)
-	#set($name = $field.key)
-	#set($display = $name)
-	#set($f = $field.value.counts)
-	#set($start = $field.value.start)
-	#set($end = $field.value.end)
-	#set($gap = $field.value.gap)
-	#set($before = $field.value.before)
-	#set($after = $field.value.after)
-	#display_facet_range($f, $display, $name, $start, $end, $gap, $before, $after)
+  #set($name = $field.key)
+  #set($display = $name)
+  #set($f = $field.value.counts)
+  #set($start = $field.value.start)
+  #set($end = $field.value.end)
+  #set($gap = $field.value.gap)
+  #set($before = $field.value.before)
+  #set($after = $field.value.after)
+  #display_facet_range($f, $display, $name, $start, $end, $gap, $before, $after)
   #end  ## end if has any values
 #end    ## end for each facet range

Modified: lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/velocity/jquery.autocomplete.css
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/velocity/jquery.autocomplete.css?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/velocity/jquery.autocomplete.css (original)
+++ lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/velocity/jquery.autocomplete.css Wed Sep  2 13:06:13 2015
@@ -1,48 +1,48 @@
 .ac_results {
-	padding: 0px;
-	border: 1px solid black;
-	background-color: white;
-	overflow: hidden;
-	z-index: 99999;
+  padding: 0px;
+  border: 1px solid black;
+  background-color: white;
+  overflow: hidden;
+  z-index: 99999;
 }
 
 .ac_results ul {
-	width: 100%;
-	list-style-position: outside;
-	list-style: none;
-	padding: 0;
-	margin: 0;
+  width: 100%;
+  list-style-position: outside;
+  list-style: none;
+  padding: 0;
+  margin: 0;
 }
 
 .ac_results li {
-	margin: 0px;
-	padding: 2px 5px;
-	cursor: default;
-	display: block;
-	/* 
-	if width will be 100% horizontal scrollbar will apear 
-	when scroll mode will be used
-	*/
-	/*width: 100%;*/
-	font: menu;
-	font-size: 12px;
-	/* 
-	it is very important, if line-height not setted or setted 
-	in relative units scroll will be broken in firefox
-	*/
-	line-height: 16px;
-	overflow: hidden;
+  margin: 0px;
+  padding: 2px 5px;
+  cursor: default;
+  display: block;
+  /* 
+  if width will be 100% horizontal scrollbar will apear 
+  when scroll mode will be used
+  */
+  /*width: 100%;*/
+  font: menu;
+  font-size: 12px;
+  /* 
+  it is very important, if line-height not setted or setted 
+  in relative units scroll will be broken in firefox
+  */
+  line-height: 16px;
+  overflow: hidden;
 }
 
 .ac_loading {
-	background: white url('indicator.gif') right center no-repeat;
+  background: white url('indicator.gif') right center no-repeat;
 }
 
 .ac_odd {
-	background-color: #eee;
+  background-color: #eee;
 }
 
 .ac_over {
-	background-color: #0A246A;
-	color: white;
+  background-color: #0A246A;
+  color: white;
 }

Modified: lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/velocity/jquery.autocomplete.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/velocity/jquery.autocomplete.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/velocity/jquery.autocomplete.js (original)
+++ lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/velocity/jquery.autocomplete.js Wed Sep  2 13:06:13 2015
@@ -12,752 +12,752 @@
  */
 
 ;(function($) {
-	
+  
 $.fn.extend({
-	autocomplete: function(urlOrData, options) {
-		var isUrl = typeof urlOrData == "string";
-		options = $.extend({}, $.Autocompleter.defaults, {
-			url: isUrl ? urlOrData : null,
-			data: isUrl ? null : urlOrData,
-			delay: isUrl ? $.Autocompleter.defaults.delay : 10,
-			max: options && !options.scroll ? 10 : 150
-		}, options);
-		
-		// if highlight is set to false, replace it with a do-nothing function
-		options.highlight = options.highlight || function(value) { return value; };
-		
-		// if the formatMatch option is not specified, then use formatItem for backwards compatibility
-		options.formatMatch = options.formatMatch || options.formatItem;
-		
-		return this.each(function() {
-			new $.Autocompleter(this, options);
-		});
-	},
-	result: function(handler) {
-		return this.bind("result", handler);
-	},
-	search: function(handler) {
-		return this.trigger("search", [handler]);
-	},
-	flushCache: function() {
-		return this.trigger("flushCache");
-	},
-	setOptions: function(options){
-		return this.trigger("setOptions", [options]);
-	},
-	unautocomplete: function() {
-		return this.trigger("unautocomplete");
-	}
+  autocomplete: function(urlOrData, options) {
+    var isUrl = typeof urlOrData == "string";
+    options = $.extend({}, $.Autocompleter.defaults, {
+      url: isUrl ? urlOrData : null,
+      data: isUrl ? null : urlOrData,
+      delay: isUrl ? $.Autocompleter.defaults.delay : 10,
+      max: options && !options.scroll ? 10 : 150
+    }, options);
+    
+    // if highlight is set to false, replace it with a do-nothing function
+    options.highlight = options.highlight || function(value) { return value; };
+    
+    // if the formatMatch option is not specified, then use formatItem for backwards compatibility
+    options.formatMatch = options.formatMatch || options.formatItem;
+    
+    return this.each(function() {
+      new $.Autocompleter(this, options);
+    });
+  },
+  result: function(handler) {
+    return this.bind("result", handler);
+  },
+  search: function(handler) {
+    return this.trigger("search", [handler]);
+  },
+  flushCache: function() {
+    return this.trigger("flushCache");
+  },
+  setOptions: function(options){
+    return this.trigger("setOptions", [options]);
+  },
+  unautocomplete: function() {
+    return this.trigger("unautocomplete");
+  }
 });
 
 $.Autocompleter = function(input, options) {
 
-	var KEY = {
-		UP: 38,
-		DOWN: 40,
-		DEL: 46,
-		TAB: 9,
-		RETURN: 13,
-		ESC: 27,
-		COMMA: 188,
-		PAGEUP: 33,
-		PAGEDOWN: 34,
-		BACKSPACE: 8
-	};
-
-	// Create $ object for input element
-	var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);
-
-	var timeout;
-	var previousValue = "";
-	var cache = $.Autocompleter.Cache(options);
-	var hasFocus = 0;
-	var lastKeyPressCode;
-	var config = {
-		mouseDownOnSelect: false
-	};
-	var select = $.Autocompleter.Select(options, input, selectCurrent, config);
-	
-	var blockSubmit;
-	
-	// prevent form submit in opera when selecting with return key
-	$.browser.opera && $(input.form).bind("submit.autocomplete", function() {
-		if (blockSubmit) {
-			blockSubmit = false;
-			return false;
-		}
-	});
-	
-	// only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
-	$input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
-		// track last key pressed
-		lastKeyPressCode = event.keyCode;
-		switch(event.keyCode) {
-		
-			case KEY.UP:
-				event.preventDefault();
-				if ( select.visible() ) {
-					select.prev();
-				} else {
-					onChange(0, true);
-				}
-				break;
-				
-			case KEY.DOWN:
-				event.preventDefault();
-				if ( select.visible() ) {
-					select.next();
-				} else {
-					onChange(0, true);
-				}
-				break;
-				
-			case KEY.PAGEUP:
-				event.preventDefault();
-				if ( select.visible() ) {
-					select.pageUp();
-				} else {
-					onChange(0, true);
-				}
-				break;
-				
-			case KEY.PAGEDOWN:
-				event.preventDefault();
-				if ( select.visible() ) {
-					select.pageDown();
-				} else {
-					onChange(0, true);
-				}
-				break;
-			
-			// matches also semicolon
-			case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
-			case KEY.TAB:
-			case KEY.RETURN:
-				if( selectCurrent() ) {
-					// stop default to prevent a form submit, Opera needs special handling
-					event.preventDefault();
-					blockSubmit = true;
-					return false;
-				}
-				break;
-				
-			case KEY.ESC:
-				select.hide();
-				break;
-				
-			default:
-				clearTimeout(timeout);
-				timeout = setTimeout(onChange, options.delay);
-				break;
-		}
-	}).focus(function(){
-		// track whether the field has focus, we shouldn't process any
-		// results if the field no longer has focus
-		hasFocus++;
-	}).blur(function() {
-		hasFocus = 0;
-		if (!config.mouseDownOnSelect) {
-			hideResults();
-		}
-	}).click(function() {
-		// show select when clicking in a focused field
-		if ( hasFocus++ > 1 && !select.visible() ) {
-			onChange(0, true);
-		}
-	}).bind("search", function() {
-		// TODO why not just specifying both arguments?
-		var fn = (arguments.length > 1) ? arguments[1] : null;
-		function findValueCallback(q, data) {
-			var result;
-			if( data && data.length ) {
-				for (var i=0; i < data.length; i++) {
-					if( data[i].result.toLowerCase() == q.toLowerCase() ) {
-						result = data[i];
-						break;
-					}
-				}
-			}
-			if( typeof fn == "function" ) fn(result);
-			else $input.trigger("result", result && [result.data, result.value]);
-		}
-		$.each(trimWords($input.val()), function(i, value) {
-			request(value, findValueCallback, findValueCallback);
-		});
-	}).bind("flushCache", function() {
-		cache.flush();
-	}).bind("setOptions", function() {
-		$.extend(options, arguments[1]);
-		// if we've updated the data, repopulate
-		if ( "data" in arguments[1] )
-			cache.populate();
-	}).bind("unautocomplete", function() {
-		select.unbind();
-		$input.unbind();
-		$(input.form).unbind(".autocomplete");
-	});
-	
-	
-	function selectCurrent() {
-		var selected = select.selected();
-		if( !selected )
-			return false;
-		
-		var v = selected.result;
-		previousValue = v;
-		
-		if ( options.multiple ) {
-			var words = trimWords($input.val());
-			if ( words.length > 1 ) {
-				v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v;
-			}
-			v += options.multipleSeparator;
-		}
-		
-		$input.val(v);
-		hideResultsNow();
-		$input.trigger("result", [selected.data, selected.value]);
-		return true;
-	}
-	
-	function onChange(crap, skipPrevCheck) {
-		if( lastKeyPressCode == KEY.DEL ) {
-			select.hide();
-			return;
-		}
-		
-		var currentValue = $input.val();
-		
-		if ( !skipPrevCheck && currentValue == previousValue )
-			return;
-		
-		previousValue = currentValue;
-		
-		currentValue = lastWord(currentValue);
-		if ( currentValue.length >= options.minChars) {
-			$input.addClass(options.loadingClass);
-			if (!options.matchCase)
-				currentValue = currentValue.toLowerCase();
-			request(currentValue, receiveData, hideResultsNow);
-		} else {
-			stopLoading();
-			select.hide();
-		}
-	};
-	
-	function trimWords(value) {
-		if ( !value ) {
-			return [""];
-		}
-		var words = value.split( options.multipleSeparator );
-		var result = [];
-		$.each(words, function(i, value) {
-			if ( $.trim(value) )
-				result[i] = $.trim(value);
-		});
-		return result;
-	}
-	
-	function lastWord(value) {
-		if ( !options.multiple )
-			return value;
-		var words = trimWords(value);
-		return words[words.length - 1];
-	}
-	
-	// fills in the input box w/the first match (assumed to be the best match)
-	// q: the term entered
-	// sValue: the first matching result
-	function autoFill(q, sValue){
-		// autofill in the complete box w/the first match as long as the user hasn't entered in more data
-		// if the last user key pressed was backspace, don't autofill
-		if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
-			// fill in the value (keep the case the user has typed)
-			$input.val($input.val() + sValue.substring(lastWord(previousValue).length));
-			// select the portion of the value not typed by the user (so the next character will erase)
-			$.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length);
-		}
-	};
-
-	function hideResults() {
-		clearTimeout(timeout);
-		timeout = setTimeout(hideResultsNow, 200);
-	};
-
-	function hideResultsNow() {
-		var wasVisible = select.visible();
-		select.hide();
-		clearTimeout(timeout);
-		stopLoading();
-		if (options.mustMatch) {
-			// call search and run callback
-			$input.search(
-				function (result){
-					// if no value found, clear the input box
-					if( !result ) {
-						if (options.multiple) {
-							var words = trimWords($input.val()).slice(0, -1);
-							$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
-						}
-						else
-							$input.val( "" );
-					}
-				}
-			);
-		}
-		if (wasVisible)
-			// position cursor at end of input field
-			$.Autocompleter.Selection(input, input.value.length, input.value.length);
-	};
-
-	function receiveData(q, data) {
-		if ( data && data.length && hasFocus ) {
-			stopLoading();
-			select.display(data, q);
-			autoFill(q, data[0].value);
-			select.show();
-		} else {
-			hideResultsNow();
-		}
-	};
-
-	function request(term, success, failure) {
-		if (!options.matchCase)
-			term = term.toLowerCase();
-		var data = cache.load(term);
-		data = null; // Avoid buggy cache and go to Solr every time 
-		// recieve the cached data
-		if (data && data.length) {
-			success(term, data);
-		// if an AJAX url has been supplied, try loading the data now
-		} else if( (typeof options.url == "string") && (options.url.length > 0) ){
-			
-			var extraParams = {
-				timestamp: +new Date()
-			};
-			$.each(options.extraParams, function(key, param) {
-				extraParams[key] = typeof param == "function" ? param() : param;
-			});
-			
-			$.ajax({
-				// try to leverage ajaxQueue plugin to abort previous requests
-				mode: "abort",
-				// limit abortion to this input
-				port: "autocomplete" + input.name,
-				dataType: options.dataType,
-				url: options.url,
-				data: $.extend({
-					q: lastWord(term),
-					limit: options.max
-				}, extraParams),
-				success: function(data) {
-					var parsed = options.parse && options.parse(data) || parse(data);
-					cache.add(term, parsed);
-					success(term, parsed);
-				}
-			});
-		} else {
-			// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
-			select.emptyList();
-			failure(term);
-		}
-	};
-	
-	function parse(data) {
-		var parsed = [];
-		var rows = data.split("\n");
-		for (var i=0; i < rows.length; i++) {
-			var row = $.trim(rows[i]);
-			if (row) {
-				row = row.split("|");
-				parsed[parsed.length] = {
-					data: row,
-					value: row[0],
-					result: options.formatResult && options.formatResult(row, row[0]) || row[0]
-				};
-			}
-		}
-		return parsed;
-	};
-
-	function stopLoading() {
-		$input.removeClass(options.loadingClass);
-	};
+  var KEY = {
+    UP: 38,
+    DOWN: 40,
+    DEL: 46,
+    TAB: 9,
+    RETURN: 13,
+    ESC: 27,
+    COMMA: 188,
+    PAGEUP: 33,
+    PAGEDOWN: 34,
+    BACKSPACE: 8
+  };
+
+  // Create $ object for input element
+  var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);
+
+  var timeout;
+  var previousValue = "";
+  var cache = $.Autocompleter.Cache(options);
+  var hasFocus = 0;
+  var lastKeyPressCode;
+  var config = {
+    mouseDownOnSelect: false
+  };
+  var select = $.Autocompleter.Select(options, input, selectCurrent, config);
+  
+  var blockSubmit;
+  
+  // prevent form submit in opera when selecting with return key
+  $.browser.opera && $(input.form).bind("submit.autocomplete", function() {
+    if (blockSubmit) {
+      blockSubmit = false;
+      return false;
+    }
+  });
+  
+  // only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
+  $input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
+    // track last key pressed
+    lastKeyPressCode = event.keyCode;
+    switch(event.keyCode) {
+    
+      case KEY.UP:
+        event.preventDefault();
+        if ( select.visible() ) {
+          select.prev();
+        } else {
+          onChange(0, true);
+        }
+        break;
+        
+      case KEY.DOWN:
+        event.preventDefault();
+        if ( select.visible() ) {
+          select.next();
+        } else {
+          onChange(0, true);
+        }
+        break;
+        
+      case KEY.PAGEUP:
+        event.preventDefault();
+        if ( select.visible() ) {
+          select.pageUp();
+        } else {
+          onChange(0, true);
+        }
+        break;
+        
+      case KEY.PAGEDOWN:
+        event.preventDefault();
+        if ( select.visible() ) {
+          select.pageDown();
+        } else {
+          onChange(0, true);
+        }
+        break;
+      
+      // matches also semicolon
+      case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
+      case KEY.TAB:
+      case KEY.RETURN:
+        if( selectCurrent() ) {
+          // stop default to prevent a form submit, Opera needs special handling
+          event.preventDefault();
+          blockSubmit = true;
+          return false;
+        }
+        break;
+        
+      case KEY.ESC:
+        select.hide();
+        break;
+        
+      default:
+        clearTimeout(timeout);
+        timeout = setTimeout(onChange, options.delay);
+        break;
+    }
+  }).focus(function(){
+    // track whether the field has focus, we shouldn't process any
+    // results if the field no longer has focus
+    hasFocus++;
+  }).blur(function() {
+    hasFocus = 0;
+    if (!config.mouseDownOnSelect) {
+      hideResults();
+    }
+  }).click(function() {
+    // show select when clicking in a focused field
+    if ( hasFocus++ > 1 && !select.visible() ) {
+      onChange(0, true);
+    }
+  }).bind("search", function() {
+    // TODO why not just specifying both arguments?
+    var fn = (arguments.length > 1) ? arguments[1] : null;
+    function findValueCallback(q, data) {
+      var result;
+      if( data && data.length ) {
+        for (var i=0; i < data.length; i++) {
+          if( data[i].result.toLowerCase() == q.toLowerCase() ) {
+            result = data[i];
+            break;
+          }
+        }
+      }
+      if( typeof fn == "function" ) fn(result);
+      else $input.trigger("result", result && [result.data, result.value]);
+    }
+    $.each(trimWords($input.val()), function(i, value) {
+      request(value, findValueCallback, findValueCallback);
+    });
+  }).bind("flushCache", function() {
+    cache.flush();
+  }).bind("setOptions", function() {
+    $.extend(options, arguments[1]);
+    // if we've updated the data, repopulate
+    if ( "data" in arguments[1] )
+      cache.populate();
+  }).bind("unautocomplete", function() {
+    select.unbind();
+    $input.unbind();
+    $(input.form).unbind(".autocomplete");
+  });
+  
+  
+  function selectCurrent() {
+    var selected = select.selected();
+    if( !selected )
+      return false;
+    
+    var v = selected.result;
+    previousValue = v;
+    
+    if ( options.multiple ) {
+      var words = trimWords($input.val());
+      if ( words.length > 1 ) {
+        v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v;
+      }
+      v += options.multipleSeparator;
+    }
+    
+    $input.val(v);
+    hideResultsNow();
+    $input.trigger("result", [selected.data, selected.value]);
+    return true;
+  }
+  
+  function onChange(crap, skipPrevCheck) {
+    if( lastKeyPressCode == KEY.DEL ) {
+      select.hide();
+      return;
+    }
+    
+    var currentValue = $input.val();
+    
+    if ( !skipPrevCheck && currentValue == previousValue )
+      return;
+    
+    previousValue = currentValue;
+    
+    currentValue = lastWord(currentValue);
+    if ( currentValue.length >= options.minChars) {
+      $input.addClass(options.loadingClass);
+      if (!options.matchCase)
+        currentValue = currentValue.toLowerCase();
+      request(currentValue, receiveData, hideResultsNow);
+    } else {
+      stopLoading();
+      select.hide();
+    }
+  };
+  
+  function trimWords(value) {
+    if ( !value ) {
+      return [""];
+    }
+    var words = value.split( options.multipleSeparator );
+    var result = [];
+    $.each(words, function(i, value) {
+      if ( $.trim(value) )
+        result[i] = $.trim(value);
+    });
+    return result;
+  }
+  
+  function lastWord(value) {
+    if ( !options.multiple )
+      return value;
+    var words = trimWords(value);
+    return words[words.length - 1];
+  }
+  
+  // fills in the input box w/the first match (assumed to be the best match)
+  // q: the term entered
+  // sValue: the first matching result
+  function autoFill(q, sValue){
+    // autofill in the complete box w/the first match as long as the user hasn't entered in more data
+    // if the last user key pressed was backspace, don't autofill
+    if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
+      // fill in the value (keep the case the user has typed)
+      $input.val($input.val() + sValue.substring(lastWord(previousValue).length));
+      // select the portion of the value not typed by the user (so the next character will erase)
+      $.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length);
+    }
+  };
+
+  function hideResults() {
+    clearTimeout(timeout);
+    timeout = setTimeout(hideResultsNow, 200);
+  };
+
+  function hideResultsNow() {
+    var wasVisible = select.visible();
+    select.hide();
+    clearTimeout(timeout);
+    stopLoading();
+    if (options.mustMatch) {
+      // call search and run callback
+      $input.search(
+        function (result){
+          // if no value found, clear the input box
+          if( !result ) {
+            if (options.multiple) {
+              var words = trimWords($input.val()).slice(0, -1);
+              $input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
+            }
+            else
+              $input.val( "" );
+          }
+        }
+      );
+    }
+    if (wasVisible)
+      // position cursor at end of input field
+      $.Autocompleter.Selection(input, input.value.length, input.value.length);
+  };
+
+  function receiveData(q, data) {
+    if ( data && data.length && hasFocus ) {
+      stopLoading();
+      select.display(data, q);
+      autoFill(q, data[0].value);
+      select.show();
+    } else {
+      hideResultsNow();
+    }
+  };
+
+  function request(term, success, failure) {
+    if (!options.matchCase)
+      term = term.toLowerCase();
+    var data = cache.load(term);
+    data = null; // Avoid buggy cache and go to Solr every time 
+    // recieve the cached data
+    if (data && data.length) {
+      success(term, data);
+    // if an AJAX url has been supplied, try loading the data now
+    } else if( (typeof options.url == "string") && (options.url.length > 0) ){
+      
+      var extraParams = {
+        timestamp: +new Date()
+      };
+      $.each(options.extraParams, function(key, param) {
+        extraParams[key] = typeof param == "function" ? param() : param;
+      });
+      
+      $.ajax({
+        // try to leverage ajaxQueue plugin to abort previous requests
+        mode: "abort",
+        // limit abortion to this input
+        port: "autocomplete" + input.name,
+        dataType: options.dataType,
+        url: options.url,
+        data: $.extend({
+          q: lastWord(term),
+          limit: options.max
+        }, extraParams),
+        success: function(data) {
+          var parsed = options.parse && options.parse(data) || parse(data);
+          cache.add(term, parsed);
+          success(term, parsed);
+        }
+      });
+    } else {
+      // if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
+      select.emptyList();
+      failure(term);
+    }
+  };
+  
+  function parse(data) {
+    var parsed = [];
+    var rows = data.split("\n");
+    for (var i=0; i < rows.length; i++) {
+      var row = $.trim(rows[i]);
+      if (row) {
+        row = row.split("|");
+        parsed[parsed.length] = {
+          data: row,
+          value: row[0],
+          result: options.formatResult && options.formatResult(row, row[0]) || row[0]
+        };
+      }
+    }
+    return parsed;
+  };
+
+  function stopLoading() {
+    $input.removeClass(options.loadingClass);
+  };
 
 };
 
 $.Autocompleter.defaults = {
-	inputClass: "ac_input",
-	resultsClass: "ac_results",
-	loadingClass: "ac_loading",
-	minChars: 1,
-	delay: 400,
-	matchCase: false,
-	matchSubset: true,
-	matchContains: false,
-	cacheLength: 10,
-	max: 100,
-	mustMatch: false,
-	extraParams: {},
-	selectFirst: false,
-	formatItem: function(row) { return row[0]; },
-	formatMatch: null,
-	autoFill: false,
-	width: 0,
-	multiple: false,
-	multipleSeparator: ", ",
-	highlight: function(value, term) {
-		return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
-	},
+  inputClass: "ac_input",
+  resultsClass: "ac_results",
+  loadingClass: "ac_loading",
+  minChars: 1,
+  delay: 400,
+  matchCase: false,
+  matchSubset: true,
+  matchContains: false,
+  cacheLength: 10,
+  max: 100,
+  mustMatch: false,
+  extraParams: {},
+  selectFirst: false,
+  formatItem: function(row) { return row[0]; },
+  formatMatch: null,
+  autoFill: false,
+  width: 0,
+  multiple: false,
+  multipleSeparator: ", ",
+  highlight: function(value, term) {
+    return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
+  },
     scroll: true,
     scrollHeight: 180
 };
 
 $.Autocompleter.Cache = function(options) {
 
-	var data = {};
-	var length = 0;
-	
-	function matchSubset(s, sub) {
-		if (!options.matchCase) 
-			s = s.toLowerCase();
-		var i = s.indexOf(sub);
-		if (options.matchContains == "word"){
-			i = s.toLowerCase().search("\\b" + sub.toLowerCase());
-		}
-		if (i == -1) return false;
-		return i == 0 || options.matchContains;
-	};
-	
-	function add(q, value) {
-		if (length > options.cacheLength){
-			flush();
-		}
-		if (!data[q]){ 
-			length++;
-		}
-		data[q] = value;
-	}
-	
-	function populate(){
-		if( !options.data ) return false;
-		// track the matches
-		var stMatchSets = {},
-			nullData = 0;
-
-		// no url was specified, we need to adjust the cache length to make sure it fits the local data store
-		if( !options.url ) options.cacheLength = 1;
-		
-		// track all options for minChars = 0
-		stMatchSets[""] = [];
-		
-		// loop through the array and create a lookup structure
-		for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
-			var rawValue = options.data[i];
-			// if rawValue is a string, make an array otherwise just reference the array
-			rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
-			
-			var value = options.formatMatch(rawValue, i+1, options.data.length);
-			if ( value === false )
-				continue;
-				
-			var firstChar = value.charAt(0).toLowerCase();
-			// if no lookup array for this character exists, look it up now
-			if( !stMatchSets[firstChar] ) 
-				stMatchSets[firstChar] = [];
-
-			// if the match is a string
-			var row = {
-				value: value,
-				data: rawValue,
-				result: options.formatResult && options.formatResult(rawValue) || value
-			};
-			
-			// push the current match into the set list
-			stMatchSets[firstChar].push(row);
-
-			// keep track of minChars zero items
-			if ( nullData++ < options.max ) {
-				stMatchSets[""].push(row);
-			}
-		};
-
-		// add the data items to the cache
-		$.each(stMatchSets, function(i, value) {
-			// increase the cache size
-			options.cacheLength++;
-			// add to the cache
-			add(i, value);
-		});
-	}
-	
-	// populate any existing data
-	setTimeout(populate, 25);
-	
-	function flush(){
-		data = {};
-		length = 0;
-	}
-	
-	return {
-		flush: flush,
-		add: add,
-		populate: populate,
-		load: function(q) {
-			if (!options.cacheLength || !length)
-				return null;
-			/* 
-			 * if dealing w/local data and matchContains than we must make sure
-			 * to loop through all the data collections looking for matches
-			 */
-			if( !options.url && options.matchContains ){
-				// track all matches
-				var csub = [];
-				// loop through all the data grids for matches
-				for( var k in data ){
-					// don't search through the stMatchSets[""] (minChars: 0) cache
-					// this prevents duplicates
-					if( k.length > 0 ){
-						var c = data[k];
-						$.each(c, function(i, x) {
-							// if we've got a match, add it to the array
-							if (matchSubset(x.value, q)) {
-								csub.push(x);
-							}
-						});
-					}
-				}				
-				return csub;
-			} else 
-			// if the exact item exists, use it
-			if (data[q]){
-				return data[q];
-			} else
-			if (options.matchSubset) {
-				for (var i = q.length - 1; i >= options.minChars; i--) {
-					var c = data[q.substr(0, i)];
-					if (c) {
-						var csub = [];
-						$.each(c, function(i, x) {
-							if (matchSubset(x.value, q)) {
-								csub[csub.length] = x;
-							}
-						});
-						return csub;
-					}
-				}
-			}
-			return null;
-		}
-	};
+  var data = {};
+  var length = 0;
+  
+  function matchSubset(s, sub) {
+    if (!options.matchCase) 
+      s = s.toLowerCase();
+    var i = s.indexOf(sub);
+    if (options.matchContains == "word"){
+      i = s.toLowerCase().search("\\b" + sub.toLowerCase());
+    }
+    if (i == -1) return false;
+    return i == 0 || options.matchContains;
+  };
+  
+  function add(q, value) {
+    if (length > options.cacheLength){
+      flush();
+    }
+    if (!data[q]){ 
+      length++;
+    }
+    data[q] = value;
+  }
+  
+  function populate(){
+    if( !options.data ) return false;
+    // track the matches
+    var stMatchSets = {},
+      nullData = 0;
+
+    // no url was specified, we need to adjust the cache length to make sure it fits the local data store
+    if( !options.url ) options.cacheLength = 1;
+    
+    // track all options for minChars = 0
+    stMatchSets[""] = [];
+    
+    // loop through the array and create a lookup structure
+    for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
+      var rawValue = options.data[i];
+      // if rawValue is a string, make an array otherwise just reference the array
+      rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
+      
+      var value = options.formatMatch(rawValue, i+1, options.data.length);
+      if ( value === false )
+        continue;
+        
+      var firstChar = value.charAt(0).toLowerCase();
+      // if no lookup array for this character exists, look it up now
+      if( !stMatchSets[firstChar] ) 
+        stMatchSets[firstChar] = [];
+
+      // if the match is a string
+      var row = {
+        value: value,
+        data: rawValue,
+        result: options.formatResult && options.formatResult(rawValue) || value
+      };
+      
+      // push the current match into the set list
+      stMatchSets[firstChar].push(row);
+
+      // keep track of minChars zero items
+      if ( nullData++ < options.max ) {
+        stMatchSets[""].push(row);
+      }
+    };
+
+    // add the data items to the cache
+    $.each(stMatchSets, function(i, value) {
+      // increase the cache size
+      options.cacheLength++;
+      // add to the cache
+      add(i, value);
+    });
+  }
+  
+  // populate any existing data
+  setTimeout(populate, 25);
+  
+  function flush(){
+    data = {};
+    length = 0;
+  }
+  
+  return {
+    flush: flush,
+    add: add,
+    populate: populate,
+    load: function(q) {
+      if (!options.cacheLength || !length)
+        return null;
+      /* 
+       * if dealing w/local data and matchContains than we must make sure
+       * to loop through all the data collections looking for matches
+       */
+      if( !options.url && options.matchContains ){
+        // track all matches
+        var csub = [];
+        // loop through all the data grids for matches
+        for( var k in data ){
+          // don't search through the stMatchSets[""] (minChars: 0) cache
+          // this prevents duplicates
+          if( k.length > 0 ){
+            var c = data[k];
+            $.each(c, function(i, x) {
+              // if we've got a match, add it to the array
+              if (matchSubset(x.value, q)) {
+                csub.push(x);
+              }
+            });
+          }
+        }        
+        return csub;
+      } else 
+      // if the exact item exists, use it
+      if (data[q]){
+        return data[q];
+      } else
+      if (options.matchSubset) {
+        for (var i = q.length - 1; i >= options.minChars; i--) {
+          var c = data[q.substr(0, i)];
+          if (c) {
+            var csub = [];
+            $.each(c, function(i, x) {
+              if (matchSubset(x.value, q)) {
+                csub[csub.length] = x;
+              }
+            });
+            return csub;
+          }
+        }
+      }
+      return null;
+    }
+  };
 };
 
 $.Autocompleter.Select = function (options, input, select, config) {
-	var CLASSES = {
-		ACTIVE: "ac_over"
-	};
-	
-	var listItems,
-		active = -1,
-		data,
-		term = "",
-		needsInit = true,
-		element,
-		list;
-	
-	// Create results
-	function init() {
-		if (!needsInit)
-			return;
-		element = $("<div/>")
-		.hide()
-		.addClass(options.resultsClass)
-		.css("position", "absolute")
-		.appendTo(document.body);
-	
-		list = $("<ul/>").appendTo(element).mouseover( function(event) {
-			if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
-	            active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
-			    $(target(event)).addClass(CLASSES.ACTIVE);            
-	        }
-		}).click(function(event) {
-			$(target(event)).addClass(CLASSES.ACTIVE);
-			select();
-			// TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
-			input.focus();
-			return false;
-		}).mousedown(function() {
-			config.mouseDownOnSelect = true;
-		}).mouseup(function() {
-			config.mouseDownOnSelect = false;
-		});
-		
-		if( options.width > 0 )
-			element.css("width", options.width);
-			
-		needsInit = false;
-	} 
-	
-	function target(event) {
-		var element = event.target;
-		while(element && element.tagName != "LI")
-			element = element.parentNode;
-		// more fun with IE, sometimes event.target is empty, just ignore it then
-		if(!element)
-			return [];
-		return element;
-	}
-
-	function moveSelect(step) {
-		listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
-		movePosition(step);
+  var CLASSES = {
+    ACTIVE: "ac_over"
+  };
+  
+  var listItems,
+    active = -1,
+    data,
+    term = "",
+    needsInit = true,
+    element,
+    list;
+  
+  // Create results
+  function init() {
+    if (!needsInit)
+      return;
+    element = $("<div/>")
+    .hide()
+    .addClass(options.resultsClass)
+    .css("position", "absolute")
+    .appendTo(document.body);
+  
+    list = $("<ul/>").appendTo(element).mouseover( function(event) {
+      if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
+              active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
+          $(target(event)).addClass(CLASSES.ACTIVE);            
+          }
+    }).click(function(event) {
+      $(target(event)).addClass(CLASSES.ACTIVE);
+      select();
+      // TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
+      input.focus();
+      return false;
+    }).mousedown(function() {
+      config.mouseDownOnSelect = true;
+    }).mouseup(function() {
+      config.mouseDownOnSelect = false;
+    });
+    
+    if( options.width > 0 )
+      element.css("width", options.width);
+      
+    needsInit = false;
+  } 
+  
+  function target(event) {
+    var element = event.target;
+    while(element && element.tagName != "LI")
+      element = element.parentNode;
+    // more fun with IE, sometimes event.target is empty, just ignore it then
+    if(!element)
+      return [];
+    return element;
+  }
+
+  function moveSelect(step) {
+    listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
+    movePosition(step);
         var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
         if(options.scroll) {
             var offset = 0;
             listItems.slice(0, active).each(function() {
-				offset += this.offsetHeight;
-			});
+        offset += this.offsetHeight;
+      });
             if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
                 list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
             } else if(offset < list.scrollTop()) {
                 list.scrollTop(offset);
             }
         }
-	};
-	
-	function movePosition(step) {
-		active += step;
-		if (active < 0) {
-			active = listItems.size() - 1;
-		} else if (active >= listItems.size()) {
-			active = 0;
-		}
-	}
-	
-	function limitNumberOfItems(available) {
-		return options.max && options.max < available
-			? options.max
-			: available;
-	}
-	
-	function fillList() {
-		list.empty();
-		var max = limitNumberOfItems(data.length);
-		for (var i=0; i < max; i++) {
-			if (!data[i])
-				continue;
-			var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
-			if ( formatted === false )
-				continue;
-			var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
-			$.data(li, "ac_data", data[i]);
-		}
-		listItems = list.find("li");
-		if ( options.selectFirst ) {
-			listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
-			active = 0;
-		}
-		// apply bgiframe if available
-		if ( $.fn.bgiframe )
-			list.bgiframe();
-	}
-	
-	return {
-		display: function(d, q) {
-			init();
-			data = d;
-			term = q;
-			fillList();
-		},
-		next: function() {
-			moveSelect(1);
-		},
-		prev: function() {
-			moveSelect(-1);
-		},
-		pageUp: function() {
-			if (active != 0 && active - 8 < 0) {
-				moveSelect( -active );
-			} else {
-				moveSelect(-8);
-			}
-		},
-		pageDown: function() {
-			if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
-				moveSelect( listItems.size() - 1 - active );
-			} else {
-				moveSelect(8);
-			}
-		},
-		hide: function() {
-			element && element.hide();
-			listItems && listItems.removeClass(CLASSES.ACTIVE);
-			active = -1;
-		},
-		visible : function() {
-			return element && element.is(":visible");
-		},
-		current: function() {
-			return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
-		},
-		show: function() {
-			var offset = $(input).offset();
-			element.css({
-				width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
-				top: offset.top + input.offsetHeight,
-				left: offset.left
-			}).show();
+  };
+  
+  function movePosition(step) {
+    active += step;
+    if (active < 0) {
+      active = listItems.size() - 1;
+    } else if (active >= listItems.size()) {
+      active = 0;
+    }
+  }
+  
+  function limitNumberOfItems(available) {
+    return options.max && options.max < available
+      ? options.max
+      : available;
+  }
+  
+  function fillList() {
+    list.empty();
+    var max = limitNumberOfItems(data.length);
+    for (var i=0; i < max; i++) {
+      if (!data[i])
+        continue;
+      var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
+      if ( formatted === false )
+        continue;
+      var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
+      $.data(li, "ac_data", data[i]);
+    }
+    listItems = list.find("li");
+    if ( options.selectFirst ) {
+      listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
+      active = 0;
+    }
+    // apply bgiframe if available
+    if ( $.fn.bgiframe )
+      list.bgiframe();
+  }
+  
+  return {
+    display: function(d, q) {
+      init();
+      data = d;
+      term = q;
+      fillList();
+    },
+    next: function() {
+      moveSelect(1);
+    },
+    prev: function() {
+      moveSelect(-1);
+    },
+    pageUp: function() {
+      if (active != 0 && active - 8 < 0) {
+        moveSelect( -active );
+      } else {
+        moveSelect(-8);
+      }
+    },
+    pageDown: function() {
+      if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
+        moveSelect( listItems.size() - 1 - active );
+      } else {
+        moveSelect(8);
+      }
+    },
+    hide: function() {
+      element && element.hide();
+      listItems && listItems.removeClass(CLASSES.ACTIVE);
+      active = -1;
+    },
+    visible : function() {
+      return element && element.is(":visible");
+    },
+    current: function() {
+      return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
+    },
+    show: function() {
+      var offset = $(input).offset();
+      element.css({
+        width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
+        top: offset.top + input.offsetHeight,
+        left: offset.left
+      }).show();
             if(options.scroll) {
                 list.scrollTop(0);
                 list.css({
-					maxHeight: options.scrollHeight,
-					overflow: 'auto'
-				});
-				
+          maxHeight: options.scrollHeight,
+          overflow: 'auto'
+        });
+        
                 if($.browser.msie && typeof document.body.style.maxHeight === "undefined") {
-					var listHeight = 0;
-					listItems.each(function() {
-						listHeight += this.offsetHeight;
-					});
-					var scrollbarsVisible = listHeight > options.scrollHeight;
+          var listHeight = 0;
+          listItems.each(function() {
+            listHeight += this.offsetHeight;
+          });
+          var scrollbarsVisible = listHeight > options.scrollHeight;
                     list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
-					if (!scrollbarsVisible) {
-						// IE doesn't recalculate width when scrollbar disappears
-						listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
-					}
+          if (!scrollbarsVisible) {
+            // IE doesn't recalculate width when scrollbar disappears
+            listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
+          }
                 }
                 
             }
-		},
-		selected: function() {
-			var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
-			return selected && selected.length && $.data(selected[0], "ac_data");
-		},
-		emptyList: function (){
-			list && list.empty();
-		},
-		unbind: function() {
-			element && element.remove();
-		}
-	};
+    },
+    selected: function() {
+      var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
+      return selected && selected.length && $.data(selected[0], "ac_data");
+    },
+    emptyList: function (){
+      list && list.empty();
+    },
+    unbind: function() {
+      element && element.remove();
+    }
+  };
 };
 
 $.Autocompleter.Selection = function(field, start, end) {
-	if( field.createTextRange ){
-		var selRange = field.createTextRange();
-		selRange.collapse(true);
-		selRange.moveStart("character", start);
-		selRange.moveEnd("character", end);
-		selRange.select();
-	} else if( field.setSelectionRange ){
-		field.setSelectionRange(start, end);
-	} else {
-		if( field.selectionStart ){
-			field.selectionStart = start;
-			field.selectionEnd = end;
-		}
-	}
-	field.focus();
+  if( field.createTextRange ){
+    var selRange = field.createTextRange();
+    selRange.collapse(true);
+    selRange.moveStart("character", start);
+    selRange.moveEnd("character", end);
+    selRange.select();
+  } else if( field.setSelectionRange ){
+    field.setSelectionRange(start, end);
+  } else {
+    if( field.selectionStart ){
+      field.selectionStart = start;
+      field.selectionEnd = end;
+    }
+  }
+  field.focus();
 };
 
 })(jQuery);
\ No newline at end of file

Modified: lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/xslt/example_rss.xsl
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/xslt/example_rss.xsl?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/xslt/example_rss.xsl (original)
+++ lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/xslt/example_rss.xsl Wed Sep  2 13:06:13 2015
@@ -32,7 +32,7 @@
   <xsl:template match='/'>
     <rss version="2.0">
        <channel>
-	 <title>Example Solr RSS 2.0 Feed</title>
+         <title>Example Solr RSS 2.0 Feed</title>
          <link>http://localhost:8983/solr</link>
          <description>
           This has been formatted by the sample "example_rss.xsl" transform -

Modified: lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/xslt/updateXml.xsl
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/xslt/updateXml.xsl?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/xslt/updateXml.xsl (original)
+++ lucene/dev/branches/lucene6699/solr/server/solr/configsets/sample_techproducts_configs/conf/xslt/updateXml.xsl Wed Sep  2 13:06:13 2015
@@ -49,10 +49,10 @@
       <xsl:variable name="fn" select="@name"/>
       
       <xsl:for-each select="*">
-		<xsl:element name="field">
-		    <xsl:attribute name="name"><xsl:value-of select="$fn"/></xsl:attribute>
-	        <xsl:value-of select="."/>
-		</xsl:element>
+        <xsl:element name="field">
+          <xsl:attribute name="name"><xsl:value-of select="$fn"/></xsl:attribute>
+          <xsl:value-of select="."/>
+        </xsl:element>
       </xsl:for-each>
   </xsl:template>
 
@@ -60,10 +60,10 @@
   <xsl:template match="doc/*">
       <xsl:variable name="fn" select="@name"/>
 
-	<xsl:element name="field">
-	    <xsl:attribute name="name"><xsl:value-of select="$fn"/></xsl:attribute>
+      <xsl:element name="field">
+        <xsl:attribute name="name"><xsl:value-of select="$fn"/></xsl:attribute>
         <xsl:value-of select="."/>
-	</xsl:element>
+      </xsl:element>
   </xsl:template>
 
   <xsl:template match="*"/>

Modified: lucene/dev/branches/lucene6699/solr/site/index.xsl
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/site/index.xsl?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/site/index.xsl (original)
+++ lucene/dev/branches/lucene6699/solr/site/index.xsl Wed Sep  2 13:06:13 2015
@@ -81,8 +81,8 @@
         <xsl:call-template name="modules"/>
       </body>
     </html>
-	</xsl:template>
-	
+  </xsl:template>
+  
   <xsl:template name="modules">
     <ul>
       <xsl:for-each select="str:split($buildfiles,'|')">

Modified: lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java Wed Sep  2 13:06:13 2015
@@ -61,6 +61,7 @@ import java.net.ConnectException;
 import java.net.SocketException;
 import java.nio.file.Path;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -74,11 +75,16 @@ import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
+import static org.apache.solr.common.params.CommonParams.AUTHC_PATH;
+import static org.apache.solr.common.params.CommonParams.AUTHZ_PATH;
+import static org.apache.solr.common.params.CommonParams.COLLECTIONS_HANDLER_PATH;
+import static org.apache.solr.common.params.CommonParams.CONFIGSETS_HANDLER_PATH;
+import static org.apache.solr.common.params.CommonParams.CORES_HANDLER_PATH;
+
 /**
  * SolrJ client class to communicate with SolrCloud.
  * Instances of this class communicate with Zookeeper to discover
@@ -799,6 +805,12 @@ public class CloudSolrClient extends Sol
       collection = (reqParams != null) ? reqParams.get("collection", getDefaultCollection()) : getDefaultCollection();
     return requestWithRetryOnStaleState(request, 0, collection);
   }
+  private static final Set<String> ADMIN_PATHS = new HashSet<>(Arrays.asList(
+      CORES_HANDLER_PATH,
+      COLLECTIONS_HANDLER_PATH,
+      CONFIGSETS_HANDLER_PATH,
+      AUTHC_PATH,
+      AUTHZ_PATH));
 
   /**
    * As this class doesn't watch external collections on the client side,
@@ -816,7 +828,8 @@ public class CloudSolrClient extends Sol
     // collections is stale and needs to be refreshed ... this code has no impact on internal collections
     String stateVerParam = null;
     List<DocCollection> requestedCollections = null;
-    if (collection != null && !request.getPath().startsWith("/admin")) { // don't do _stateVer_ checking for admin requests
+    boolean isAdmin = ADMIN_PATHS.contains(request.getPath());
+    if (collection != null &&  !isAdmin) { // don't do _stateVer_ checking for admin requests
       Set<String> requestedCollectionNames = getCollectionNames(getZkStateReader().getClusterState(), collection);
 
       StringBuilder stateVerParamBuilder = null;
@@ -871,7 +884,7 @@ public class CloudSolrClient extends Sol
 
       Throwable rootCause = SolrException.getRootCause(exc);
       // don't do retry support for admin requests or if the request doesn't have a collection specified
-      if (collection == null || request.getPath().startsWith("/admin")) {
+      if (collection == null || isAdmin) {
         if (exc instanceof SolrServerException) {
           throw (SolrServerException)exc;
         } else if (exc instanceof IOException) {
@@ -979,7 +992,7 @@ public class CloudSolrClient extends Sol
       reqParams = new ModifiableSolrParams();
     }
     List<String> theUrlList = new ArrayList<>();
-    if (request.getPath().startsWith("/admin/")) {
+    if (ADMIN_PATHS.contains(request.getPath())) {
       Set<String> liveNodes = clusterState.getLiveNodes();
       for (String liveNode : liveNodes) {
         theUrlList.add(zkStateReader.getBaseUrlForNodeName(liveNode));
@@ -1094,7 +1107,7 @@ public class CloudSolrClient extends Sol
     Set<String> collectionNames = new HashSet<>();
     // validate collections
     for (String collectionName : rawCollectionsList) {
-      if (!clusterState.getCollections().contains(collectionName)) {
+      if (!clusterState.hasCollection(collectionName)) {
         Aliases aliases = zkStateReader.getAliases();
         String alias = aliases.getCollectionAlias(collectionName);
         if (alias != null) {

Modified: lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Krb5HttpClientConfigurer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Krb5HttpClientConfigurer.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Krb5HttpClientConfigurer.java (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Krb5HttpClientConfigurer.java Wed Sep  2 13:06:13 2015
@@ -34,6 +34,7 @@ import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.Credentials;
+import org.apache.http.auth.AuthSchemeRegistry;
 import org.apache.http.impl.auth.SPNegoSchemeFactory;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.protocol.HttpContext;
@@ -77,7 +78,10 @@ public class Krb5HttpClientConfigurer ex
         }
 
         javax.security.auth.login.Configuration.setConfiguration(jaasConfig);
-        httpClient.getAuthSchemes().register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory(true, false));
+        //Enable only SPNEGO authentication scheme.
+        AuthSchemeRegistry registry = new AuthSchemeRegistry();
+        registry.register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory(true, false));
+        httpClient.setAuthSchemes(registry);
         // Get the credentials from the JAAS configuration rather than here
         Credentials useJaasCreds = new Credentials() {
           public String getPassword() {

Modified: lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java Wed Sep  2 13:06:13 2015
@@ -17,13 +17,6 @@ package org.apache.solr.common.cloud;
  * limitations under the License.
  */
 
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.common.util.Utils;
-import org.noggit.JSONWriter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -33,6 +26,14 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
+import org.apache.solr.common.util.Utils;
+import org.apache.zookeeper.Watcher;
+import org.noggit.JSONWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * Immutable state of the cloud. Normally you can get the state by using
  * {@link ZkStateReader#getClusterState()}.
@@ -110,8 +111,16 @@ public class ClusterState implements JSO
     return null;
   }
 
-  public boolean hasCollection(String coll) {
-    return  collectionStates.containsKey(coll) ;
+  /**
+   * Returns true if the specified collection name exists, false otherwise.
+   *
+   * Implementation note: This method resolves the collection reference by calling
+   * {@link CollectionRef#get()} which can make a call to ZooKeeper. This is necessary
+   * because the semantics of how collection list is loaded have changed in SOLR-6629.
+   * Please javadocs in {@link ZkStateReader#refreshCollectionList(Watcher)}
+   */
+  public boolean hasCollection(String collectionName) {
+    return getCollectionOrNull(collectionName) != null;
   }
 
   /**
@@ -170,19 +179,38 @@ public class ClusterState implements JSO
     return  collectionStates.get(coll);
   }
 
-  public DocCollection getCollectionOrNull(String coll) {
-    CollectionRef ref = collectionStates.get(coll);
-    return ref == null? null:ref.get();
+  /**
+   * Returns the corresponding {@link DocCollection} object for the given collection name
+   * if such a collection exists. Returns null otherwise.
+   *
+   * Implementation note: This method resolves the collection reference by calling
+   * {@link CollectionRef#get()} which can make a call to ZooKeeper. This is necessary
+   * because the semantics of how collection list is loaded have changed in SOLR-6629.
+   * Please javadocs in {@link ZkStateReader#refreshCollectionList(Watcher)}
+   */
+  public DocCollection getCollectionOrNull(String collectionName) {
+    CollectionRef ref = collectionStates.get(collectionName);
+    return ref == null ? null : ref.get();
   }
 
   /**
    * Get collection names.
+   *
+   * Implementation note: This method resolves the collection reference by calling
+   * {@link CollectionRef#get()} which can make a call to ZooKeeper. This is necessary
+   * because the semantics of how collection list is loaded have changed in SOLR-6629.
+   * Please javadocs in {@link ZkStateReader#refreshCollectionList(Watcher)}
    */
   public Set<String> getCollections() {
-    return collectionStates.keySet();
+    Set<String> result = new HashSet<>();
+    for (Entry<String, CollectionRef> entry : collectionStates.entrySet()) {
+      if (entry.getValue().get() != null) {
+        result.add(entry.getKey());
+      }
+    }
+    return result;
   }
 
-
   /**
    * Get names of the currently live nodes.
    */

Modified: lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/cloud/ZkConfigManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/cloud/ZkConfigManager.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/cloud/ZkConfigManager.java (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/cloud/ZkConfigManager.java Wed Sep  2 13:06:13 2015
@@ -29,6 +29,7 @@ import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Class that manages named configs in Zookeeper
@@ -142,4 +143,81 @@ public class ZkConfigManager {
       throw new IOException("Error listing configs", SolrZkClient.checkInterrupted(e));
     }
   }
+
+  /**
+   * Check whether a config exists in Zookeeper
+   *
+   * @param configName the config to check existance on
+   * @return whether the config exists or not
+   * @throws IOException if an I/O error occurs
+   */
+  public Boolean configExists(String configName) throws IOException {
+    try {
+      return zkClient.exists(ZkConfigManager.CONFIGS_ZKNODE + "/" + configName, true);
+    } catch (KeeperException | InterruptedException e) {
+      throw new IOException("Error checking whether config exists",
+          SolrZkClient.checkInterrupted(e));
+    }
+  }
+
+  /**
+   * Delete a config in ZooKeeper
+   *
+   * @param configName the config to delete
+   * @throws IOException if an I/O error occurs
+   */
+  public void deleteConfigDir(String configName) throws IOException {
+    try {
+      zkClient.clean(ZkConfigManager.CONFIGS_ZKNODE + "/" + configName);
+    } catch (KeeperException | InterruptedException e) {
+      throw new IOException("Error checking whether config exists",
+          SolrZkClient.checkInterrupted(e));
+    }
+  }
+
+  private void copyConfigDirFromZk(String fromZkPath, String toZkPath, Set<String> copiedToZkPaths) throws IOException {
+    try {
+      List<String> files = zkClient.getChildren(fromZkPath, null, true);
+      for (String file : files) {
+        List<String> children = zkClient.getChildren(fromZkPath + "/" + file, null, true);
+        if (children.size() == 0) {
+          final String toZkFilePath = toZkPath + "/" + file;
+          logger.info("Copying zk node {} to {}",
+              fromZkPath + "/" + file, toZkFilePath);
+          byte[] data = zkClient.getData(fromZkPath + "/" + file, null, null, true);
+          zkClient.makePath(toZkFilePath, data, true);
+          if (copiedToZkPaths != null) copiedToZkPaths.add(toZkFilePath);
+        } else {
+          copyConfigDirFromZk(fromZkPath + "/" + file, toZkPath + "/" + file, copiedToZkPaths);
+        }
+      }
+    } catch (KeeperException | InterruptedException e) {
+      throw new IOException("Error copying nodes from zookeeper path " + fromZkPath + " to " + toZkPath,
+          SolrZkClient.checkInterrupted(e));
+    }
+  }
+
+  /**
+   * Copy a config in ZooKeeper
+   *
+   * @param fromConfig the config to copy from
+   * @param toConfig the config to copy to
+   * @throws IOException if an I/O error occurs
+   */
+  public void copyConfigDir(String fromConfig, String toConfig) throws IOException {
+    copyConfigDir(CONFIGS_ZKNODE + "/" + fromConfig, CONFIGS_ZKNODE + "/" + toConfig, null);
+  }
+
+  /**
+   * Copy a config in ZooKeeper
+   *
+   * @param fromConfig the config to copy from
+   * @param toConfig the config to copy to
+   * @param copiedToZkPaths should be an empty Set, will be filled in by function
+                            with the paths that were actually copied to.
+   * @throws IOException if an I/O error occurs
+   */
+  public void copyConfigDir(String fromConfig, String toConfig, Set<String> copiedToZkPaths) throws IOException {
+    copyConfigDirFromZk(CONFIGS_ZKNODE + "/" + fromConfig, CONFIGS_ZKNODE + "/" + toConfig, copiedToZkPaths);
+  }
 }



Mime
View raw message