com.alogient.cameleon.sdk.search.solr.SolrSearchService Maven / Gradle / Ivy
The newest version!
package com.alogient.cameleon.sdk.search.solr;
import com.alogient.cameleon.sdk.content.model.AbstractCameleonModel;
import com.alogient.cameleon.sdk.content.model.ImageModel;
import com.alogient.cameleon.sdk.content.model.ResourceModel;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModel;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelAllElements;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelClosestUpElement;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelElement;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelElement.DataType;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelFirstElement;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelImage;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelLinkedElement;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelLinkedElements;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelParentElement;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelResource;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelReverseLinkedElements;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelSubElements;
import com.alogient.cameleon.sdk.content.util.InternalCameleonConfig;
import com.alogient.cameleon.sdk.content.vo.media.VideoVo;
import com.alogient.cameleon.sdk.search.SearchService;
import com.google.common.base.Strings;
import org.apache.commons.lang.StringUtils;
import org.apache.solr.client.solrj.ResponseParser;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.util.ContentStreamBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class SolrSearchService implements SearchService {
/**
* The log for this class
*/
protected final Logger log = LoggerFactory.getLogger(getClass());
private final static String SERVER_URL = "cameleon.search.solr.server_url";
private final static String SOCKET_TIMEOUT = "cameleon.search.solr.socket_timeout";
private final static String CONNECTION_TIMEOUT = "cameleon.search.solr.connection_timeout";
private final static String DEFAULT_MAX_CONNECTION_PER_HOST = "cameleon.search.solr.default_max_connection_per_host";
private final static String DEFAULT_MAX_TOTAL_CONNECTION = "cameleon.search.solr.max_total_connection";
private final static String FOLLOW_REDIRECTS = "cameleon.search.solr.follow_redirects";
private final static String ALLOW_COMPRESSION = "cameleon.search.solr.allow_compression";
private final static String MAX_RETRIES = "cameleon.search.solr.max_retries";
private final static String PARSER = "cameleon.search.solr.parser";
private final static String READ_ONLY = "cameleon.search.solr.read_only";
private CommonsHttpSolrServer server;
private boolean isReadOnly;
private boolean isInitialized;
public SolrSearchService() {
isInitialized = false;
}
@Override
public Set getIndexedUrls() {
SolrQuery query = new SolrQuery();
query.setQuery("*");
query.setRows(Integer.MAX_VALUE);
Set indexedUrls = new HashSet();
try {
QueryResponse response = server.query(query);
for (SolrDocument document : response.getResults()) {
indexedUrls.add((String) document.getFieldValue(SEARCH_ID));
}
} catch (SolrServerException e) {
log.error(e.getMessage(), e);
}
return indexedUrls;
}
@Override
public void removeIndex(String url) {
try {
server.deleteById(url);
server.commit();
} catch (SolrServerException e) {
log.error(e.getMessage(), e);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
@Override
public void indexBinaryDocument(String path, String fileName, boolean isRemote) {
if (!isRemote) {
indexLocalBinaryDocument(path, fileName);
} else {
indexRemoteBinaryDocument(path, fileName);
}
}
private void indexLocalBinaryDocument(String path, String fileName) {
try {
File fileToIndex = new File(path);
ContentStreamUpdateRequest up = new ContentStreamUpdateRequest("/update/extract");
up.addFile(fileToIndex);
up.setParam("literal.id", fileName);
up.setParam("uprefix", "attr_");
up.setParam("fmap.content", "attr_content");
up.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true);
server.request(up);
} catch (IOException e) {
log.error("Unable to index a binary document - " + e.getMessage(), e);
} catch (SolrServerException e) {
log.error("Unable to index a binary document - " + e.getMessage(), e);
}
}
public void indexRemoteBinaryDocument(String remoteUrl, String fileName) {
try {
ContentStreamUpdateRequest up = new ContentStreamUpdateRequest("/update/extract");
up.addContentStream(new ContentStreamBase.URLStream(new URL(remoteUrl)));
up.setParam("literal.id", remoteUrl);
up.setParam("resource.name", fileName);
up.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true);
server.request(up);
} catch (IOException e) {
log.error("Unable to index a binary document - " + e.getMessage(), e);
} catch (SolrServerException e) {
log.error("Unable to index a binary document - " + e.getMessage(), e);
}
}
@Override
public void indexCameleonModel(String url, AbstractCameleonModel model) {
SolrInputDocument doc = new SolrInputDocument();
doc.addField(SEARCH_ID, url);
doc.addField(SEARCH_NAV_ID, model.getNavId());
doc.addField(SEARCH_PAGE_ID, model.getPageId());
doc.addField(SEARCH_CULTURE_CODE, model.getCultureCode());
doc.addField(SEARCH_PAGE_NAME, model.getPageName());
doc.addField("text", model.getPageName());
// Extract the templateName
Class extends AbstractCameleonModel> clazz = model.getClass();
if (clazz.isAnnotationPresent(CameleonModel.class)) {
CameleonModel cameleonModel = clazz.getAnnotation(CameleonModel.class);
doc.addField(SEARCH_TEMPLATE_NAME, cameleonModel.templateName());
}
// Index inner elements
indexInnerElements(doc, model);
try {
server.add(doc);
server.commit();
} catch (SolrServerException e) {
log.error(e.getMessage(), e);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
private void indexInnerElements(SolrInputDocument doc, Object object) {
if (object == null) {
return;
}
if (object.getClass().isAnnotationPresent(CameleonModel.class)) {
CameleonModel cameleonModel = object.getClass().getAnnotation(CameleonModel.class);
AbstractCameleonModel abstractCameleonModel = (AbstractCameleonModel) object;
if (!Strings.isNullOrEmpty(cameleonModel.pageNameIndexField())) {
doc.addField(cameleonModel.pageNameIndexField(), abstractCameleonModel.getPageName());
}
}
@SuppressWarnings("rawtypes")
Class clazz = object.getClass();
while (clazz != null) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(CameleonModelElement.class)) {
CameleonModelElement cme = field.getAnnotation(CameleonModelElement.class);
if (cme.isIndexed()) {
if (cme.dataType() == DataType.Value || cme.dataType() == DataType.OptionValue) {
Object elementValue = getFieldValue(field, object);
if (elementValue != null) {
doc.addField(StringUtils.isBlank(cme.valueIndexField()) ? "text" : cme.valueIndexField(), elementValue);
}
} else if (cme.dataType() == DataType.Video) {
VideoVo elementValue = getFieldValue(field, object);
if (elementValue != null) {
doc.addField(StringUtils.isBlank(cme.videoTitleIndexField()) ? "text" : cme.videoTitleIndexField(), elementValue.getTitle());
doc.addField(StringUtils.isBlank(cme.videoDescriptionIndexField()) ? "text" : cme.videoDescriptionIndexField(), elementValue.getDescription());
}
}
}
} else if (field.isAnnotationPresent(CameleonModelImage.class)) {
CameleonModelImage cmi = field.getAnnotation(CameleonModelImage.class);
if (cmi.isIndexed()) {
ImageModel elementValue = getFieldValue(field, object);
if (elementValue != null) {
doc.addField(StringUtils.isBlank(cmi.altIndexField()) ? "text" : cmi.altIndexField(), elementValue.getAlt());
}
}
} else if (field.isAnnotationPresent(CameleonModelResource.class)) {
CameleonModelResource cmi = field.getAnnotation(CameleonModelResource.class);
if (cmi.isIndexed()) {
ResourceModel elementValue = getFieldValue(field, object);
// Index the resource if the resource is live.
if ((elementValue != null) && elementValue.getModeType().isLiveMode()) {
indexBinaryDocument(elementValue.getUrl(), elementValue.getFileName(), true);
}
}
} else if (field.isAnnotationPresent(CameleonModelLinkedElement.class)) {
CameleonModelLinkedElement cmle = field.getAnnotation(CameleonModelLinkedElement.class);
if (cmle.isIndexed()) {
Object subModel = getFieldValue(field, object);
if (subModel != null) {
indexInnerElements(doc, subModel);
}
}
} else if (field.isAnnotationPresent(CameleonModelLinkedElements.class)) {
CameleonModelLinkedElements cmle = field.getAnnotation(CameleonModelLinkedElements.class);
if (cmle.isIndexed()) {
@SuppressWarnings("rawtypes")
List subModels = getFieldValue(field, object);
if (subModels != null) {
for (Object subModel : subModels) {
indexInnerElements(doc, subModel);
}
}
}
} else if (field.isAnnotationPresent(CameleonModelReverseLinkedElements.class)) {
CameleonModelReverseLinkedElements cmrle = field.getAnnotation(CameleonModelReverseLinkedElements.class);
if (cmrle.isIndexed()) {
@SuppressWarnings("rawtypes")
List subModels = getFieldValue(field, object);
if (subModels != null) {
for (Object subModel : subModels) {
indexInnerElements(doc, subModel);
}
}
}
} else if (field.isAnnotationPresent(CameleonModelAllElements.class)) {
CameleonModelAllElements cmae = field.getAnnotation(CameleonModelAllElements.class);
if (cmae.isIndexed()) {
@SuppressWarnings("rawtypes")
List subModels = getFieldValue(field, object);
if (subModels != null) {
for (Object subModel : subModels) {
indexInnerElements(doc, subModel);
}
}
}
} else if (field.isAnnotationPresent(CameleonModelFirstElement.class)) {
CameleonModelFirstElement cmfe = field.getAnnotation(CameleonModelFirstElement.class);
if (cmfe.isIndexed()) {
Object subModel = getFieldValue(field, object);
if (subModel != null) {
indexInnerElements(doc, subModel);
}
}
} else if (field.isAnnotationPresent(CameleonModelSubElements.class)) {
CameleonModelSubElements cmse = field.getAnnotation(CameleonModelSubElements.class);
if (cmse.isIndexed()) {
@SuppressWarnings("rawtypes")
List subModels = getFieldValue(field, object);
if (subModels != null) {
for (Object subModel : subModels) {
indexInnerElements(doc, subModel);
}
}
}
} else if (field.isAnnotationPresent(CameleonModelParentElement.class)) {
CameleonModelParentElement cmpe = field.getAnnotation(CameleonModelParentElement.class);
if (cmpe.isIndexed()) {
Object subModel = getFieldValue(field, object);
if (subModel != null) {
indexInnerElements(doc, subModel);
}
}
} else if (field.isAnnotationPresent(CameleonModelClosestUpElement.class)) {
CameleonModelClosestUpElement cmcue = field.getAnnotation(CameleonModelClosestUpElement.class);
if (cmcue.isIndexed()) {
Object subModel = getFieldValue(field, object);
if (subModel != null) {
indexInnerElements(doc, subModel);
}
}
}
}
clazz = clazz.getSuperclass();
}
}
@SuppressWarnings("unchecked")
private T getFieldValue(Field field, Object object) {
field.setAccessible(true);
try {
return (T) field.get(object);
} catch (IllegalArgumentException e) {
log.error(e.getMessage(), e);
} catch (IllegalAccessException e) {
log.error(e.getMessage(), e);
}
return null;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isReadOnly() {
return isReadOnly;
}
@Override
public boolean isInitialized() {
if (!isInitialized) {
init();
}
return server != null;
}
@Override
public List doSearch(SolrQuery query) {
if (!isInitialized()) {
return Collections.emptyList();
}
List results = new ArrayList();
try {
QueryResponse response = server.query(query);
for (SolrDocument document : response.getResults()) {
results.add(document);
}
} catch (SolrServerException e) {
log.error(e.getMessage(), e);
}
return results;
}
private void init() {
String serverUrl = InternalCameleonConfig.getString(SERVER_URL, null);
Integer socketTimeout = InternalCameleonConfig.getInteger(SOCKET_TIMEOUT, null);
Integer connectionTimeout = InternalCameleonConfig.getInteger(CONNECTION_TIMEOUT, null);
Integer defaultMaxConnectionPerHost = InternalCameleonConfig.getInteger(DEFAULT_MAX_CONNECTION_PER_HOST, null);
Integer defaultMaxTotalConnection = InternalCameleonConfig.getInteger(DEFAULT_MAX_TOTAL_CONNECTION, null);
Boolean followRedirects = InternalCameleonConfig.getBoolean(FOLLOW_REDIRECTS, null);
Boolean allowCompression = InternalCameleonConfig.getBoolean(ALLOW_COMPRESSION, null);
Integer maxRetries = InternalCameleonConfig.getInteger(MAX_RETRIES, null);
String parser = InternalCameleonConfig.getString(PARSER, null);
isReadOnly = InternalCameleonConfig.getBoolean(READ_ONLY, Boolean.FALSE);
if (StringUtils.isBlank(serverUrl)) {
log.error("Solr cannot be initialized without a server url : cameleon.search.solr.server_url");
return;
}
try {
server = new CommonsHttpSolrServer(serverUrl);
} catch (MalformedURLException e) {
log.error("Solr cannot be initialized without a malformed url : ", e);
return;
}
if (socketTimeout != null) {
server.setSoTimeout(socketTimeout);
}
if (connectionTimeout != null) {
server.setConnectionTimeout(connectionTimeout);
}
if (defaultMaxConnectionPerHost != null) {
server.setDefaultMaxConnectionsPerHost(defaultMaxConnectionPerHost);
}
if (defaultMaxTotalConnection != null) {
server.setMaxTotalConnections(defaultMaxTotalConnection);
}
if (followRedirects != null) {
server.setFollowRedirects(followRedirects);
}
if (allowCompression != null) {
server.setAllowCompression(allowCompression);
}
if (maxRetries != null) {
server.setMaxRetries(maxRetries);
}
if (StringUtils.isNotBlank(parser)) {
try {
server.setParser((ResponseParser) Class.forName(parser).newInstance());
} catch (InstantiationException e) {
log.error(e.getMessage(), e);
throw new IllegalStateException("Invalid parser " + parser);
} catch (IllegalAccessException e) {
log.error(e.getMessage(), e);
throw new IllegalStateException("Invalid parser " + parser);
} catch (ClassNotFoundException e) {
log.error(e.getMessage(), e);
throw new IllegalStateException("Invalid parser " + parser);
}
}
isInitialized = true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy