Package org.dspace.app.cris.discovery

Source Code of org.dspace.app.cris.discovery.CrisSearchService$CrisItemWrapper

/**
* 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);
        }
    }

}
TOP

Related Classes of org.dspace.app.cris.discovery.CrisSearchService$CrisItemWrapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.