// Path: aemsolrsearch-search-service/src/main/java/com/headwire/aemsolrsearch/search/services/AbstractSolrSearchService.java
// public abstract class AbstractSolrSearchService extends AbstractSolrService {
//     
//     private static final Logger LOG = LoggerFactory.getLogger(AbstractSolrSearchService.class);
// 
//     /**
//      * Query a particular instance of SolrServer identified by the core name
//      * with a given query.
//      */
//     public QueryResponse query(String solrCore, SolrQuery solrQuery) throws SolrServerException {
//         SolrClient server = getSolrQueryClient();
//         LOG.info("Quering {} with '{}'", getSolrServerURI(solrCore), solrQuery);
//         QueryResponse solrResponse;
//         try {
//             solrResponse = server.query(solrCore, solrQuery);
//             return solrResponse;
//         } catch (IOException e) {
//             e.printStackTrace();
//         }
//         return new QueryResponse();
//     }
// 
// }
// 
// Path: aemsolrsearch-search-service/src/main/java/com/headwire/aemsolrsearch/search/services/DefaultSolrSearchService.java
// @Component(
//         name = "com.headwire.aemsolrsearch.search.services.DefaultSolrSearchService",
//         label = "AEM Solr Search - Solr Search Service",
//         description = "A service for performing searches against Solr",
//         immediate = true,
//         metatype = true)
// @Service(DefaultSolrSearchService.class)
// @Properties({
//         @Property(
//                 name = Constants.SERVICE_VENDOR,
//                 value = "headwire.com, Inc."),
//         @Property(
//                 name = Constants.SERVICE_DESCRIPTION,
//                 value = "A default implementation of the Solr.search.service")
// })
// /**
//  * DefaultSolrSearchService is responsible for obtaining the uri for a particular solr instance identified by a core.
//  */
// public class DefaultSolrSearchService extends AbstractSolrSearchService {
// 
//     private static final Logger LOG = LoggerFactory.getLogger(DefaultSolrSearchService.class);
// 
//     @Reference
//     SolrConfigurationService solrConfigService;
// 
//     @Activate
//     protected void activate(final Map<String, String> config) {
//         resetService(config);
//     }
// 
//     @Modified
//     protected void modified(final Map<String, String> config) {
//         resetService(config);
//     }
// 
//     @Override
//     protected String getSolrServerURI() {
//         assertSolrConfigService();
//         return solrConfigService.getSolrEndPoint();
//     }
// 
//     @Override
//     protected String getSolrServerURI(String solrCore) {
//         assertSolrConfigService();
//         return formatSolrEndPointAndCore(solrConfigService.getSolrEndPoint(), solrCore);
//     }
// 
//     @Override
//     protected SolrClient getSolrIndexClient() {
//         return solrConfigService.getIndexingSolrClient();
//     }
// 
//     @Override
//     protected SolrClient getSolrQueryClient() {
//         return solrConfigService.getQueryingSolrClient();
//     }
// 
//     private void resetService(final Map<String, String> config) {
//         LOG.info("Resetting Solr search service using configuration: " + config);
//     }
//     
//     private void assertSolrConfigService() throws IllegalStateException {        
//         if (null == solrConfigService) {
//             LOG.error("Can't get SolrConfigurationService. Check that all OSGi bundles are active");
//             throw new IllegalStateException("No solr configuration service.");
//         }
//     }
// }


import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.jsp.JspException;
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.response.QueryResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.cqblueprints.taglib.CqSimpleTagSupport;
import com.headwire.aemsolrsearch.search.services.AbstractSolrSearchService;
import com.headwire.aemsolrsearch.search.services.DefaultSolrSearchService;
import com.squeakysand.jsp.tagext.annotations.JspTag;
import com.squeakysand.jsp.tagext.annotations.JspTagAttribute;
package com.headwire.aemsolrsearch.taglib;





/**
 * Tag used to build SolrQuery, call the SolrSearchService, and store results. 
 */
@JspTag
public class SolrSearchTag extends CqSimpleTagSupport {

	private static final Logger LOG = LoggerFactory
			.getLogger(SolrSearchTag.class);

	private SolrQuery solrQuery;

	/** Name to retrieve this object in JSP/Servlet in page scope. */
	private String var;

	/** Name to retrieve the SolrSearchResult object in JSP/Servlet in page scope. */
	private String varResults;
		
	// Set by user
	private String query;
	private int start = 0;
	private String[] filterQueries;
	
	// Set by author
	private String solrCoreName;
	private int rows = 0;
	private String[] fieldNames;
	private String[] advancedFilterQueries;
	private boolean facetEnabled;
	private String facetSort;
	private int facetLimit;
	private int facetMinCount;
	private String[] facetFieldNames;	
	private boolean highlightEnabled;
	private boolean highlightRequireFieldMatchEnabled;
	private String highlightSimplePre;
	private String highlightSimplePost;
	private int highlightNumberSnippets;
	private int highlightFragsize;
	private String[] highlightingFields;
    private String searchHandler;
	private String sort;
	private String sortDir;

	@Override
	public void doTag() throws JspException, IOException {

		// Make this tag object available to the JSP/Servlet scope.
		if (StringUtils.isNotBlank(getVar())) {				
			getPageContext().setAttribute(getVar(), this);
//			getRequest().setAttribute(getVar(), this);
		}

		// Get Solr Service
		AbstractSolrSearchService searchService = null;
		try {
// Path: aemsolrsearch-search-service/src/main/java/com/headwire/aemsolrsearch/search/services/AbstractSolrSearchService.java
// public abstract class AbstractSolrSearchService extends AbstractSolrService {
//     
//     private static final Logger LOG = LoggerFactory.getLogger(AbstractSolrSearchService.class);
// 
//     /**
//      * Query a particular instance of SolrServer identified by the core name
//      * with a given query.
//      */
//     public QueryResponse query(String solrCore, SolrQuery solrQuery) throws SolrServerException {
//         SolrClient server = getSolrQueryClient();
//         LOG.info("Quering {} with '{}'", getSolrServerURI(solrCore), solrQuery);
//         QueryResponse solrResponse;
//         try {
//             solrResponse = server.query(solrCore, solrQuery);
//             return solrResponse;
//         } catch (IOException e) {
//             e.printStackTrace();
//         }
//         return new QueryResponse();
//     }
// 
// }
// 
// Path: aemsolrsearch-search-service/src/main/java/com/headwire/aemsolrsearch/search/services/DefaultSolrSearchService.java
// @Component(
//         name = "com.headwire.aemsolrsearch.search.services.DefaultSolrSearchService",
//         label = "AEM Solr Search - Solr Search Service",
//         description = "A service for performing searches against Solr",
//         immediate = true,
//         metatype = true)
// @Service(DefaultSolrSearchService.class)
// @Properties({
//         @Property(
//                 name = Constants.SERVICE_VENDOR,
//                 value = "headwire.com, Inc."),
//         @Property(
//                 name = Constants.SERVICE_DESCRIPTION,
//                 value = "A default implementation of the Solr.search.service")
// })
// /**
//  * DefaultSolrSearchService is responsible for obtaining the uri for a particular solr instance identified by a core.
//  */
// public class DefaultSolrSearchService extends AbstractSolrSearchService {
// 
//     private static final Logger LOG = LoggerFactory.getLogger(DefaultSolrSearchService.class);
// 
//     @Reference
//     SolrConfigurationService solrConfigService;
// 
//     @Activate
//     protected void activate(final Map<String, String> config) {
//         resetService(config);
//     }
// 
//     @Modified
//     protected void modified(final Map<String, String> config) {
//         resetService(config);
//     }
// 
//     @Override
//     protected String getSolrServerURI() {
//         assertSolrConfigService();
//         return solrConfigService.getSolrEndPoint();
//     }
// 
//     @Override
//     protected String getSolrServerURI(String solrCore) {
//         assertSolrConfigService();
//         return formatSolrEndPointAndCore(solrConfigService.getSolrEndPoint(), solrCore);
//     }
// 
//     @Override
//     protected SolrClient getSolrIndexClient() {
//         return solrConfigService.getIndexingSolrClient();
//     }
// 
//     @Override
//     protected SolrClient getSolrQueryClient() {
//         return solrConfigService.getQueryingSolrClient();
//     }
// 
//     private void resetService(final Map<String, String> config) {
//         LOG.info("Resetting Solr search service using configuration: " + config);
//     }
//     
//     private void assertSolrConfigService() throws IllegalStateException {        
//         if (null == solrConfigService) {
//             LOG.error("Can't get SolrConfigurationService. Check that all OSGi bundles are active");
//             throw new IllegalStateException("No solr configuration service.");
//         }
//     }
// }


// Path: aemsolrsearch-taglib/src/main/java/com/headwire/aemsolrsearch/taglib/SolrSearchTag.java
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.jsp.JspException;
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.response.QueryResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.cqblueprints.taglib.CqSimpleTagSupport;
import com.headwire.aemsolrsearch.search.services.AbstractSolrSearchService;
import com.headwire.aemsolrsearch.search.services.DefaultSolrSearchService;
import com.squeakysand.jsp.tagext.annotations.JspTag;
import com.squeakysand.jsp.tagext.annotations.JspTagAttribute;

package com.headwire.aemsolrsearch.taglib;





/**
 * Tag used to build SolrQuery, call the SolrSearchService, and store results. 
 */
@JspTag
public class SolrSearchTag extends CqSimpleTagSupport {

	private static final Logger LOG = LoggerFactory
			.getLogger(SolrSearchTag.class);

	private SolrQuery solrQuery;

	/** Name to retrieve this object in JSP/Servlet in page scope. */
	private String var;

	/** Name to retrieve the SolrSearchResult object in JSP/Servlet in page scope. */
	private String varResults;
		
	// Set by user
	private String query;
	private int start = 0;
	private String[] filterQueries;
	
	// Set by author
	private String solrCoreName;
	private int rows = 0;
	private String[] fieldNames;
	private String[] advancedFilterQueries;
	private boolean facetEnabled;
	private String facetSort;
	private int facetLimit;
	private int facetMinCount;
	private String[] facetFieldNames;	
	private boolean highlightEnabled;
	private boolean highlightRequireFieldMatchEnabled;
	private String highlightSimplePre;
	private String highlightSimplePost;
	private int highlightNumberSnippets;
	private int highlightFragsize;
	private String[] highlightingFields;
    private String searchHandler;
	private String sort;
	private String sortDir;

	@Override
	public void doTag() throws JspException, IOException {

		// Make this tag object available to the JSP/Servlet scope.
		if (StringUtils.isNotBlank(getVar())) {				
			getPageContext().setAttribute(getVar(), this);
//			getRequest().setAttribute(getVar(), this);
		}

		// Get Solr Service
		AbstractSolrSearchService searchService = null;
		try {
			searchService = (AbstractSolrSearchService) getService(DefaultSolrSearchService.class);