Java tutorial
/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE and NOTICE files at the root of the source * tree and available online at * * https://github.com/CILEA/dspace-cris/wiki/License */ package org.dspace.app.cris.discovery; import it.cilea.osd.common.core.HasTimeStampInfo; import it.cilea.osd.jdyna.model.ANestedPropertiesDefinition; import it.cilea.osd.jdyna.model.ANestedProperty; import it.cilea.osd.jdyna.model.ATypeNestedObject; import it.cilea.osd.jdyna.model.AValue; import it.cilea.osd.jdyna.model.AnagraficaSupport; import it.cilea.osd.jdyna.model.PropertiesDefinition; import it.cilea.osd.jdyna.model.Property; import it.cilea.osd.jdyna.value.DateValue; import it.cilea.osd.jdyna.value.PointerValue; import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.time.DateFormatUtils; import org.apache.log4j.Logger; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrInputDocument; import org.dspace.app.cris.model.ACrisObject; import org.dspace.app.cris.model.CrisConstants; import org.dspace.app.cris.model.ICrisObject; import org.dspace.app.cris.model.OrganizationUnit; import org.dspace.app.cris.model.Project; import org.dspace.app.cris.model.ResearchObject; import org.dspace.app.cris.model.ResearcherPage; import org.dspace.app.cris.model.VisibilityConstants; import org.dspace.app.cris.model.jdyna.ACrisNestedObject; import org.dspace.app.cris.model.jdyna.DynamicNestedObject; import org.dspace.app.cris.model.jdyna.DynamicNestedPropertiesDefinition; import org.dspace.app.cris.model.jdyna.DynamicNestedProperty; import org.dspace.app.cris.model.jdyna.DynamicPropertiesDefinition; import org.dspace.app.cris.model.jdyna.DynamicProperty; import org.dspace.app.cris.model.jdyna.DynamicTypeNestedObject; import org.dspace.app.cris.model.jdyna.OUNestedObject; import org.dspace.app.cris.model.jdyna.OUNestedPropertiesDefinition; import org.dspace.app.cris.model.jdyna.OUNestedProperty; import org.dspace.app.cris.model.jdyna.OUPropertiesDefinition; import org.dspace.app.cris.model.jdyna.OUProperty; import org.dspace.app.cris.model.jdyna.OUTypeNestedObject; import org.dspace.app.cris.model.jdyna.ProjectNestedObject; import org.dspace.app.cris.model.jdyna.ProjectNestedPropertiesDefinition; import org.dspace.app.cris.model.jdyna.ProjectNestedProperty; import org.dspace.app.cris.model.jdyna.ProjectPropertiesDefinition; import org.dspace.app.cris.model.jdyna.ProjectProperty; import org.dspace.app.cris.model.jdyna.ProjectTypeNestedObject; import org.dspace.app.cris.model.jdyna.RPNestedObject; import org.dspace.app.cris.model.jdyna.RPNestedPropertiesDefinition; import org.dspace.app.cris.model.jdyna.RPNestedProperty; import org.dspace.app.cris.model.jdyna.RPPropertiesDefinition; import org.dspace.app.cris.model.jdyna.RPProperty; import org.dspace.app.cris.model.jdyna.RPTypeNestedObject; import org.dspace.app.cris.service.ApplicationService; import org.dspace.app.cris.util.ResearcherPageUtils; import org.dspace.content.DCValue; import org.dspace.content.DSpaceObject; import org.dspace.content.Item; import org.dspace.core.Context; import org.dspace.discovery.SearchServiceException; import org.dspace.discovery.SearchUtils; import org.dspace.discovery.SolrServiceImpl; import org.dspace.discovery.configuration.DiscoveryConfiguration; import org.dspace.discovery.configuration.DiscoveryConfigurationParameters; import org.dspace.discovery.configuration.DiscoveryConfigurationService; import org.dspace.discovery.configuration.DiscoverySearchFilter; import org.dspace.discovery.configuration.DiscoverySearchFilterFacet; import org.dspace.discovery.configuration.DiscoverySortConfiguration; import org.dspace.discovery.configuration.DiscoverySortFieldConfiguration; import org.dspace.discovery.configuration.HierarchicalSidebarFacetConfiguration; import org.dspace.utils.DSpace; import org.springframework.aop.aspectj.annotation.AspectJProxyFactory; public class CrisSearchService extends SolrServiceImpl { private final class CrisItemWrapper implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { if (invocation.getMethod().getName().equals("getMetadata")) { if (invocation.getArguments().length == 4) { DCValue[] basic = (DCValue[]) invocation.proceed(); String schema = (String) invocation.getArguments()[0]; String element = (String) invocation.getArguments()[1]; String qualifier = (String) invocation.getArguments()[2]; String lang = (String) invocation.getArguments()[3]; if (schema == Item.ANY || "crisitem".equals(schema)) { DCValue[] dcvalues = addCrisEnhancedMetadata((Item) invocation.getThis(), basic, schema, element, qualifier, lang); return dcvalues; } } } return invocation.proceed(); } private DCValue[] addCrisEnhancedMetadata(Item item, DCValue[] basic, String schema, String element, String qualifier, String lang) { List<DCValue> extraMetadata = new ArrayList<DCValue>(); if (schema == Item.ANY) { List<String> crisMetadata = CrisItemEnhancerUtility.getAllCrisMetadata(); if (crisMetadata != null) { for (String cM : crisMetadata) { extraMetadata = CrisItemEnhancerUtility.getCrisMetadata(item, cM); } } } else if ("crisitem".equals(schema)) { extraMetadata = CrisItemEnhancerUtility.getCrisMetadata(item, schema + "." + element + "." + qualifier); } if (extraMetadata.size() == 0) { return basic; } else { DCValue[] result = new DCValue[basic.length + extraMetadata.size()]; List<DCValue> resultList = new ArrayList<DCValue>(); resultList.addAll(Arrays.asList(basic)); resultList.addAll(extraMetadata); result = resultList.toArray(result); return result; } } } private static final Logger log = Logger.getLogger(CrisSearchService.class); public ApplicationService getApplicationService() { return new DSpace().getServiceManager().getServiceByName("applicationService", ApplicationService.class); } @Override public void indexContent(Context context, DSpaceObject dso, boolean force) throws SQLException { if (dso != null && dso.getType() >= CrisConstants.CRIS_TYPE_ID_START) { indexCrisObject((ACrisObject) dso, false); } else { super.indexContent(context, dso, force); } } @Override public void createIndex(Context context) throws SQLException, IOException { createCrisIndex(context); super.createIndex(context); } @Override public void updateIndex(Context context, boolean force) { updateCrisIndex(context, force); super.updateIndex(context, force); } @Override public void cleanIndex(boolean force) throws IOException, SQLException, SearchServiceException { super.cleanIndex(force); try { if (force) { getSolr().deleteByQuery("search.resourcetype:[" + CrisConstants.CRIS_TYPE_ID_START + " TO *]"); } else { cleanIndex(force, CrisConstants.RP_TYPE_ID); cleanIndex(force, CrisConstants.NRP_TYPE_ID); cleanIndex(force, CrisConstants.PROJECT_TYPE_ID); cleanIndex(force, CrisConstants.NPROJECT_TYPE_ID); cleanIndex(force, CrisConstants.OU_TYPE_ID); cleanIndex(force, CrisConstants.NOU_TYPE_ID); } } catch (Exception e) { throw new SearchServiceException(e.getMessage(), e); } } @Override public DSpaceObject findDSpaceObject(Context context, SolrDocument doc) throws SQLException { Integer type = (Integer) doc.getFirstValue("search.resourcetype"); if (type != null && type >= CrisConstants.CRIS_TYPE_ID_START) { Integer id = (Integer) doc.getFirstValue("search.resourceid"); if (type > CrisConstants.CRIS_DYNAMIC_TYPE_ID_START) { return getApplicationService().get(ResearchObject.class, id); } else { switch (type) { case CrisConstants.RP_TYPE_ID: return getApplicationService().get(ResearcherPage.class, id); case CrisConstants.PROJECT_TYPE_ID: return getApplicationService().get(Project.class, id); case CrisConstants.OU_TYPE_ID: return getApplicationService().get(OrganizationUnit.class, id); default: return null; } } } else { return super.findDSpaceObject(context, doc); } } @Override protected void buildDocument(Context context, Item item) throws SQLException, IOException { AspectJProxyFactory pf = new AspectJProxyFactory(item); pf.setProxyTargetClass(true); pf.addAdvice(new CrisItemWrapper()); // ProxyFactory pf = new ProxyFactory(item); super.buildDocument(context, (Item) pf.getProxy()); } public <P extends Property<TP>, TP extends PropertiesDefinition, NP extends ANestedProperty<NTP>, NTP extends ANestedPropertiesDefinition, ACNO extends ACrisNestedObject<NP, NTP, P, TP>, ATNO extends ATypeNestedObject<NTP>> boolean indexCrisObject( ACrisObject<P, TP, NP, NTP, ACNO, ATNO> dso, boolean b) { boolean result = false; SolrInputDocument doc = buildDocument(dso.getType(), dso.getID(), null, null); log.debug("Building Cris: " + dso.getUuid()); String schema = "cris" + dso.getPublicPath(); String uuid = dso.getUuid(); Boolean status = dso.getStatus(); commonIndexerHeader(status, uuid, doc); // Keep a list of our sort values which we added, sort values can only // be added once List<String> sortFieldsAdded = new ArrayList<String>(); Set<String> hitHighlightingFields = new HashSet<String>(); List<String> toIgnoreFields = new ArrayList<String>(); // A map used to save each sidebarFacet config by the metadata // fields Map<String, List<DiscoverySearchFilter>> searchFilters = new HashMap<String, List<DiscoverySearchFilter>>(); Map<String, DiscoverySortFieldConfiguration> sortFields = new HashMap<String, DiscoverySortFieldConfiguration>(); Set<String> moreLikeThisFields = new HashSet<String>(); List<String> toProjectionFields = new ArrayList<String>(); commonIndexerDiscovery(schema, toIgnoreFields, searchFilters, toProjectionFields, sortFields); // add the special crisXX.this metadata indexProperty(doc, dso.getUuid(), schema + ".this", dso.getName(), ResearcherPageUtils.getPersistentIdentifier(dso), toIgnoreFields, searchFilters, toProjectionFields, sortFields, sortFieldsAdded, hitHighlightingFields, moreLikeThisFields); commonsIndexerAnagrafica(dso, doc, schema, sortFieldsAdded, hitHighlightingFields, uuid, toIgnoreFields, searchFilters, toProjectionFields, sortFields, moreLikeThisFields); commonsIndexerEnhancer(dso, doc, schema, sortFieldsAdded, hitHighlightingFields, uuid, toIgnoreFields, searchFilters, toProjectionFields, sortFields, moreLikeThisFields); commonsIndexerTimestamp(dso, doc, schema); log.debug(" Added Metadata"); // Do any additional indexing, depends on the plugins List<CrisServiceIndexPlugin> solrServiceIndexPlugins = new DSpace().getServiceManager() .getServicesByType(CrisServiceIndexPlugin.class); for (CrisServiceIndexPlugin solrServiceIndexPlugin : solrServiceIndexPlugins) { solrServiceIndexPlugin.additionalIndex(dso, doc); } // write the index and close the inputstreamreaders try { writeDocument(doc); result = true; log.info("Wrote cris: " + dso.getUuid() + " to Index"); } catch (Exception e) { log.error( "Error while writing cris to discovery index: " + dso.getUuid() + " message:" + e.getMessage(), e); } return result; } private void createCrisIndex(Context context) { this.<ResearcherPage, RPProperty, RPPropertiesDefinition, RPNestedProperty, RPNestedPropertiesDefinition, RPNestedObject, RPTypeNestedObject>createCrisIndex( context, ResearcherPage.class); this.<Project, ProjectProperty, ProjectPropertiesDefinition, ProjectNestedProperty, ProjectNestedPropertiesDefinition, ProjectNestedObject, ProjectTypeNestedObject>createCrisIndex( context, Project.class); this.<OrganizationUnit, OUProperty, OUPropertiesDefinition, OUNestedProperty, OUNestedPropertiesDefinition, OUNestedObject, OUTypeNestedObject>createCrisIndex( context, OrganizationUnit.class); this.<ResearchObject, DynamicProperty, DynamicPropertiesDefinition, DynamicNestedProperty, DynamicNestedPropertiesDefinition, DynamicNestedObject, DynamicTypeNestedObject>createCrisIndex( context, ResearchObject.class); } private void updateCrisIndex(Context context, boolean force) { cleanCrisIndex(context); createCrisIndex(context); } private void cleanCrisIndex(Context context) { try { getSolr().deleteByQuery("search.resourcetype:[" + CrisConstants.CRIS_TYPE_ID_START + " TO *]"); } catch (Exception e) { log.error("Error cleaning cris discovery index: " + e.getMessage(), e); } } private <P extends Property<TP>, TP extends PropertiesDefinition> void indexProperty(SolrInputDocument doc, String uuid, String field, P meta, List<String> toIgnoreFields, Map<String, List<DiscoverySearchFilter>> searchFilters, List<String> toProjectionFields, Map<String, DiscoverySortFieldConfiguration> sortFields, List<String> sortFieldsAdded, Set<String> hitHighlightingFields, Set<String> moreLikeThisFields) { AValue value = meta.getValue(); if (value == null || meta.getVisibility() != VisibilityConstants.PUBLIC) { return; } String svalue = meta.toString(); String authority = null; if (value instanceof PointerValue && value.getObject() instanceof ACrisObject) { authority = ResearcherPageUtils.getPersistentIdentifier((ACrisObject) value.getObject()); } if (value instanceof DateValue) { // TODO: make this date format configurable ! svalue = DateFormatUtils.formatUTC(((DateValue) value).getObject(), "yyyy-MM-dd"); } indexProperty(doc, uuid, field, svalue, authority, toIgnoreFields, searchFilters, toProjectionFields, sortFields, sortFieldsAdded, hitHighlightingFields, moreLikeThisFields); } private void indexProperty(SolrInputDocument doc, String uuid, String field, String svalue, String authority, List<String> toIgnoreFields, Map<String, List<DiscoverySearchFilter>> searchFilters, List<String> toProjectionFields, Map<String, DiscoverySortFieldConfiguration> sortFields, List<String> sortFieldsAdded, Set<String> hitHighlightingFields, Set<String> moreLikeThisFields) { if (toIgnoreFields.contains(field)) { return; } if ((searchFilters.get(field) != null)) { List<DiscoverySearchFilter> searchFilterConfigs = searchFilters.get(field); for (DiscoverySearchFilter searchFilter : searchFilterConfigs) { String separator = new DSpace().getConfigurationService() .getProperty("discovery.solr.facets.split.char"); if (separator == null) { separator = FILTER_SEPARATOR; } doc.addField(searchFilter.getIndexFieldName(), svalue); doc.addField(searchFilter.getIndexFieldName() + "_keyword", svalue); if (authority != null) { doc.addField(searchFilter.getIndexFieldName() + "_keyword", svalue + AUTHORITY_SEPARATOR + authority); doc.addField(searchFilter.getIndexFieldName() + "_authority", authority); doc.addField(searchFilter.getIndexFieldName() + "_acid", svalue.toLowerCase() + separator + svalue + AUTHORITY_SEPARATOR + authority); } // Add a dynamic fields for auto complete in search doc.addField(searchFilter.getIndexFieldName() + "_ac", svalue.toLowerCase() + separator + svalue); if (searchFilter.getFilterType().equals(DiscoverySearchFilterFacet.FILTER_TYPE_FACET)) { if (searchFilter.getType().equals(DiscoveryConfigurationParameters.TYPE_TEXT)) { // Add a special filter // We use a separator to split up the lowercase // and regular case, this is needed to get our // filters in regular case // Solr has issues with facet prefix and cases if (authority != null) { String facetValue = svalue; doc.addField(searchFilter.getIndexFieldName() + "_filter", facetValue.toLowerCase() + separator + facetValue + AUTHORITY_SEPARATOR + authority); } else { doc.addField(searchFilter.getIndexFieldName() + "_filter", svalue.toLowerCase() + separator + svalue); } } else if (searchFilter.getType().equals(DiscoveryConfigurationParameters.TYPE_DATE)) { Date date = toDate(svalue); if (date != null) { String indexField = searchFilter.getIndexFieldName() + ".year"; doc.addField(searchFilter.getIndexFieldName() + "_keyword", DateFormatUtils.formatUTC(date, "yyyy")); doc.addField(indexField, DateFormatUtils.formatUTC(date, "yyyy")); // Also save a sort value of this year, this // is required for determining the upper & // lower bound year of our facet if (doc.getField(indexField + "_sort") == null) { // We can only add one year so take the // first one doc.addField(indexField + "_sort", DateFormatUtils.formatUTC(date, "yyyy")); } } } else if (searchFilter.getType().equals(DiscoveryConfigurationParameters.TYPE_HIERARCHICAL)) { HierarchicalSidebarFacetConfiguration hierarchicalSidebarFacetConfiguration = (HierarchicalSidebarFacetConfiguration) searchFilter; String[] subValues = svalue.split(hierarchicalSidebarFacetConfiguration.getSplitter()); if (hierarchicalSidebarFacetConfiguration.isSkipFirstNodeLevel() && 1 < subValues.length) { // Remove the first element of our array subValues = (String[]) ArrayUtils.subarray(subValues, 1, subValues.length); } for (int i = 0; i < subValues.length; i++) { StringBuilder valueBuilder = new StringBuilder(); for (int j = 0; j <= i; j++) { valueBuilder.append(subValues[j]); if (j < i) { valueBuilder.append(hierarchicalSidebarFacetConfiguration.getSplitter()); } } String indexValue = valueBuilder.toString().trim(); doc.addField(searchFilter.getIndexFieldName() + "_tax_" + i + "_filter", indexValue.toLowerCase() + separator + indexValue); // We add the field x times that it has // occurred for (int j = i; j < subValues.length; j++) { doc.addField(searchFilter.getIndexFieldName() + "_filter", indexValue.toLowerCase() + separator + indexValue); doc.addField(searchFilter.getIndexFieldName() + "_keyword", indexValue); } } } } } } if ((sortFields.get(field) != null && !sortFieldsAdded.contains(field))) { // Only add sort value once String type = ""; if (sortFields.get(field) != null) { type = sortFields.get(field).getType(); } if (type.equals(DiscoveryConfigurationParameters.TYPE_DATE)) { Date date = toDate(svalue); if (date != null) { doc.addField(field + "_dt", date); } else { log.warn("Error while indexing sort date field, cris: " + uuid + " metadata field: " + field + " date value: " + svalue); } } else { doc.addField(field + "_sort", svalue); } sortFieldsAdded.add(field); } if (hitHighlightingFields.contains(field) || hitHighlightingFields.contains("*")) { doc.addField(field + "_hl", svalue); } if (moreLikeThisFields.contains(field)) { doc.addField(field + "_mlt", svalue); } doc.addField(field, svalue); if (authority != null) { doc.addField(field + "_authority", authority); } if (toProjectionFields.contains(field)) { doc.addField(field + "_stored", svalue + STORE_SEPARATOR + authority); } } public QueryResponse search(SolrQuery query) throws SearchServiceException { try { return getSolr().query(query); } catch (Exception e) { throw new org.dspace.discovery.SearchServiceException(e.getMessage(), e); } } @Override public void updateIndex(Context context, boolean force, int type) { if (type > CrisConstants.CRIS_DYNAMIC_TYPE_ID_START) { this.<ResearchObject, DynamicProperty, DynamicPropertiesDefinition, DynamicNestedProperty, DynamicNestedPropertiesDefinition, DynamicNestedObject, DynamicTypeNestedObject>createCrisIndex( context, ResearchObject.class); } else { if (CrisConstants.RP_TYPE_ID == type) { this.<ResearcherPage, RPProperty, RPPropertiesDefinition, RPNestedProperty, RPNestedPropertiesDefinition, RPNestedObject, RPTypeNestedObject>createCrisIndex( context, ResearcherPage.class); } else if (CrisConstants.PROJECT_TYPE_ID == type) { this.<Project, ProjectProperty, ProjectPropertiesDefinition, ProjectNestedProperty, ProjectNestedPropertiesDefinition, ProjectNestedObject, ProjectTypeNestedObject>createCrisIndex( context, Project.class); } else if (CrisConstants.OU_TYPE_ID == type) { this.<OrganizationUnit, OUProperty, OUPropertiesDefinition, OUNestedProperty, OUNestedPropertiesDefinition, OUNestedObject, OUTypeNestedObject>createCrisIndex( context, OrganizationUnit.class); } else { super.updateIndex(context, force, type); } } } private <T extends ACrisObject<P, TP, NP, NTP, ACNO, ATNO>, P extends Property<TP>, TP extends PropertiesDefinition, NP extends ANestedProperty<NTP>, NTP extends ANestedPropertiesDefinition, ACNO extends ACrisNestedObject<NP, NTP, P, TP>, ATNO extends ATypeNestedObject<NTP>> void createCrisIndex( Context context, Class<T> classCrisObject) { List<T> rpObjects = getApplicationService().getList(classCrisObject); if (rpObjects != null) { for (T cris : rpObjects) { indexCrisObject(cris, true); // indexing nested for (ATNO anestedtype : getApplicationService().getList(cris.getClassTypeNested())) { List<ACNO> anesteds = getApplicationService().getNestedObjectsByParentIDAndTypoID(cris.getId(), anestedtype.getId(), cris.getClassNested()); for (ACNO anested : anesteds) { indexNestedObject(anested, true); } } } } } public <P extends Property<TP>, TP extends PropertiesDefinition, NP extends ANestedProperty<NTP>, NTP extends ANestedPropertiesDefinition, ACNO extends ACrisNestedObject<NP, NTP, P, TP>, ATNO extends ATypeNestedObject<NTP>> boolean indexNestedObject( ACNO dso, boolean b) { boolean result = false; SolrInputDocument doc = buildDocument(dso.getType(), dso.getID(), null, null); log.debug("Building Cris: " + dso.getUuid()); ICrisObject<P, TP> parent = (ICrisObject<P, TP>) dso.getParent(); doc.addField("search.parentfk", parent.getType() + "-" + parent.getID()); String confName = "ncris" + parent.getPublicPath(); String schema = confName + dso.getTypo().getShortName(); String uuid = dso.getUuid(); Boolean status = dso.getStatus(); Integer position = dso.getPositionDef(); doc.addField("position", position); commonIndexerHeader(status, uuid, doc); // Keep a list of our sort values which we added, sort values can only // be added once List<String> sortFieldsAdded = new ArrayList<String>(); Set<String> hitHighlightingFields = new HashSet<String>(); List<String> toIgnoreFields = new ArrayList<String>(); // A map used to save each sidebarFacet config by the metadata // fields Map<String, List<DiscoverySearchFilter>> searchFilters = new HashMap<String, List<DiscoverySearchFilter>>(); Map<String, DiscoverySortFieldConfiguration> sortFields = new HashMap<String, DiscoverySortFieldConfiguration>(); Set<String> moreLikeThisFields = new HashSet<String>(); List<String> toProjectionFields = new ArrayList<String>(); commonIndexerDiscovery(confName, toIgnoreFields, searchFilters, toProjectionFields, sortFields); commonsIndexerAnagrafica(dso, doc, schema, sortFieldsAdded, hitHighlightingFields, uuid, toIgnoreFields, searchFilters, toProjectionFields, sortFields, moreLikeThisFields); commonsIndexerEnhancer(dso, doc, schema, sortFieldsAdded, hitHighlightingFields, uuid, toIgnoreFields, searchFilters, toProjectionFields, sortFields, moreLikeThisFields); commonsIndexerTimestamp(dso, doc, schema); // Do any additional indexing, depends on the plugins List<CrisServiceIndexPlugin> solrServiceIndexPlugins = new DSpace().getServiceManager() .getServicesByType(CrisServiceIndexPlugin.class); for (CrisServiceIndexPlugin solrServiceIndexPlugin : solrServiceIndexPlugins) { solrServiceIndexPlugin.additionalIndex(dso, doc); } log.debug(" Added Metadata"); // write the index and close the inputstreamreaders try { writeDocument(doc); result = true; log.info("Wrote cris: " + dso.getUuid() + " to Index"); } catch (Exception e) { log.error( "Error while writing cris to discovery index: " + dso.getUuid() + " message:" + e.getMessage(), e); } return result; } private <P, TP, PP, PTP> void commonIndexerHeader(Boolean status, String uuid, SolrInputDocument doc) { if (status == null || !status) { // only admin can searh/browse disabled researcher page doc.addField("withdrawn", true); doc.addField("disabled", true); } else { doc.addField("withdrawn", false); doc.addField("disabled", false); } doc.addField("read", "g0"); doc.addField("discoverable", true);// item.isDiscoverable()); doc.addField("cris-uuid", uuid); } private void commonsIndexerTimestamp(HasTimeStampInfo dso, SolrInputDocument doc, String schema) { try { if (dso.getTimeStampInfo() != null && dso.getTimeStampInfo().getTimestampCreated() != null && dso.getTimeStampInfo().getTimestampCreated().getTimestamp() != null) { doc.addField(schema + ".time_creation_dt", dso.getTimeStampInfo().getTimestampCreated().getTimestamp()); doc.addField("crisDateIssued.year", DateFormatUtils .formatUTC(dso.getTimeStampInfo().getTimestampCreated().getTimestamp(), "yyyy")); } if (dso.getTimeStampInfo() != null && dso.getTimeStampInfo().getTimestampLastModified() != null && dso.getTimeStampInfo().getTimestampLastModified().getTimestamp() != null) { doc.addField(schema + ".time_lastmodified_dt", dso.getTimeStampInfo().getTimestampLastModified().getTimestamp()); doc.addField("crisDateIssued.year_lastmodified", DateFormatUtils .formatUTC(dso.getTimeStampInfo().getTimestampCreated().getTimestamp(), "yyyy")); } } catch (Exception e) { log.error(e.getMessage(), e); } } private <P extends Property<TP>, TP extends PropertiesDefinition> void commonsIndexerEnhancer( ICrisObject<P, TP> dso, SolrInputDocument doc, String schema, List<String> sortFieldsAdded, Set<String> hitHighlightingFields, String uuid, List<String> toIgnoreFields, Map<String, List<DiscoverySearchFilter>> searchFilters, List<String> toProjectionFields, Map<String, DiscoverySortFieldConfiguration> sortFields, Set<String> moreLikeThisFields) { try { List<CrisEnhancer> crisEnhancers = new DSpace().getServiceManager() .getServicesByType(CrisEnhancer.class); for (CrisEnhancer cEnh : crisEnhancers) { if (cEnh.getClazz().isAssignableFrom(dso.getClass())) { for (String qual : cEnh.getQualifiers()) { List<P> props = cEnh.getProperties(dso, qual); for (P meta : props) { String field = schema + "." + cEnh.getAlias() + "." + qual; indexProperty(doc, uuid, field, meta, toIgnoreFields, searchFilters, toProjectionFields, sortFields, sortFieldsAdded, hitHighlightingFields, moreLikeThisFields); } } } } } catch (Exception e) { log.error(e.getMessage(), e); } } private <P extends Property<TP>, TP extends PropertiesDefinition> void commonsIndexerAnagrafica( AnagraficaSupport<P, TP> dso, SolrInputDocument doc, String schema, List<String> sortFieldsAdded, Set<String> hitHighlightingFields, String uuid, List<String> toIgnoreFields, Map<String, List<DiscoverySearchFilter>> searchFilters, List<String> toProjectionFields, Map<String, DiscoverySortFieldConfiguration> sortFields, Set<String> moreLikeThisFields) { try { List<P> mydc = dso.getAnagrafica(); for (P meta : mydc) { String field = schema + "." + meta.getTypo().getShortName(); indexProperty(doc, uuid, field, meta, toIgnoreFields, searchFilters, toProjectionFields, sortFields, sortFieldsAdded, hitHighlightingFields, moreLikeThisFields); } } catch (Exception e) { log.error(e.getMessage(), e); } } private void commonIndexerDiscovery(String confName, List<String> toIgnoreFields, Map<String, List<DiscoverySearchFilter>> searchFilters, List<String> toProjectionFields, Map<String, DiscoverySortFieldConfiguration> sortFields) { try { List<DiscoveryConfiguration> discoveryConfigurations = new ArrayList<DiscoveryConfiguration>(); DiscoveryConfiguration generalConfiguration = SearchUtils.getDiscoveryConfiguration(); if (generalConfiguration != null) { discoveryConfigurations.add(generalConfiguration); } DiscoveryConfigurationService configurationService = SearchUtils.getConfigurationService(); DiscoveryConfiguration crisConfiguration = configurationService.getMap().get(confName); if (crisConfiguration != null) { discoveryConfigurations.add(crisConfiguration); } for (DiscoveryConfiguration discoveryConfiguration : discoveryConfigurations) { for (int i = 0; i < discoveryConfiguration.getSearchFilters().size(); i++) { DiscoverySearchFilter discoverySearchFilter = discoveryConfiguration.getSearchFilters().get(i); for (int j = 0; j < discoverySearchFilter.getMetadataFields().size(); j++) { String metadataField = discoverySearchFilter.getMetadataFields().get(j); List<DiscoverySearchFilter> resultingList; if (searchFilters.get(metadataField) != null) { resultingList = searchFilters.get(metadataField); } else { // New metadata field, create a new list for it resultingList = new ArrayList<DiscoverySearchFilter>(); } resultingList.add(discoverySearchFilter); searchFilters.put(metadataField, resultingList); } } DiscoverySortConfiguration sortConfiguration = discoveryConfiguration.getSearchSortConfiguration(); if (sortConfiguration != null) { for (DiscoverySortFieldConfiguration discoverySortConfiguration : sortConfiguration .getSortFields()) { sortFields.put(discoverySortConfiguration.getMetadataField(), discoverySortConfiguration); } } } String ignoreFieldsString = new DSpace().getConfigurationService() .getProperty("discovery.index.ignore"); if (ignoreFieldsString != null) { if (ignoreFieldsString.contains(",")) { for (int i = 0; i < ignoreFieldsString.split(",").length; i++) { toIgnoreFields.add(ignoreFieldsString.split(",")[i].trim()); } } else { toIgnoreFields.add(ignoreFieldsString); } } String projectionFieldsString = new DSpace().getConfigurationService() .getProperty("discovery.index.projection"); if (projectionFieldsString != null) { if (projectionFieldsString.indexOf(",") != -1) { for (int i = 0; i < projectionFieldsString.split(",").length; i++) { toProjectionFields.add(projectionFieldsString.split(",")[i].trim()); } } else { toProjectionFields.add(projectionFieldsString); } } } catch (Exception e) { log.error(e.getMessage(), e); } } public <P extends ANestedProperty<TP>, TP extends ANestedPropertiesDefinition, PP extends Property<PTP>, PTP extends PropertiesDefinition> void unIndexContent( Object context, ACrisNestedObject<P, TP, PP, PTP> nested, boolean commit) { try { if (nested == null) { return; } String uniqueID = nested.getType() + "-" + nested.getID(); getSolr().deleteById(uniqueID); if (commit) { getSolr().commit(); } } catch (Exception exception) { log.error(exception.getMessage(), exception); emailException(exception); } } }