You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by sh...@apache.org on 2015/08/30 15:27:14 UTC

svn commit: r1700119 [8/26] - in /ofbiz/trunk: ./ runtime/indexes/ specialpurpose/ specialpurpose/solr/ specialpurpose/solr/conf/ specialpurpose/solr/config/ specialpurpose/solr/entitydef/ specialpurpose/solr/lib/ specialpurpose/solr/lib/compile/ speci...

Added: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/example_atom.xsl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/example_atom.xsl?rev=1700119&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/example_atom.xsl (added)
+++ ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/example_atom.xsl Sun Aug 30 13:27:07 2015
@@ -0,0 +1,67 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<!-- 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<!-- 
+  Simple transform of Solr query results to Atom
+ -->
+
+<xsl:stylesheet version='1.0'
+    xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
+
+  <xsl:output
+       method="xml"
+       encoding="utf-8"
+       media-type="application/xml"
+  />
+
+  <xsl:template match='/'>
+    <xsl:variable name="query" select="response/lst[@name='responseHeader']/lst[@name='params']/str[@name='q']"/>
+    <feed xmlns="http://www.w3.org/2005/Atom">
+      <title>Example Solr Atom 1.0 Feed</title>
+      <subtitle>
+       This has been formatted by the sample "example_atom.xsl" transform -
+       use your own XSLT to get a nicer Atom feed.
+      </subtitle>
+      <author>
+        <name>Apache Solr</name>
+        <email>solr-user@lucene.apache.org</email>
+      </author>
+      <link rel="self" type="application/atom+xml" 
+            href="http://localhost:8983/solr/q={$query}&amp;wt=xslt&amp;tr=atom.xsl"/>
+      <updated>
+        <xsl:value-of select="response/result/doc[position()=1]/date[@name='timestamp']"/>
+      </updated>
+      <id>tag:localhost,2007:example</id>
+      <xsl:apply-templates select="response/result/doc"/>
+    </feed>
+  </xsl:template>
+    
+  <!-- search results xslt -->
+  <xsl:template match="doc">
+    <xsl:variable name="id" select="str[@name='id']"/>
+    <entry>
+      <title><xsl:value-of select="str[@name='name']"/></title>
+      <link href="http://localhost:8983/solr/select?q={$id}"/>
+      <id>tag:localhost,2007:<xsl:value-of select="$id"/></id>
+      <summary><xsl:value-of select="arr[@name='features']"/></summary>
+      <updated><xsl:value-of select="date[@name='timestamp']"/></updated>
+    </entry>
+  </xsl:template>
+
+</xsl:stylesheet>

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/example_atom.xsl
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/example_atom.xsl
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/example_atom.xsl
------------------------------------------------------------------------------
    svn:mime-type = text/xsl

Added: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/example_rss.xsl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/example_rss.xsl?rev=1700119&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/example_rss.xsl (added)
+++ ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/example_rss.xsl Sun Aug 30 13:27:07 2015
@@ -0,0 +1,66 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<!-- 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<!-- 
+  Simple transform of Solr query results to RSS
+ -->
+
+<xsl:stylesheet version='1.0'
+    xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
+
+  <xsl:output
+       method="xml"
+       encoding="utf-8"
+       media-type="application/xml"
+  />
+  <xsl:template match='/'>
+    <rss version="2.0">
+       <channel>
+	 <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 -
+          use your own XSLT to get a nicer RSS feed.
+         </description>
+         <language>en-us</language>
+         <docs>http://localhost:8983/solr</docs>
+         <xsl:apply-templates select="response/result/doc"/>
+       </channel>
+    </rss>
+  </xsl:template>
+  
+  <!-- search results xslt -->
+  <xsl:template match="doc">
+    <xsl:variable name="id" select="str[@name='id']"/>
+    <xsl:variable name="timestamp" select="date[@name='timestamp']"/>
+    <item>
+      <title><xsl:value-of select="str[@name='name']"/></title>
+      <link>
+        http://localhost:8983/solr/select?q=id:<xsl:value-of select="$id"/>
+      </link>
+      <description>
+        <xsl:value-of select="arr[@name='features']"/>
+      </description>
+      <pubDate><xsl:value-of select="$timestamp"/></pubDate>
+      <guid>
+        http://localhost:8983/solr/select?q=id:<xsl:value-of select="$id"/>
+      </guid>
+    </item>
+  </xsl:template>
+</xsl:stylesheet>

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/example_rss.xsl
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/example_rss.xsl
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/example_rss.xsl
------------------------------------------------------------------------------
    svn:mime-type = text/xsl

Added: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/luke.xsl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/luke.xsl?rev=1700119&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/luke.xsl (added)
+++ ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/luke.xsl Sun Aug 30 13:27:07 2015
@@ -0,0 +1,337 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+
+<!-- 
+  Display the luke request handler with graphs
+ -->
+<xsl:stylesheet
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns="http://www.w3.org/1999/xhtml"
+    version="1.0"
+    >
+    <xsl:output
+        method="html"
+        encoding="UTF-8"
+        media-type="text/html"
+        doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
+        doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
+    />
+
+    <xsl:variable name="title">Solr Luke Request Handler Response</xsl:variable>
+
+    <xsl:template match="/">
+        <html xmlns="http://www.w3.org/1999/xhtml">
+            <head>
+                <link rel="stylesheet" type="text/css" href="solr-admin.css"/>
+                <link rel="icon" href="favicon.ico" type="image/ico"/>
+                <link rel="shortcut icon" href="favicon.ico" type="image/ico"/>
+                <title>
+                    <xsl:value-of select="$title"/>
+                </title>
+                <xsl:call-template name="css"/>
+
+            </head>
+            <body>
+                <h1>
+                    <xsl:value-of select="$title"/>
+                </h1>
+                <div class="doc">
+                    <ul>
+                        <xsl:if test="response/lst[@name='index']">
+                            <li>
+                                <a href="#index">Index Statistics</a>
+                            </li>
+                        </xsl:if>
+                        <xsl:if test="response/lst[@name='fields']">
+                            <li>
+                                <a href="#fields">Field Statistics</a>
+                                <ul>
+                                    <xsl:for-each select="response/lst[@name='fields']/lst">
+                                        <li>
+                                            <a href="#{@name}">
+                                                <xsl:value-of select="@name"/>
+                                            </a>
+                                        </li>
+                                    </xsl:for-each>
+                                </ul>
+                            </li>
+                        </xsl:if>
+                        <xsl:if test="response/lst[@name='doc']">
+                            <li>
+                                <a href="#doc">Document statistics</a>
+                            </li>
+                        </xsl:if>
+                    </ul>
+                </div>
+                <xsl:if test="response/lst[@name='index']">
+                    <h2><a name="index"/>Index Statistics</h2>
+                    <xsl:apply-templates select="response/lst[@name='index']"/>
+                </xsl:if>
+                <xsl:if test="response/lst[@name='fields']">
+                    <h2><a name="fields"/>Field Statistics</h2>
+                    <xsl:apply-templates select="response/lst[@name='fields']"/>
+                </xsl:if>
+                <xsl:if test="response/lst[@name='doc']">
+                    <h2><a name="doc"/>Document statistics</h2>
+                    <xsl:apply-templates select="response/lst[@name='doc']"/>
+                </xsl:if>
+            </body>
+        </html>
+    </xsl:template>
+
+    <xsl:template match="lst">
+        <xsl:if test="parent::lst">
+            <tr>
+                <td colspan="2">
+                    <div class="doc">
+                        <xsl:call-template name="list"/>
+                    </div>
+                </td>
+            </tr>
+        </xsl:if>
+        <xsl:if test="not(parent::lst)">
+            <div class="doc">
+                <xsl:call-template name="list"/>
+            </div>
+        </xsl:if>
+    </xsl:template>
+
+    <xsl:template name="list">
+        <xsl:if test="count(child::*)>0">
+            <table>
+                <thead>
+                    <tr>
+                        <th colspan="2">
+                            <p>
+                                <a name="{@name}"/>
+                            </p>
+                            <xsl:value-of select="@name"/>
+                        </th>
+                    </tr>
+                </thead>
+                <tbody>
+                    <xsl:choose>
+                        <xsl:when
+                            test="@name='histogram'">
+                            <tr>
+                                <td colspan="2">
+                                    <xsl:call-template name="histogram"/>
+                                </td>
+                            </tr>
+                        </xsl:when>
+                        <xsl:otherwise>
+                            <xsl:apply-templates/>
+                        </xsl:otherwise>
+                    </xsl:choose>
+                </tbody>
+            </table>
+        </xsl:if>
+    </xsl:template>
+
+    <xsl:template name="histogram">
+        <div class="doc">
+            <xsl:call-template name="barchart">
+                <xsl:with-param name="max_bar_width">50</xsl:with-param>
+                <xsl:with-param name="iwidth">800</xsl:with-param>
+                <xsl:with-param name="iheight">160</xsl:with-param>
+                <xsl:with-param name="fill">blue</xsl:with-param>
+            </xsl:call-template>
+        </div>
+    </xsl:template>
+
+    <xsl:template name="barchart">
+        <xsl:param name="max_bar_width"/>
+        <xsl:param name="iwidth"/>
+        <xsl:param name="iheight"/>
+        <xsl:param name="fill"/>
+        <xsl:variable name="max">
+            <xsl:for-each select="int">
+                <xsl:sort data-type="number" order="descending"/>
+                <xsl:if test="position()=1">
+                    <xsl:value-of select="."/>
+                </xsl:if>
+            </xsl:for-each>
+        </xsl:variable>
+        <xsl:variable name="bars">
+           <xsl:value-of select="count(int)"/>
+        </xsl:variable>
+        <xsl:variable name="bar_width">
+           <xsl:choose>
+             <xsl:when test="$max_bar_width &lt; ($iwidth div $bars)">
+               <xsl:value-of select="$max_bar_width"/>
+             </xsl:when>
+             <xsl:otherwise>
+               <xsl:value-of select="$iwidth div $bars"/>
+             </xsl:otherwise>
+           </xsl:choose>
+        </xsl:variable>
+        <table class="histogram">
+           <tbody>
+              <tr>
+                <xsl:for-each select="int">
+                   <td>
+                 <xsl:value-of select="."/>
+                 <div class="histogram">
+                  <xsl:attribute name="style">background-color: <xsl:value-of select="$fill"/>; width: <xsl:value-of select="$bar_width"/>px; height: <xsl:value-of select="($iheight*number(.)) div $max"/>px;</xsl:attribute>
+                 </div>
+                   </td> 
+                </xsl:for-each>
+              </tr>
+              <tr>
+                <xsl:for-each select="int">
+                   <td>
+                       <xsl:value-of select="@name"/>
+                   </td>
+                </xsl:for-each>
+              </tr>
+           </tbody>
+        </table>
+    </xsl:template>
+
+    <xsl:template name="keyvalue">
+        <xsl:choose>
+            <xsl:when test="@name">
+                <tr>
+                    <td class="name">
+                        <xsl:value-of select="@name"/>
+                    </td>
+                    <td class="value">
+                        <xsl:value-of select="."/>
+                    </td>
+                </tr>
+            </xsl:when>
+            <xsl:otherwise>
+                <xsl:value-of select="."/>
+            </xsl:otherwise>
+        </xsl:choose>
+    </xsl:template>
+
+    <xsl:template match="int|bool|long|float|double|uuid|date">
+        <xsl:call-template name="keyvalue"/>
+    </xsl:template>
+
+    <xsl:template match="arr">
+        <tr>
+            <td class="name">
+                <xsl:value-of select="@name"/>
+            </td>
+            <td class="value">
+                <ul>
+                    <xsl:for-each select="child::*">
+                        <li>
+                            <xsl:apply-templates/>
+                        </li>
+                    </xsl:for-each>
+                </ul>
+            </td>
+        </tr>
+    </xsl:template>
+
+    <xsl:template match="str">
+        <xsl:choose>
+            <xsl:when test="@name='schema' or @name='index' or @name='flags'">
+                <xsl:call-template name="schema"/>
+            </xsl:when>
+            <xsl:otherwise>
+                <xsl:call-template name="keyvalue"/>
+            </xsl:otherwise>
+        </xsl:choose>
+    </xsl:template>
+
+    <xsl:template name="schema">
+        <tr>
+            <td class="name">
+                <xsl:value-of select="@name"/>
+            </td>
+            <td class="value">
+                <xsl:if test="contains(.,'unstored')">
+                    <xsl:value-of select="."/>
+                </xsl:if>
+                <xsl:if test="not(contains(.,'unstored'))">
+                    <xsl:call-template name="infochar2string">
+                        <xsl:with-param name="charList">
+                            <xsl:value-of select="."/>
+                        </xsl:with-param>
+                    </xsl:call-template>
+                </xsl:if>
+            </td>
+        </tr>
+    </xsl:template>
+
+    <xsl:template name="infochar2string">
+        <xsl:param name="i">1</xsl:param>
+        <xsl:param name="charList"/>
+
+        <xsl:variable name="char">
+            <xsl:value-of select="substring($charList,$i,1)"/>
+        </xsl:variable>
+        <xsl:choose>
+            <xsl:when test="$char='I'">
+                <xsl:value-of select="/response/lst[@name='info']/lst/str[@name='I']"/> - </xsl:when>
+            <xsl:when test="$char='T'">
+                <xsl:value-of select="/response/lst[@name='info']/lst/str[@name='T']"/> - </xsl:when>
+            <xsl:when test="$char='S'">
+                <xsl:value-of select="/response/lst[@name='info']/lst/str[@name='S']"/> - </xsl:when>
+            <xsl:when test="$char='M'">
+                <xsl:value-of select="/response/lst[@name='info']/lst/str[@name='M']"/> - </xsl:when>
+            <xsl:when test="$char='V'">
+                <xsl:value-of select="/response/lst[@name='info']/lst/str[@name='V']"/> - </xsl:when>
+            <xsl:when test="$char='o'">
+                <xsl:value-of select="/response/lst[@name='info']/lst/str[@name='o']"/> - </xsl:when>
+            <xsl:when test="$char='p'">
+                <xsl:value-of select="/response/lst[@name='info']/lst/str[@name='p']"/> - </xsl:when>
+            <xsl:when test="$char='O'">
+                <xsl:value-of select="/response/lst[@name='info']/lst/str[@name='O']"/> - </xsl:when>
+            <xsl:when test="$char='L'">
+                <xsl:value-of select="/response/lst[@name='info']/lst/str[@name='L']"/> - </xsl:when>
+            <xsl:when test="$char='B'">
+                <xsl:value-of select="/response/lst[@name='info']/lst/str[@name='B']"/> - </xsl:when>
+            <xsl:when test="$char='C'">
+                <xsl:value-of select="/response/lst[@name='info']/lst/str[@name='C']"/> - </xsl:when>
+            <xsl:when test="$char='f'">
+                <xsl:value-of select="/response/lst[@name='info']/lst/str[@name='f']"/> - </xsl:when>
+            <xsl:when test="$char='l'">
+                <xsl:value-of select="/response/lst[@name='info']/lst/str[@name='l']"/> -
+            </xsl:when>
+        </xsl:choose>
+
+        <xsl:if test="not($i>=string-length($charList))">
+            <xsl:call-template name="infochar2string">
+                <xsl:with-param name="i">
+                    <xsl:value-of select="$i+1"/>
+                </xsl:with-param>
+                <xsl:with-param name="charList">
+                    <xsl:value-of select="$charList"/>
+                </xsl:with-param>
+            </xsl:call-template>
+        </xsl:if>
+    </xsl:template>
+    <xsl:template name="css">
+        <style type="text/css">
+            <![CDATA[
+            td.name {font-style: italic; font-size:80%; }
+            .doc { margin: 0.5em; border: solid grey 1px; }
+            .exp { display: none; font-family: monospace; white-space: pre; }
+            div.histogram { background: none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;}
+            table.histogram { width: auto; vertical-align: bottom; }
+            table.histogram td, table.histogram th { text-align: center; vertical-align: bottom; border-bottom: 1px solid #ff9933; width: auto; }
+            ]]>
+        </style>
+    </xsl:template>
+</xsl:stylesheet>

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/luke.xsl
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/luke.xsl
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/luke.xsl
------------------------------------------------------------------------------
    svn:mime-type = text/xsl

Added: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/updateXml.xsl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/updateXml.xsl?rev=1700119&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/updateXml.xsl (added)
+++ ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/updateXml.xsl Sun Aug 30 13:27:07 2015
@@ -0,0 +1,70 @@
+<!-- 
+ * 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.
+ -->
+
+<!--
+  Simple transform of Solr query response into Solr Update XML compliant XML.
+  When used in the xslt response writer you will get UpdaateXML as output.
+  But you can also store a query response XML to disk and feed this XML to
+  the XSLTUpdateRequestHandler to index the content. Provided as example only.
+  See http://wiki.apache.org/solr/XsltUpdateRequestHandler for more info
+ -->
+<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
+  <xsl:output media-type="text/xml" method="xml" indent="yes"/>
+
+  <xsl:template match='/'>
+    <add>
+        <xsl:apply-templates select="response/result/doc"/>
+    </add>
+  </xsl:template>
+  
+  <!-- Ignore score (makes no sense to index) -->
+  <xsl:template match="doc/*[@name='score']" priority="100">
+  </xsl:template>
+
+  <xsl:template match="doc">
+    <xsl:variable name="pos" select="position()"/>
+    <doc>
+        <xsl:apply-templates>
+          <xsl:with-param name="pos"><xsl:value-of select="$pos"/></xsl:with-param>
+        </xsl:apply-templates>
+    </doc>
+  </xsl:template>
+
+  <!-- Flatten arrays to duplicate field lines -->
+  <xsl:template match="doc/arr" priority="100">
+      <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:for-each>
+  </xsl:template>
+
+
+  <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:value-of select="."/>
+	</xsl:element>
+  </xsl:template>
+
+  <xsl:template match="*"/>
+</xsl:stylesheet>

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/updateXml.xsl
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/updateXml.xsl
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/conf/xslt/updateXml.xsl
------------------------------------------------------------------------------
    svn:mime-type = text/xsl

Added: ofbiz/trunk/specialpurpose/solr/solrdefault/core.properties
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/solrdefault/core.properties?rev=1700119&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/solrdefault/core.properties (added)
+++ ofbiz/trunk/specialpurpose/solr/solrdefault/core.properties Sun Aug 30 13:27:07 2015
@@ -0,0 +1,2 @@
+# To config this file, please read:
+# https://cwiki.apache.org/confluence/display/solr/Defining+core.properties

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/core.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/core.properties
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: ofbiz/trunk/specialpurpose/solr/solrdefault/core.properties
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/CategoryUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/CategoryUtil.java?rev=1700119&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/CategoryUtil.java (added)
+++ ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/CategoryUtil.java Sun Aug 30 13:27:07 2015
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * 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.ofbiz.solr;
+
+import java.util.Iterator;
+import java.util.List;
+
+import javolution.util.FastList;
+
+import org.apache.commons.lang.StringUtils;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericDelegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.condition.EntityCondition;
+import org.ofbiz.entity.util.EntityUtil;
+import org.ofbiz.service.DispatchContext;
+
+/**
+ * Product category util class for solr.
+ */
+public abstract class CategoryUtil {
+    
+    public static final String module = CategoryUtil.class.getName();
+
+    /**
+     * Gets catalog IDs for specified product category.
+     * <p>
+     * This method is a supplement to CatalogWorker methods. 
+     */
+    public static List<String> getCatalogIdsByCategoryId(Delegator delegator, String productCategoryId) {
+        List<String> catalogIds = FastList.newInstance();
+        List<GenericValue> catalogs = null;
+        try {
+            EntityCondition condition = EntityCondition.makeCondition(UtilMisc.toMap("productCategoryId", productCategoryId));
+            // catalogs = delegator.findList("ProdCatalog", null, null, UtilMisc.toList("catalogName"), null, false);
+            catalogs = delegator.findList("ProdCatalogCategory", condition, null, null, null, false);
+        } catch (GenericEntityException e) {
+            Debug.logError(e, "Error looking up all catalogs", module);
+        }
+        if (catalogs != null) {
+            for (GenericValue c : catalogs) {
+                catalogIds.add(c.getString("prodCatalogId"));
+            }
+        }
+        return catalogIds;
+    }    
+    
+    public static List<List<String>> getCategoryTrail(String productCategoryId, DispatchContext dctx) {
+       GenericDelegator delegator = (GenericDelegator) dctx.getDelegator();
+        List<List<String>> trailElements = FastList.newInstance();
+        String parentProductCategoryId = productCategoryId;
+        while (UtilValidate.isNotEmpty(parentProductCategoryId)) {
+            // find product category rollup
+            try {
+                List<EntityCondition> rolllupConds = FastList.newInstance();
+                rolllupConds.add(EntityCondition.makeCondition("productCategoryId", parentProductCategoryId));
+                rolllupConds.add(EntityUtil.getFilterByDateExpr());
+                List<GenericValue> productCategoryRollups = delegator.findList("ProductCategoryRollup", EntityCondition.makeCondition(rolllupConds), null, UtilMisc.toList("-fromDate"), null, true);
+                if (UtilValidate.isNotEmpty(productCategoryRollups)) {
+                    List<List<String>> trailElementsAux = FastList.newInstance();
+                    trailElementsAux.addAll(trailElements);
+                    // add only categories that belong to the top category to trail
+                    for (GenericValue productCategoryRollup : productCategoryRollups) {
+                        String trailCategoryId = productCategoryRollup.getString("parentProductCategoryId");
+                        parentProductCategoryId = trailCategoryId;
+                        List<String> trailElement = FastList.newInstance();
+                        if (!trailElements.isEmpty()) {
+                            for (List<String> trailList : trailElementsAux) {
+                                trailElement.add(trailCategoryId);
+                                trailElement.addAll(trailList);
+                                trailElements.remove(trailList);
+                                trailElements.add(trailElement);
+                            }
+                        } else {
+                            trailElement.add(trailCategoryId);
+                            trailElement.add(productCategoryId);
+                            trailElements.add(trailElement);
+                        }
+                    }
+                } else {
+                    parentProductCategoryId = null;
+                }
+
+            } catch (GenericEntityException e) {
+                Debug.logError(e, "Cannot generate trail from product category", module);
+            }
+        }
+        if (trailElements.size() == 0) {
+            List<String> trailElement = FastList.newInstance();
+            trailElement.add(productCategoryId);
+            trailElements.add(trailElement);
+        }
+        return trailElements;
+    }
+    
+    /**
+     * Returns categoryName with trail
+     */
+    public static String getCategoryNameWithTrail(String productCategoryId, DispatchContext dctx) {
+        return getCategoryNameWithTrail(productCategoryId, true,  dctx);
+    }
+
+    public static String getCategoryNameWithTrail(String productCategoryId, Boolean showDepth, DispatchContext dctx) {
+        List<List<String>> trailElements = CategoryUtil.getCategoryTrail(productCategoryId, dctx);
+        //Debug.log("trailElements ======> " + trailElements.toString());
+        StringBuilder catMember = new StringBuilder();
+        String cm ="";
+        int i = 0;
+        for (List<String> trailElement : trailElements) {
+            for (Iterator<String> trailIter = trailElement.iterator(); trailIter.hasNext();) {
+                String trailString = (String) trailIter.next();
+                if (catMember.length() > 0){
+                    catMember.append("/");
+                    i++;
+                }
+                
+                catMember.append(trailString);
+            }
+        }
+        
+        if (catMember.length() == 0){catMember.append(productCategoryId);}
+        
+        if(showDepth) {
+            cm = i +"/"+ catMember.toString();
+        } else {
+            cm = catMember.toString();
+        }
+        //Debug.logInfo("catMember "+cm,module);
+        return cm;
+    }
+    
+    /**    
+     * Returns nextLevel from trailed category.
+     * <p>
+     * Ie for "1/SYRACUS2_CATEGORY/FICTION_C/" the returned value would be 2.
+     */
+    public static int getNextLevelFromCategoryId(String productCategoryId, DispatchContext dctx) {
+        try{
+            if (productCategoryId.contains("/")) {
+                String[] productCategories = productCategoryId.split("/");
+                int level = Integer.parseInt(productCategories[0]);
+                return level++;
+            } else {
+                return 0;
+            }
+        } catch(Exception e) {
+            return 0;
+        }
+    }
+    
+    /**    
+     * Returns proper FacetFilter from trailed category.
+     * <p>
+     * Ie for "1/SYRACUS2_CATEGORY/FICTION_C/" the returned value would be
+     * "2/SYRACUS2_CATEGORY/FICTION_C/".
+     */
+    public static String getFacetFilterForCategory(String productCategoryId, DispatchContext dctx) {
+        try{
+            String[] productCategories = productCategoryId.split("/");
+            int level = Integer.parseInt(productCategories[0]);
+            int nextLevel = level+1;
+            productCategories[0] = ""+nextLevel;
+            return StringUtils.join(productCategories,"/");
+        } catch(Exception e) {
+            return productCategoryId;
+        }
+    }
+    
+}
\ No newline at end of file

Propchange: ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/CategoryUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/CategoryUtil.java
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/CategoryUtil.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/ProductUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/ProductUtil.java?rev=1700119&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/ProductUtil.java (added)
+++ ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/ProductUtil.java Sun Aug 30 13:27:07 2015
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * 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.ofbiz.solr;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javolution.util.FastList;
+import javolution.util.FastMap;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.entity.GenericDelegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.condition.EntityCondition;
+import org.ofbiz.product.config.ProductConfigWrapper;
+import org.ofbiz.product.product.ProductContentWrapper;
+import org.ofbiz.product.product.ProductWorker;
+import org.ofbiz.service.DispatchContext;
+import org.ofbiz.service.LocalDispatcher;
+
+/**
+ * Product utility class for solr.
+ */
+public abstract class ProductUtil {
+    public static final String module = ProductUtil.class.getName();
+
+    public static Map<String, Object> getProductContent(GenericValue product, DispatchContext dctx, Map<String, Object> context) {
+        GenericDelegator delegator = (GenericDelegator) dctx.getDelegator();
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+        String productId = (String) product.get("productId");
+        Map<String, Object> dispatchContext = new HashMap<String, Object>();
+        Locale locale = new Locale("de_DE");
+
+        if (Debug.verboseOn()) {
+            Debug.logVerbose("Solr: Getting product content for productId '" + productId + "'", module);
+        }
+        
+        try {
+            // Generate special ProductContentWrapper for the supported languages (de/en/fr)
+            ProductContentWrapper productContentEn = new ProductContentWrapper(dispatcher, product, new Locale("en"), null);
+            ProductContentWrapper productContentDe = new ProductContentWrapper(dispatcher, product, new Locale("de"), null);
+            ProductContentWrapper productContentFr = new ProductContentWrapper(dispatcher, product, new Locale("fr"), null);
+            if (productId != null) {
+                dispatchContext.put("productId", productId);
+                // if (product.get("sku") != null) dispatchContext.put("sku", product.get("sku"));
+                if (product.get("internalName") != null)
+                    dispatchContext.put("internalName", product.get("internalName"));
+                // GenericValue manu = product.getRelatedOneCache("Manufacturer");
+                // if (product.get("manu") != null) dispatchContext.put("manu", "");
+                String smallImage = (String) product.get("smallImageUrl");
+                if (smallImage != null)
+                    dispatchContext.put("smallImage", smallImage);
+                String mediumImage = (String) product.get("mediumImageUrl");
+                if (mediumImage != null)
+                    dispatchContext.put("mediumImage", mediumImage);
+                String largeImage = (String) product.get("largeImageUrl");
+                if (largeImage != null)
+                    dispatchContext.put("largeImage", largeImage);                
+                
+                // if(product.get("weight") != null) dispatchContext.put("weight", "");
+
+                // Trying to set a correctand trail
+                List<GenericValue> category = delegator.findList("ProductCategoryMember", EntityCondition.makeCondition(UtilMisc.toMap("productId", productId)), null, null, null, false);
+                List<String> trails = new ArrayList<String>();
+                for (Iterator<GenericValue> catIterator = category.iterator(); catIterator.hasNext();) {
+                    GenericValue cat = (GenericValue) catIterator.next();
+                    String productCategoryId = (String) cat.get("productCategoryId");
+                    List<List<String>> trailElements = CategoryUtil.getCategoryTrail(productCategoryId, dctx);
+                    //Debug.log("trailElements ======> " + trailElements.toString());
+                    for (List<String> trailElement : trailElements) {
+                        StringBuilder catMember = new StringBuilder();
+                        int i = 0;
+                        Iterator<String> trailIter = trailElement.iterator();
+                       
+                        while (trailIter.hasNext()) {
+                            String trailString = (String) trailIter.next();
+                            if (catMember.length() > 0){
+                                catMember.append("/");
+                                i++;
+                            }
+                            catMember.append(trailString);
+                            String cm = i +"/"+ catMember.toString();
+                            if (!trails.contains(cm)) {
+                                //Debug.logInfo("cm : "+cm, module);
+                                trails.add(cm);
+                                // Debug.log("trail for product " + productId + " ====> " + catMember.toString());
+                            }
+                        }
+                        
+                    }
+                }
+                dispatchContext.put("category", trails);
+
+                // Get the catalogs that have associated the categories
+                List<String> catalogs = FastList.newInstance();
+                for (String trail : trails) {
+                    String productCategoryId = (trail.split("/").length > 0) ? trail.split("/")[1] : trail;
+                    List<String> catalogMembers = CategoryUtil.getCatalogIdsByCategoryId(delegator, productCategoryId);
+                    for (String catalogMember : catalogMembers)
+                        if (!catalogs.contains(catalogMember))
+                            catalogs.add(catalogMember);
+                }
+                dispatchContext.put("catalog", catalogs);
+
+                // Alternative
+                // if(category.size()>0) dispatchContext.put("category", category);
+                // if(product.get("popularity") != null) dispatchContext.put("popularity", "");
+
+                Map<String, Object> featureSet = dispatcher.runSync("getProductFeatureSet", UtilMisc.toMap("productId", productId));
+                if (featureSet != null) {
+                    dispatchContext.put("features", (Set<?>) featureSet.get("featureSet"));
+                }
+
+                Map<String, Object> productInventoryAvailable = dispatcher.runSync("getProductInventoryAvailable", UtilMisc.toMap("productId", productId));
+                String inStock = null;
+                BigDecimal availableToPromiseTotal = (BigDecimal) productInventoryAvailable.get("availableToPromiseTotal");
+                if (availableToPromiseTotal != null) {
+                    inStock = availableToPromiseTotal.toBigInteger().toString();
+                }
+                dispatchContext.put("inStock", inStock);
+
+                Boolean isVirtual = ProductWorker.isVirtual(delegator, productId);
+                if (isVirtual)
+                    dispatchContext.put("isVirtual", isVirtual);
+                Boolean isDigital = ProductWorker.isDigital(product);
+                if (isDigital)
+                    dispatchContext.put("isDigital", isDigital);
+                Boolean isPhysical = ProductWorker.isPhysical(product);
+                if (isPhysical)
+                    dispatchContext.put("isPhysical", isPhysical);
+
+                FastMap<String, String> title = new FastMap<String, String>();
+                String detitle = productContentDe.get("PRODUCT_NAME").toString();
+                if (detitle != null)
+                    title.put("de", detitle);
+                else if (product.get("productName") != null)
+                    title.put("de", (String) product.get("productName"));
+                String entitle = productContentEn.get("PRODUCT_NAME").toString();
+                if (entitle != null)
+                    title.put("en", entitle);
+                else if (product.get("productName") != null)
+                    title.put("en", (String) product.get("productName"));
+                String frtitle = productContentFr.get("PRODUCT_NAME").toString();
+                if (frtitle != null)
+                    title.put("fr", frtitle);
+                else if (product.get("productName") != null)
+                    title.put("fr", (String) product.get("productName"));
+                dispatchContext.put("title", title);
+
+                Map<String, String> description = new FastMap<String, String>();
+                String dedescription = productContentDe.get("DESCRIPTION").toString();
+                if (dedescription != null)
+                    description.put("de", dedescription);
+                String endescription = productContentEn.get("DESCRIPTION").toString();
+                if (endescription != null)
+                    description.put("en", endescription);
+                String frdescription = productContentFr.get("DESCRIPTION").toString();
+                if (frdescription != null)
+                    description.put("fr", frdescription);
+                dispatchContext.put("description", description);
+
+                FastMap<String, String> longDescription = new FastMap<String, String>();
+                String delongDescription = productContentDe.get("LONG_DESCRIPTION").toString();
+                if (delongDescription != null)
+                    longDescription.put("de", delongDescription);
+                String enlongDescription = productContentEn.get("LONG_DESCRIPTION").toString();
+                if (enlongDescription != null)
+                    longDescription.put("en", enlongDescription);
+                String frlongDescription = productContentFr.get("LONG_DESCRIPTION").toString();
+                if (frlongDescription != null)
+                    longDescription.put("fr", frlongDescription);
+                dispatchContext.put("longDescription", longDescription);
+
+                // dispatchContext.put("comments", "");
+                // dispatchContext.put("keywords", "");
+                // dispatchContext.put("last_modified", "");
+
+                if (product != null && "AGGREGATED".equals(product.getString("productTypeId"))) {
+                    ProductConfigWrapper configWrapper = new ProductConfigWrapper(delegator, dispatcher, productId, null, null, null, null, locale, userLogin);
+                    String listPrice = configWrapper.getTotalListPrice().setScale(2, BigDecimal.ROUND_HALF_DOWN).toString();
+                    if (listPrice != null)
+                        dispatchContext.put("listPrice", listPrice);
+                    String defaultPrice = configWrapper.getTotalListPrice().setScale(2, BigDecimal.ROUND_HALF_DOWN).toString();
+                    if (defaultPrice != null)
+                        dispatchContext.put("defaultPrice", defaultPrice);
+                } else {
+                    Map<String, GenericValue> priceContext = UtilMisc.toMap("product", product);
+                    Map<String, Object> priceMap = dispatcher.runSync("calculateProductPrice", priceContext);
+                    if (priceMap.get("listPrice") != null) {
+                        String listPrice = ((BigDecimal) priceMap.get("listPrice")).setScale(2, BigDecimal.ROUND_HALF_DOWN).toString();
+                        dispatchContext.put("listPrice", listPrice);
+                    }
+                    if (priceMap.get("defaultPrice") != null) {
+                        String defaultPrice = ((BigDecimal) priceMap.get("defaultPrice")).setScale(2, BigDecimal.ROUND_HALF_DOWN).toString();
+                        if (defaultPrice != null)
+                            dispatchContext.put("defaultPrice", defaultPrice);
+                    }
+                }
+            }
+        } catch (GenericEntityException e) {
+            Debug.logError(e, e.getMessage(), module);
+        } catch (Exception e) {
+            Debug.logError(e, e.getMessage(), module);
+        }
+        return dispatchContext;
+    }
+}
\ No newline at end of file

Propchange: ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/ProductUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/ProductUtil.java
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/ProductUtil.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/SolrProductSearch.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/SolrProductSearch.java?rev=1700119&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/SolrProductSearch.java (added)
+++ ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/SolrProductSearch.java Sun Aug 30 13:27:07 2015
@@ -0,0 +1,675 @@
+/*******************************************************************************
+ * 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.ofbiz.solr;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javolution.util.FastList;
+import javolution.util.FastMap;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.impl.HttpSolrServer;
+import org.apache.solr.client.solrj.response.FacetField;
+import org.apache.solr.client.solrj.response.FacetField.Count;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.client.solrj.response.SpellCheckResponse.Suggestion;
+import org.apache.solr.common.SolrInputDocument;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericDelegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.service.DispatchContext;
+import org.ofbiz.service.GenericServiceException;
+import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.service.ServiceAuthException;
+import org.ofbiz.service.ServiceUtil;
+import org.ofbiz.service.ServiceValidationException;
+
+/**
+ * Base class for OFBiz Test Tools test case implementations.
+ */
+public abstract class SolrProductSearch {
+
+    public static final String module = SolrProductSearch.class.getName();
+    
+
+    /**
+     * Adds product to solr, with product denoted by productId field in instance attribute
+     * - intended for use with ECAs/SECAs.
+     */
+    public static Map<String, Object> addToSolr(DispatchContext dctx, Map<String, Object> context) throws GenericEntityException {
+        Map<String, Object> result;
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        Delegator delegator = dctx.getDelegator();
+        GenericValue productInstance = (GenericValue) context.get("instance");
+        String productId = (String) productInstance.get("productId");
+        
+        if (SolrUtil.isSolrEcaEnabled()) {
+            // Debug.logVerbose("Solr: addToSolr: Running indexing for productId '" + productId + "'", module);
+            try {
+                GenericValue product = delegator.findOne("Product", UtilMisc.toMap("productId", productId), false);
+                Map<String, Object> dispatchContext = ProductUtil.getProductContent(product, dctx, context);
+                dispatchContext.put("treatConnectErrorNonFatal", SolrUtil.isEcaTreatConnectErrorNonFatal());
+                Map<String, Object> runResult = dispatcher.runSync("addToSolrIndex", dispatchContext);
+                String runMsg = ServiceUtil.getErrorMessage(runResult);
+                if (UtilValidate.isEmpty(runMsg)) {
+                    runMsg = null;
+                }
+                if (ServiceUtil.isError(runResult)) {
+                    result = ServiceUtil.returnError(runMsg);
+                }
+                else if (ServiceUtil.isFailure(runResult)) {
+                    result = ServiceUtil.returnFailure(runMsg);
+                }
+                else {
+                    result = ServiceUtil.returnSuccess();
+                }
+            } catch (Exception e) {
+                Debug.logError(e, e.getMessage(), module);
+                result = ServiceUtil.returnError(e.toString());
+            }
+        }
+        else {
+            final String statusMsg = "Solr ECA indexing disabled; skipping indexing for productId '" + productId + "'";
+            Debug.logVerbose("Solr: addToSolr: " + statusMsg, module);
+            result = ServiceUtil.returnSuccess();
+        }
+        return result;
+    }
+
+    /**
+     * Adds product to solr index.
+     */
+    public static Map<String, Object> addToSolrIndex(DispatchContext dctx, Map<String, Object> context) throws GenericEntityException {
+        HttpSolrServer server = null;
+        Map<String, Object> result;
+        String productId = (String) context.get("productId");
+        // connectErrorNonFatal is a necessary option because in some cases it may be considered normal that solr server is unavailable;
+        // don't want to return error and abort transactions in these cases.
+        Boolean treatConnectErrorNonFatal = (Boolean) context.get("treatConnectErrorNonFatal");
+        try {
+            Debug.logInfo("Solr: Generating and indexing document for productId '" + productId + "'", module);
+            
+            server = new HttpSolrServer(SolrUtil.solrUrl);
+            //Debug.log(server.ping().toString());
+
+            // Construct Documents
+            SolrInputDocument doc1 = SolrUtil.generateSolrDocument(context);
+            Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
+            
+            if (Debug.verboseOn()) {
+                Debug.logVerbose("Solr: Indexing document: " + doc1.toString(), module);
+            }
+            
+            docs.add(doc1);
+
+            // push Documents to server
+            server.add(docs);
+            server.commit();
+            
+            final String statusStr = "Document for productId " + productId + " added to solr index";
+            Debug.logInfo("Solr: " + statusStr, module);
+            result = ServiceUtil.returnSuccess(statusStr);
+        } catch (MalformedURLException e) {
+            Debug.logError(e, e.getMessage(), module);
+            result = ServiceUtil.returnError(e.toString());
+            result.put("errorType", "urlError");
+        } catch (SolrServerException e) {
+            if (e.getCause() != null && e.getCause() instanceof ConnectException) {
+                final String statusStr = "Failure connecting to solr server to commit productId " + 
+                        context.get("productId") + "; product not updated";
+                if (Boolean.TRUE.equals(treatConnectErrorNonFatal)) {
+                    Debug.logWarning(e, "Solr: " + statusStr, module);
+                    result = ServiceUtil.returnFailure(statusStr);
+                }
+                else {
+                    Debug.logError(e, "Solr: " + statusStr, module);
+                    result = ServiceUtil.returnError(statusStr);
+                }
+                result.put("errorType", "connectError");
+            }
+            else {
+                Debug.logError(e, e.getMessage(), module);
+                result = ServiceUtil.returnError(e.toString());
+                result.put("errorType", "solrServerError");
+            }
+        } catch (IOException e) {
+            Debug.logError(e, e.getMessage(), module);
+            result = ServiceUtil.returnError(e.toString());
+            result.put("errorType", "ioError");
+        }
+        return result;
+    }
+
+    /**
+     * Adds a List of products to the solr index.
+     * <p>
+     * This is faster than reflushing the index each time.
+     */
+    public static Map<String, Object> addListToSolrIndex(DispatchContext dctx, Map<String, Object> context) throws GenericEntityException {
+        HttpSolrServer server = null;
+        Map<String, Object> result;
+        Boolean treatConnectErrorNonFatal = (Boolean) context.get("treatConnectErrorNonFatal");
+        try {
+            Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
+
+            // Construct Documents
+            List<Map<String, Object>> fieldList = UtilGenerics.<Map<String, Object>>checkList(context.get("fieldList"));
+            
+            Debug.logInfo("Solr: Generating and adding " + fieldList.size() + " documents to solr index", module);
+            
+            for (Iterator<Map<String, Object>> fieldListIterator = fieldList.iterator(); fieldListIterator.hasNext();) {
+                SolrInputDocument doc1 = SolrUtil.generateSolrDocument(fieldListIterator.next());
+                if (Debug.verboseOn()) {
+                    Debug.logVerbose("Solr: Indexing document: " + doc1.toString(), module);
+                }
+                docs.add(doc1);
+            }
+            // push Documents to server
+            server = new HttpSolrServer(SolrUtil.solrUrl);
+            server.add(docs);
+            server.commit();
+            
+            final String statusStr = "Added " + fieldList.size() + " documents to solr index";
+            Debug.logInfo("Solr: " + statusStr, module);
+            result = ServiceUtil.returnSuccess(statusStr);
+        } catch (MalformedURLException e) {
+            Debug.logError(e, e.getMessage(), module);
+            result = ServiceUtil.returnError(e.toString());
+            result.put("errorType", "urlError");
+        } catch (SolrServerException e) {
+            if (e.getCause() != null && e.getCause() instanceof ConnectException) {
+                final String statusStr = "Failure connecting to solr server to commit product list; products not updated";
+                if (Boolean.TRUE.equals(treatConnectErrorNonFatal)) {
+                    Debug.logWarning(e, "Solr: " + statusStr, module);
+                    result = ServiceUtil.returnFailure(statusStr);
+                }
+                else {
+                    Debug.logError(e, "Solr: " + statusStr, module);
+                    result = ServiceUtil.returnError(statusStr);
+                }
+                result.put("errorType", "connectError");
+            }
+            else {
+                Debug.logError(e, e.getMessage(), module);
+                result = ServiceUtil.returnError(e.toString());
+                result.put("errorType", "solrServerError");
+            }
+        } catch (IOException e) {
+            Debug.logError(e, e.getMessage(), module);
+            result = ServiceUtil.returnError(e.toString());
+            result.put("errorType", "ioError");
+        }
+        return result;
+    }
+
+    /**
+     * Runs a query on the Solr Search Engine and returns the results.
+     * <p>
+     * This function only returns an object of type QueryResponse, so it is probably not a good idea to call it directly from within the
+     * groovy files (As a decent example on how to use it, however, use keywordSearch instead).
+     */
+    public static Map<String, Object> runSolrQuery(DispatchContext dctx, Map<String, Object> context) {
+        // get Connection
+        HttpSolrServer server = null;
+        Map<String, Object> result;
+        try {
+            server = new HttpSolrServer(SolrUtil.solrUrl);
+            // create Query Object
+            SolrQuery solrQuery = new SolrQuery();
+            solrQuery.setQuery((String) context.get("query"));
+            // solrQuery.setQueryType("dismax");
+            boolean faceted = (Boolean) context.get("facet");
+            if (faceted) {
+                solrQuery.setFacet(faceted);
+                solrQuery.addFacetField("manu");
+                solrQuery.addFacetField("cat");
+                solrQuery.setFacetMinCount(1);
+                solrQuery.setFacetLimit(8);
+
+                solrQuery.addFacetQuery("listPrice:[0 TO 50]");
+                solrQuery.addFacetQuery("listPrice:[50 TO 100]");
+                solrQuery.addFacetQuery("listPrice:[100 TO 250]");
+                solrQuery.addFacetQuery("listPrice:[250 TO 500]");
+                solrQuery.addFacetQuery("listPrice:[500 TO 1000]");
+                solrQuery.addFacetQuery("listPrice:[1000 TO 2500]");
+                solrQuery.addFacetQuery("listPrice:[2500 TO 5000]");
+                solrQuery.addFacetQuery("listPrice:[5000 TO 10000]");
+                solrQuery.addFacetQuery("listPrice:[10000 TO 50000]");
+                solrQuery.addFacetQuery("listPrice:[50000 TO *]");
+            }
+            
+            boolean spellCheck = (Boolean) context.get("spellcheck");
+            if(spellCheck){
+                solrQuery.setParam("spellcheck", spellCheck);
+            }
+            
+            boolean highLight = (Boolean) context.get("highlight");
+            if (highLight) {
+                solrQuery.setHighlight(highLight);
+                solrQuery.setHighlightSimplePre("<span class=\"highlight\">");
+                solrQuery.addHighlightField("description");
+                solrQuery.setHighlightSimplePost("</span>");
+                solrQuery.setHighlightSnippets(2);
+            }
+
+            // Set additional Parameter
+            // SolrQuery.ORDER order = SolrQuery.ORDER.desc;
+
+            if (context.get("viewIndex") != null && (Integer) context.get("viewIndex") > 0) {
+                solrQuery.setStart((Integer) context.get("viewIndex"));
+            }
+            if (context.get("viewSize") != null && (Integer) context.get("viewSize") > 0) {
+                solrQuery.setRows((Integer) context.get("viewSize"));
+            }
+
+            // if ((List) context.get("queryFilter") != null && ((ArrayList<SolrDocument>) context.get("queryFilter")).size() > 0) {
+            // List filter = (List) context.get("queryFilter");
+            // String[] tn = new String[filter.size()];
+            // Iterator it = filter.iterator();
+            // for (int i = 0; i < filter.size(); i++) {
+            // tn[i] = (String) filter.get(i);
+            // }
+            // solrQuery.setFilterQueries(tn);
+            // }
+            String queryFilter = (String) context.get("queryFilter");
+            if(UtilValidate.isNotEmpty(queryFilter))
+            solrQuery.setFilterQueries(queryFilter.split(" "));
+            if ((String) context.get("returnFields") != null) {
+                solrQuery.setFields((String) context.get("returnFields"));
+            }
+
+            // if((Boolean)context.get("sortByReverse"))order.reverse();
+            if ((String) context.get("sortBy") != null && ((String) context.get("sortBy")).length() > 0) {
+                SolrQuery.ORDER order;
+                if (!((Boolean) context.get("sortByReverse")))
+                    order = SolrQuery.ORDER.asc;
+                else
+                    order = SolrQuery.ORDER.desc;
+                solrQuery.setSort(((String) context.get("sortBy")).replaceFirst("-", ""), order);
+            }
+
+            if ((String) context.get("facetQuery") != null) {
+                solrQuery.addFacetQuery((String) context.get("facetQuery"));
+            }
+
+            QueryResponse rsp = server.query(solrQuery);
+            result = ServiceUtil.returnSuccess();
+            result.put("queryResult", rsp);
+        } catch (Exception e) {
+            Debug.logError(e, e.getMessage(), module);
+            result = ServiceUtil.returnError(e.toString());
+        }
+        return result;
+    }
+
+    /**
+     * Performs solr products search.
+     */
+    public static Map<String, Object> productsSearch(DispatchContext dctx, Map<String, Object> context) {
+        Map<String, Object> result;
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+
+        try {
+            Map<String, Object> dispatchMap = FastMap.newInstance();
+            if (UtilValidate.isNotEmpty(context.get("productCategoryId"))){
+                String productCategoryId = (String) context.get("productCategoryId");
+                dispatchMap.put("query", "cat:*" + productCategoryId+"*");
+            }
+            else
+                return ServiceUtil.returnError("Missing product category id");
+            if (context.get("viewSize") != null)
+                dispatchMap.put("viewSize", Integer.parseInt(((String) context.get("viewSize"))));
+            if (context.get("viewIndex") != null)
+                dispatchMap.put("viewIndex", Integer.parseInt((String) context.get("viewIndex")));
+            if (context.get("queryFilter") != null)
+                dispatchMap.put("queryFilter", context.get("queryFilter"));
+            dispatchMap.put("facet", false);
+            dispatchMap.put("spellcheck", true);
+            dispatchMap.put("highlight", true);
+            Map<String, Object> searchResult = dispatcher.runSync("runSolrQuery", dispatchMap);
+            QueryResponse queryResult = (QueryResponse) searchResult.get("queryResult");
+            result = ServiceUtil.returnSuccess();
+            result.put("results", queryResult.getResults());
+            result.put("listSize", queryResult.getResults().getNumFound());
+            result.put("viewIndex", queryResult.getResults().getStart());
+            result.put("viewSize", queryResult.getResults().size());
+        } catch (Exception e) {
+            Debug.logError(e, e.getMessage(), module);
+            result = ServiceUtil.returnError(e.toString());
+        }
+        return result;
+    }
+
+    /**
+     * Performs keyword search.
+     * <p>
+     * The search form requires the result to be in a specific layout, so this will generate the proper results.
+     */
+    public static Map<String, Object> keywordSearch(DispatchContext dctx, Map<String, Object> context) {
+        Map<String, Object> result;
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+
+        try {
+            if (context.get("query") == null || context.get("query").equals(""))
+                context.put("query", "*:*");
+
+            Map<String, Object> dispatchMap = FastMap.newInstance();
+            if (context.get("viewSize") != null)
+                dispatchMap.put("viewSize", Integer.parseInt(((String) context.get("viewSize"))));
+            if (context.get("viewIndex") != null)
+                dispatchMap.put("viewIndex", Integer.parseInt((String) context.get("viewIndex")));
+            if (context.get("query") != null)
+                dispatchMap.put("query", context.get("query"));
+            if (context.get("queryFilter") != null)
+                dispatchMap.put("queryFilter", context.get("queryFilter"));
+            dispatchMap.put("spellcheck", true);
+            Map<String, Object> searchResult = dispatcher.runSync("runSolrQuery", dispatchMap);
+            QueryResponse queryResult = (QueryResponse) searchResult.get("queryResult");
+
+            List<List<String>> suggestions = FastList.newInstance();
+            if (queryResult.getSpellCheckResponse() != null && queryResult.getSpellCheckResponse().getSuggestions() != null) {
+                Iterator<Suggestion> iter = queryResult.getSpellCheckResponse().getSuggestions().iterator();
+                while (iter.hasNext()) {
+                    Suggestion resultDoc = iter.next();
+                    Debug.logInfo("Suggestion " + resultDoc.getAlternatives(), module);
+                    suggestions.add(resultDoc.getAlternatives());
+                }
+            }
+
+            Boolean isCorrectlySpelled = true;
+            if (queryResult.getSpellCheckResponse() != null) {
+                isCorrectlySpelled = queryResult.getSpellCheckResponse().isCorrectlySpelled();
+            }
+
+            result = ServiceUtil.returnSuccess();
+            result.put("isCorrectlySpelled", isCorrectlySpelled);
+
+            Map<String, Integer> facetQuery = queryResult.getFacetQuery();
+            Map<String, String> facetQueries = FastMap.newInstance();
+            for (String fq : facetQuery.keySet()) {
+                if (facetQuery.get(fq).intValue() > 0)
+                    facetQueries.put(fq, fq.replaceAll("^.*\\u005B(.*)\\u005D", "$1") + " (" + facetQuery.get(fq).intValue() + ")");
+            }
+
+            Map<String, Map<String, Long>> facetFields = FastMap.newInstance();
+            List<FacetField> facets = queryResult.getFacetFields();
+            for (FacetField facet : facets) {
+                Map<String, Long> facetEntry = FastMap.newInstance();
+                List<FacetField.Count> facetEntries = facet.getValues();
+                if (UtilValidate.isNotEmpty(facetEntries)) {
+                    for (FacetField.Count fcount : facetEntries)
+                        facetEntry.put(fcount.getName(), fcount.getCount());
+                    facetFields.put(facet.getName(), facetEntry);
+                }
+            }
+
+            result.put("results", queryResult.getResults());
+            result.put("facetFields", facetFields);
+            result.put("facetQueries", facetQueries);
+            result.put("queryTime", queryResult.getElapsedTime());
+            result.put("listSize", queryResult.getResults().getNumFound());
+            result.put("viewIndex", queryResult.getResults().getStart());
+            result.put("viewSize", queryResult.getResults().size());
+            result.put("suggestions", suggestions);
+
+        } catch (Exception e) {
+            Debug.logError(e, e.getMessage(), module);
+            result = ServiceUtil.returnError(e.toString());
+        }
+        return result;
+    }
+
+    /**
+     * Returns a map of the categories currently available under the root element.
+     */
+    public static Map<String, Object> getAvailableCategories(DispatchContext dctx, Map<String, Object> context) {
+        Map<String, Object> result;
+        try {
+            boolean displayProducts = false;
+            if (UtilValidate.isNotEmpty(context.get("displayProducts")))
+                displayProducts = (Boolean) context.get("displayProducts");
+
+            int viewIndex = 0;
+            int viewSize = 9;
+            if (displayProducts) {
+                viewIndex = (Integer) context.get("viewIndex");
+                viewSize = (Integer) context.get("viewSize");
+            }
+            String catalogId = null;
+            if (UtilValidate.isNotEmpty(context.get("catalogId")))
+                catalogId = (String) context.get("catalogId");
+            
+            //String productCategoryId = (String) context.get("productCategoryId") != null ? CategoryUtil.getCategoryNameWithTrail((String) context.get("productCategoryId"), dctx): null;
+            String productCategoryId = (String) context.get("productCategoryId") != null ? CategoryUtil.getCategoryNameWithTrail((String) context.get("productCategoryId"),dctx) : null;
+            Debug.logInfo("productCategoryId "+productCategoryId, module);
+            Map<String, Object> query = SolrUtil.categoriesAvailable(catalogId, productCategoryId, (String) context.get("productId"), displayProducts, viewIndex, viewSize);
+
+            QueryResponse cat = (QueryResponse) query.get("rows");
+            result = ServiceUtil.returnSuccess();
+            result.put("numFound", (long) 0);
+            Map<String, Object> categories = FastMap.newInstance();
+            List<FacetField> catList = (List<FacetField>) cat.getFacetFields();
+            for (Iterator<FacetField> catIterator = catList.iterator(); catIterator.hasNext();) {
+                FacetField field = (FacetField) catIterator.next();
+                List<Count> catL = (List<Count>) field.getValues();
+                if (catL != null) {
+                    // log.info("FacetFields = "+catL);
+                    for (Iterator<Count> catIter = catL.iterator(); catIter.hasNext();) {
+                        FacetField.Count f = (FacetField.Count) catIter.next();
+                        if (f.getCount() > 0) {
+                            categories.put(f.getName(), Long.toString(f.getCount()));
+                        }
+                    }
+                    result.put("categories", categories);
+                    result.put("numFound", cat.getResults().getNumFound());
+                    // log.info("The returned map is this:"+result);
+                }
+            }
+        } catch (Exception e) {
+            result = ServiceUtil.returnError(e.toString());
+            result.put("numFound", (long) 0);
+        }
+        return result;
+    }
+    
+    
+    /**
+     * Return a map of the side deep categories.
+     */
+    public static Map<String, Object> getSideDeepCategories(DispatchContext dctx, Map<String, Object> context) {
+        Map<String, Object> result;
+        try {
+            String catalogId = null;
+            if (UtilValidate.isNotEmpty(context.get("catalogId")))
+                catalogId = (String) context.get("catalogId");
+            
+            String productCategoryId = (String) context.get("productCategoryId") != null ? CategoryUtil.getCategoryNameWithTrail((String) context.get("productCategoryId"),dctx) : null;
+            result = ServiceUtil.returnSuccess();
+            Map<String, List<Map<String, Object>>> catLevel = FastMap.newInstance();
+            Debug.logInfo("productCategoryId: "+productCategoryId, module);
+            
+            //Add toplevel categories
+            String[] trailElements = productCategoryId.split("/");
+            
+            //iterate over actual results
+            for(String elements : trailElements){
+                //catIds must be greater than 3 chars
+                if(elements.length()>3){
+                Debug.logInfo("elements: "+elements,module);
+                String categoryPath = CategoryUtil.getCategoryNameWithTrail(elements,dctx);
+                String[] categoryPathArray = categoryPath.split("/");
+                int level = Integer.parseInt(categoryPathArray[0]);
+                String facetQuery = CategoryUtil.getFacetFilterForCategory(categoryPath, dctx);
+                //Debug.logInfo("categoryPath: "+categoryPath + " facetQuery: "+facetQuery,module);
+                Map<String, Object> query = SolrUtil.categoriesAvailable(catalogId, categoryPath, null, facetQuery,false, 0, 0);
+                QueryResponse cat = (QueryResponse) query.get("rows");
+                List<Map<String, Object>> categories = FastList.newInstance();
+                
+                
+                List<FacetField> catList = (List<FacetField>) cat.getFacetFields();
+                for (Iterator<FacetField> catIterator = catList.iterator(); catIterator.hasNext();) {
+                    FacetField field = (FacetField) catIterator.next();
+                    List<Count> catL = (List<Count>) field.getValues();
+                    if (catL != null) {
+                        for (Iterator<Count> catIter = catL.iterator(); catIter.hasNext();) {
+                            FacetField.Count f = (FacetField.Count) catIter.next();
+                            if (f.getCount() > 0) {
+                                Map<String, Object> catMap = FastMap.newInstance();
+                                FastList<String> iName = FastList.newInstance();
+                                iName.addAll(Arrays.asList(f.getName().split("/")));
+                                //Debug.logInfo("topLevel "+topLevel,"");
+                                // int l = Integer.parseInt((String) iName.getFirst());
+                                catMap.put("catId",iName.getLast());
+                                iName.removeFirst();
+                                String path = f.getName();
+                                catMap.put("path",path);
+                                if(level>0){
+                                    iName.removeLast();    
+                                    catMap.put("parentCategory",StringUtils.join(iName, "/"));
+                                }else{
+                                    catMap.put("parentCategory",null);
+                                }
+                                catMap.put("count", Long.toString(f.getCount()));
+                                categories.add(catMap);
+                            }
+                        }
+                    }
+                }
+                catLevel.put("menu-"+level, categories);
+                }
+            }
+            result.put("categories", catLevel);
+            result.put("numFound", (long) 0);
+            
+        } catch (Exception e) {
+            result = ServiceUtil.returnError(e.toString());
+            result.put("numFound", (long) 0);
+        }
+        return result;
+    }
+    
+    /**
+     * Rebuilds the solr index.
+     */
+    public static Map<String, Object> rebuildSolrIndex(DispatchContext dctx, Map<String, Object> context) throws GenericEntityException {
+        HttpSolrServer server = null;
+        Map<String, Object> result;
+        GenericDelegator delegator = (GenericDelegator) dctx.getDelegator();
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+        Locale locale = new Locale("de_DE");
+        
+        Boolean treatConnectErrorNonFatal = (Boolean) context.get("treatConnectErrorNonFatal");
+        
+        try {
+            server = new HttpSolrServer(SolrUtil.solrUrl);
+
+            // now lets fetch all products
+            List<Map<String, Object>> solrDocs = FastList.newInstance();
+            List<GenericValue> products = delegator.findList("Product", null, null, null, null, true);
+            int numDocs = 0;
+            if (products != null) {
+                numDocs = products.size();
+            }
+            
+            Debug.logInfo("Solr: Clearing solr index and rebuilding with " + numDocs + " found products", module);
+            
+            Iterator<GenericValue> productIterator = products.iterator();
+            while (productIterator.hasNext()) {
+                GenericValue product = productIterator.next();
+                Map<String, Object> dispatchContext = ProductUtil.getProductContent(product, dctx, context);
+                solrDocs.add(dispatchContext);
+            }
+
+            // this removes everything from the index
+            server.deleteByQuery("*:*");
+            server.commit();
+
+            // THis adds all products to the Index (instantly)
+            Map<String, Object> runResult = dispatcher.runSync("addListToSolrIndex", UtilMisc.toMap("fieldList", solrDocs, "userLogin", userLogin, 
+                    "locale", locale, "treatConnectErrorNonFatal", treatConnectErrorNonFatal));
+            
+            String runMsg = ServiceUtil.getErrorMessage(runResult);
+            if (UtilValidate.isEmpty(runMsg)) {
+                runMsg = null;
+            }
+            if (ServiceUtil.isError(runResult)) {
+                result = ServiceUtil.returnError(runMsg);
+            }
+            else if (ServiceUtil.isFailure(runResult)) {
+                result = ServiceUtil.returnFailure(runMsg);
+            }
+            else {
+                final String statusMsg = "Cleared solr index and reindexed " + numDocs + " documents";
+                result = ServiceUtil.returnSuccess(statusMsg);
+            }
+        } catch (MalformedURLException e) {
+            Debug.logError(e, e.getMessage(), module);
+            result = ServiceUtil.returnError(e.toString());
+        } catch (SolrServerException e) {
+            if (e.getCause() != null && e.getCause() instanceof ConnectException) {
+                final String statusStr = "Failure connecting to solr server to rebuild index; index not updated";
+                if (Boolean.TRUE.equals(treatConnectErrorNonFatal)) {
+                    Debug.logWarning(e, "Solr: " + statusStr, module);
+                    result = ServiceUtil.returnFailure(statusStr);
+                }
+                else {
+                    Debug.logError(e, "Solr: " + statusStr, module);
+                    result = ServiceUtil.returnError(statusStr);
+                }
+            }
+            else {
+                Debug.logError(e, e.getMessage(), module);
+                result = ServiceUtil.returnError(e.toString());
+            }
+        } catch (IOException e) {
+            Debug.logError(e, e.getMessage(), module);
+            result = ServiceUtil.returnError(e.toString());
+        } catch (ServiceAuthException e) {
+            Debug.logError(e, e.getMessage(), module);
+            result = ServiceUtil.returnError(e.toString());
+        } catch (ServiceValidationException e) {
+            Debug.logError(e, e.getMessage(), module);
+            result = ServiceUtil.returnError(e.toString());
+        } catch (GenericServiceException e) {
+            Debug.logError(e, e.getMessage(), module);
+            result = ServiceUtil.returnError(e.toString());
+        } catch (Exception e) {
+            Debug.logError(e, e.getMessage(), module);
+            result = ServiceUtil.returnError(e.toString());
+        }
+        return result;
+    }
+}

Propchange: ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/SolrProductSearch.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/SolrProductSearch.java
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: ofbiz/trunk/specialpurpose/solr/src/org/ofbiz/solr/SolrProductSearch.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain