All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jaeksoft.searchlib.join.JoinItem Maven / Gradle / Ivy

Go to download

OpenSearchServer is a powerful, enterprise-class, search engine program. Using the web user interface, the crawlers (web, file, database, ...) and the REST/RESTFul API you will be able to integrate quickly and easily advanced full-text search capabilities in your application. OpenSearchServer runs on Windows and Linux/Unix/BSD.

The newest version!
/**   
 * License Agreement for OpenSearchServer
 *
 * Copyright (C) 2012-2014 Emmanuel Keller / Jaeksoft
 * 
 * http://www.open-search-server.com
 * 
 * This file is part of OpenSearchServer.
 *
 * OpenSearchServer is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 * OpenSearchServer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with OpenSearchServer. 
 *  If not, see .
 **/

package com.jaeksoft.searchlib.join;

import java.io.IOException;
import java.util.List;

import javax.xml.xpath.XPathExpressionException;

import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import com.jaeksoft.searchlib.Client;
import com.jaeksoft.searchlib.ClientCatalog;
import com.jaeksoft.searchlib.SearchLibException;
import com.jaeksoft.searchlib.filter.FilterAbstract;
import com.jaeksoft.searchlib.filter.FilterList;
import com.jaeksoft.searchlib.function.expression.SyntaxError;
import com.jaeksoft.searchlib.index.FieldCacheIndex;
import com.jaeksoft.searchlib.index.ReaderAbstract;
import com.jaeksoft.searchlib.request.AbstractRequest;
import com.jaeksoft.searchlib.request.AbstractSearchRequest;
import com.jaeksoft.searchlib.request.SearchFieldRequest;
import com.jaeksoft.searchlib.result.ResultSearchSingle;
import com.jaeksoft.searchlib.result.collector.DocIdInterface;
import com.jaeksoft.searchlib.result.collector.join.JoinUtils;
import com.jaeksoft.searchlib.util.StringUtils;
import com.jaeksoft.searchlib.util.Timer;
import com.jaeksoft.searchlib.util.XPathParser;
import com.jaeksoft.searchlib.util.XmlWriter;
import com.jaeksoft.searchlib.web.ServletTransaction;

public class JoinItem implements Comparable {

	public interface OuterCollector {
		public void collect(final int id, final String value);
	}

	public static enum JoinType {
		INNER, OUTER;

		private final String label = name().toLowerCase();

		final public static JoinType find(String name) {
			for (JoinType type : values())
				if (type.name().equalsIgnoreCase(name))
					return type;
			return INNER;
		}

		public String getLabel() {
			return label;
		}
	}

	private String indexName;

	private String queryTemplate;

	private FilterList filterList;

	private String queryString;

	private String localField;

	private String foreignField;

	private int position;

	private String paramPosition;

	private boolean returnFields;

	private boolean returnScores;

	private boolean returnFacets;

	private JoinType type;

	private transient OuterCollector outerCollector;

	private transient Client foreignClient;

	private transient AbstractSearchRequest foreignSearchRequest;

	public JoinItem() {
		indexName = null;
		queryTemplate = null;
		queryString = null;
		localField = null;
		foreignField = null;
		position = 0;
		paramPosition = null;
		returnFields = false;
		returnScores = false;
		returnFacets = false;
		type = JoinType.INNER;
		filterList = new FilterList();
		outerCollector = null;
		foreignSearchRequest = null;
		foreignClient = null;
	}

	public JoinItem(JoinItem source) {
		source.copyTo(this);
	}

	public void copyTo(JoinItem target) {
		target.indexName = indexName;
		target.queryTemplate = queryTemplate;
		target.queryString = queryString;
		target.localField = localField;
		target.foreignField = foreignField;
		target.position = position;
		target.paramPosition = paramPosition;
		target.returnFields = returnFields;
		target.returnScores = returnScores;
		target.returnFacets = returnFacets;
		target.type = type;
		target.filterList = new FilterList(filterList);
	}

	public JoinItem(XPathParser xpp, Node node) throws XPathExpressionException {
		indexName = XPathParser.getAttributeString(node, ATTR_NAME_INDEXNAME);
		queryTemplate = XPathParser.getAttributeString(node,
				ATTR_NAME_QUERYTEMPLATE);
		queryString = xpp.getNodeString(node, false);
		localField = XPathParser.getAttributeString(node, ATTR_NAME_LOCALFIELD);
		foreignField = XPathParser.getAttributeString(node,
				ATTR_NAME_FOREIGNFIELD);
		returnFields = Boolean.parseBoolean(XPathParser.getAttributeString(
				node, ATTR_NAME_RETURNFIELDS));
		returnScores = Boolean.parseBoolean(XPathParser.getAttributeString(
				node, ATTR_NAME_RETURNSCORES));
		returnFacets = Boolean.parseBoolean(XPathParser.getAttributeString(
				node, ATTR_NAME_RETURNFACETS));
		type = JoinType.find(XPathParser.getAttributeString(node,
				ATTR_NAME_TYPE));
		filterList = new FilterList();
	}

	public final String NODE_NAME_JOIN = "join";
	public final String ATTR_NAME_INDEXNAME = "indexName";
	public final String ATTR_NAME_QUERYTEMPLATE = "queryTemplate";
	public final String ATTR_NAME_LOCALFIELD = "localField";
	public final String ATTR_NAME_FOREIGNFIELD = "foreignField";
	public final String ATTR_NAME_RETURNFIELDS = "returnFields";
	public final String ATTR_NAME_RETURNSCORES = "returnScores";
	public final String ATTR_NAME_RETURNFACETS = "returnFacets";
	public final String ATTR_NAME_TYPE = "type";

	public void writeXmlConfig(XmlWriter xmlWriter) throws SAXException {
		xmlWriter.startElement(NODE_NAME_JOIN, ATTR_NAME_INDEXNAME, indexName,
				ATTR_NAME_QUERYTEMPLATE, queryTemplate, ATTR_NAME_LOCALFIELD,
				localField, ATTR_NAME_FOREIGNFIELD, foreignField,
				ATTR_NAME_RETURNFIELDS, Boolean.toString(returnFields),
				ATTR_NAME_RETURNSCORES, Boolean.toString(returnScores),
				ATTR_NAME_RETURNFACETS, Boolean.toString(returnFacets),
				ATTR_NAME_TYPE, type.name());
		xmlWriter.textNode(queryString);
		xmlWriter.endElement();
	}

	/**
	 * @return the indexName
	 */
	public String getIndexName() {
		return indexName;
	}

	/**
	 * @param indexName
	 *            the indexName to set
	 */
	public void setIndexName(String indexName) {
		this.indexName = indexName;
	}

	/**
	 * @return the queryTemplate
	 */
	public String getQueryTemplate() {
		return queryTemplate;
	}

	/**
	 * @param queryTemplate
	 *            the queryTemplate to set
	 */
	public void setQueryTemplate(String queryTemplate) {
		this.queryTemplate = queryTemplate;
	}

	/**
	 * @return the queryString
	 */
	public String getQueryString() {
		return queryString;
	}

	/**
	 * @param queryString
	 *            the queryString to set
	 */
	public void setQueryString(String queryString) {
		this.queryString = queryString;
	}

	/**
	 * @return the localField
	 */
	public String getLocalField() {
		return localField;
	}

	/**
	 * @param localField
	 *            the localField to set
	 */
	public void setLocalField(String localField) {
		this.localField = localField;
	}

	/**
	 * @return the foreignField
	 */
	public String getForeignField() {
		return foreignField;
	}

	/**
	 * @param foreignField
	 *            the foreignField to set
	 */
	public void setForeignField(String foreignField) {
		this.foreignField = foreignField;
	}

	public void setOuterCollector(OuterCollector outerCollector) {
		this.outerCollector = outerCollector;
	}

	@Override
	public int compareTo(JoinItem o) {
		int c = 0;
		if ((c = indexName.compareTo(o.indexName)) != 0)
			return c;
		if ((c = queryTemplate.compareTo(o.queryTemplate)) != 0)
			return c;
		if ((c = queryString.compareTo(o.queryString)) != 0)
			return c;
		if ((c = localField.compareTo(o.localField)) != 0)
			return c;
		if ((c = foreignField.compareTo(o.foreignField)) != 0)
			return c;
		return 0;
	}

	public void setParamPosition(int position) {
		this.position = position;
		paramPosition = StringUtils
				.fastConcat("jq", Integer.toString(position));
	}

	public int getPosition() {
		return position;
	}

	public String getParamPosition() {
		return paramPosition;
	}

	/**
	 * @return the returnFields
	 */
	public boolean isReturnFields() {
		return returnFields;
	}

	/**
	 * @param returnFields
	 *            the returnFields to set
	 */
	public void setReturnFields(boolean returnFields) {
		this.returnFields = returnFields;
	}

	/**
	 * @return the returnScores
	 */
	public boolean isReturnScores() {
		return returnScores;
	}

	/**
	 * @param returnScores
	 *            the returnScores to set
	 */
	public void setReturnScores(boolean returnScores) {
		this.returnScores = returnScores;
	}

	/**
	 * @return the returnFacets
	 */
	public boolean isReturnFacets() {
		return returnFacets;
	}

	/**
	 * @param returnFacets
	 *            the returnFacets to set
	 */
	public void setReturnFacets(boolean returnFacets) {
		this.returnFacets = returnFacets;
	}

	/**
	 * @return the type
	 */
	public JoinType getType() {
		return type;
	}

	/**
	 * @param type
	 *            the type to set
	 */
	public void setType(JoinType type) {
		this.type = type;
	}

	protected final Client getFogeignClient() throws SearchLibException {
		Client foreignClient = ClientCatalog.getClient(indexName);
		if (foreignClient == null)
			throw new SearchLibException("No client found: " + indexName);
		return foreignClient;
	}

	protected AbstractSearchRequest getForeignSearchRequest(
			final Client foreignClient) throws SearchLibException {
		AbstractRequest foreignRequest = StringUtils.isEmpty(queryTemplate) ? new SearchFieldRequest(
				foreignClient) : foreignClient.getNewRequest(queryTemplate);
		if (foreignRequest == null)
			throw new SearchLibException("The request template was not found: "
					+ queryTemplate);
		if (!(foreignRequest instanceof AbstractSearchRequest))
			throw new SearchLibException(
					"The request template is not a Search request: "
							+ queryTemplate);
		return (AbstractSearchRequest) foreignRequest;
	}

	private final void lazyLoadForeignSearchRequest() throws SearchLibException {
		if (foreignClient == null)
			foreignClient = getFogeignClient();
		if (foreignSearchRequest == null)
			foreignSearchRequest = getForeignSearchRequest(foreignClient);
	}

	public DocIdInterface apply(AbstractSearchRequest searchRequest,
			ReaderAbstract reader, DocIdInterface docs, int joinResultSize,
			JoinResult joinResult, List joinFacets, Timer timer)
			throws SearchLibException {
		try {
			FieldCacheIndex localStringIndex = reader
					.getStringIndex(localField);
			if (localStringIndex == null)
				throw new SearchLibException(
						"No string index found for the local field: "
								+ localField);
			lazyLoadForeignSearchRequest();
			foreignSearchRequest.setStart(0);
			foreignSearchRequest.setRows(0);
			foreignSearchRequest.setUsers(searchRequest.getUsers());
			foreignSearchRequest.setGroups(searchRequest.getGroups());
			foreignSearchRequest.setQueryString(queryString);
			for (FilterAbstract filter : filterList)
				foreignSearchRequest.getFilterList().add(filter);
			String joinResultName = "join " + joinResult.joinPosition;
			Timer t = new Timer(timer, joinResultName + " foreign search");
			ResultSearchSingle resultSearch = (ResultSearchSingle) foreignClient
					.request(foreignSearchRequest);
			t.getDuration();
			joinResult.setForeignResult(resultSearch);
			if (foreignSearchRequest.isFacet()) {
				if (returnFacets)
					joinFacets.add(new JoinFacet(joinResult,
							foreignSearchRequest.getFacetFieldList(),
							resultSearch));
				foreignSearchRequest.getFacetFieldList().clear();
			}

			ReaderAbstract foreignReader = resultSearch.getReader();
			FieldCacheIndex foreignFieldIndex = foreignReader
					.getStringIndex(foreignField);
			if (foreignFieldIndex == null)
				throw new SearchLibException(StringUtils.fastConcat(
						"No string index found for the foreign field: ",
						foreignField));
			t = new Timer(timer, joinResultName + " join");
			DocIdInterface joinDocs = JoinUtils.join(docs, localStringIndex,
					resultSearch.getDocs(), foreignFieldIndex, joinResultSize,
					joinResult.joinPosition, t, type, outerCollector,
					foreignReader);
			t.getDuration();
			return joinDocs;
		} catch (IOException e) {
			throw new SearchLibException(e);
		}
	}

	public void setFromServlet(ServletTransaction transaction, String prefix)
			throws SearchLibException, SyntaxError {
		String myPrefix = StringUtils.fastConcat(prefix, paramPosition);
		String q = transaction.getParameterString(myPrefix);
		if (q != null)
			setQueryString(q);
		myPrefix = StringUtils.fastConcat(myPrefix, ".");
		filterList.addFromServlet(transaction, myPrefix);
		lazyLoadForeignSearchRequest();
		foreignSearchRequest.setFromServlet(transaction, myPrefix);
	}

	public void setParam(String param) {
		if (param != null)
			setQueryString(param);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy