001// --------------------------------------------------------------------------------
002// Copyright 2002-2024 Echo Three, LLC
003//
004// Licensed under the Apache License, Version 2.0 (the "License");
005// you may not use this file except in compliance with the License.
006// You may obtain a copy of the License at
007//
008//     http://www.apache.org/licenses/LICENSE-2.0
009//
010// Unless required by applicable law or agreed to in writing, software
011// distributed under the License is distributed on an "AS IS" BASIS,
012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013// See the License for the specific language governing permissions and
014// limitations under the License.
015// --------------------------------------------------------------------------------
016
017package com.echothree.model.control.party.server.indexer;
018
019import com.echothree.model.control.index.common.IndexFields;
020import com.echothree.model.control.index.server.analysis.PartyAnalyzer;
021import com.echothree.model.control.index.server.indexer.BaseIndexer;
022import com.echothree.model.control.index.server.indexer.FieldTypes;
023import com.echothree.model.control.party.server.control.PartyControl;
024import com.echothree.model.control.party.server.logic.PartyLogic;
025import com.echothree.model.data.core.server.entity.EntityInstance;
026import com.echothree.model.data.index.server.entity.Index;
027import com.echothree.model.data.party.server.entity.Party;
028import com.echothree.model.data.party.server.entity.PartyType;
029import com.echothree.util.server.message.ExecutionErrorAccumulator;
030import com.echothree.util.server.persistence.Session;
031import org.apache.lucene.analysis.Analyzer;
032import org.apache.lucene.document.Document;
033import org.apache.lucene.document.Field;
034
035public abstract class PartyIndexer
036        extends BaseIndexer<Party> {
037    
038    PartyControl partyControl = Session.getModelController(PartyControl.class);
039    
040    protected PartyType partyType;
041    protected String entityNameIndexField;
042    
043    protected PartyIndexer(final ExecutionErrorAccumulator eea, final Index index, final String partyTypeName,
044            final String entityNameIndexField) {
045        super(eea, index);
046        
047        this.partyType = PartyLogic.getInstance().getPartyTypeByName(eea, partyTypeName);
048        this.entityNameIndexField = entityNameIndexField;
049    }
050    
051    @Override
052    protected Party getEntity(final EntityInstance entityInstance) {
053        return partyControl.getPartyByEntityInstance(entityInstance);
054
055    }
056
057    @Override
058    protected Analyzer getAnalyzer() {
059        return new PartyAnalyzer(eea, language, entityType, entityAliasTypes, entityAttributes, tagScopes, partyType, entityNameIndexField);
060    }
061
062    /**
063     * All PartyTypes have their own EntityName in addition to the partyName. If null is returned for this field, it
064     * likely indicates that the Party has been deleted before indexing picked it up and it will be ignored.
065     * @param party Party to return the EntityName for
066     * @return String with the EntityName, or null if it was not found
067     */
068    protected abstract String getEntityNameFromParty(final Party party);
069
070    protected void addPartyFieldsToDocument(final Party party, final String entityName, final Document document) {
071        var partyDetail = party.getLastDetail();
072        var person = partyControl.getPerson(party);
073        var partyGroup = partyControl.getPartyGroup(party);
074        var name = partyGroup == null ? null : partyGroup.getName();
075        var partyAliases = partyControl.getPartyAliasesByParty(party);
076
077        document.add(new Field(IndexFields.partyName.name(), partyDetail.getPartyName(), FieldTypes.NOT_STORED_TOKENIZED));
078        document.add(new Field(entityNameIndexField, entityName, FieldTypes.NOT_STORED_TOKENIZED));
079
080        if(name != null) {
081            document.add(new Field(IndexFields.name.name(), name, FieldTypes.NOT_STORED_TOKENIZED));
082        }
083
084        if(person != null) {
085            var firstName = person.getFirstName();
086            var middleName = person.getMiddleName();
087            var lastName = person.getLastName();
088
089            if(firstName != null) {
090                document.add(new Field(IndexFields.firstName.name(), firstName, FieldTypes.NOT_STORED_TOKENIZED));
091            }
092            if(middleName != null) {
093                document.add(new Field(IndexFields.middleName.name(), middleName, FieldTypes.NOT_STORED_TOKENIZED));
094            }
095            if(lastName != null) {
096                document.add(new Field(IndexFields.lastName.name(), lastName, FieldTypes.NOT_STORED_TOKENIZED));
097            }
098        }
099
100        for(var partyAlias : partyAliases) {
101            document.add(new Field(partyAlias.getPartyAliasType().getLastDetail().getPartyAliasTypeName(),
102                    partyAlias.getAlias(), FieldTypes.NOT_STORED_TOKENIZED));
103        }
104    }
105
106    @Override
107    protected Document convertToDocument(final EntityInstance entityInstance, final Party party) {
108        var partyDetail = party.getLastDetail();
109        Document document = null;
110
111        if(partyDetail.getPartyType().equals(partyType)) {
112            var entityName = getEntityNameFromParty(party);
113
114            // If this field is null, do not index the Party.
115            if(entityName != null) {
116                document = newDocumentWithEntityInstanceFields(entityInstance, party.getPrimaryKey());
117
118                addPartyFieldsToDocument(party, entityName, document);
119            }
120        }
121
122        return document;
123    }
124
125}