com.evolveum.midpoint.repo.sql.data.common.RObjectTextInfo.java Source code

Java tutorial

Introduction

Here is the source code for com.evolveum.midpoint.repo.sql.data.common.RObjectTextInfo.java

Source

/*
 * Copyright (c) 2010-2013 Evolveum
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.evolveum.midpoint.repo.sql.data.common;

import com.evolveum.midpoint.prism.Item;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismPropertyValue;
import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.polystring.PolyString;
import com.evolveum.midpoint.repo.sql.data.RepositoryContext;
import com.evolveum.midpoint.repo.sql.data.common.id.RObjectTextInfoId;
import com.evolveum.midpoint.repo.sql.helpers.modify.Ignore;
import com.evolveum.midpoint.repo.sql.query2.definition.NotQueryable;
import com.evolveum.midpoint.repo.sql.util.RUtil;
import com.evolveum.midpoint.schema.util.FullTextSearchConfigurationUtil;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.ForeignKey;
import org.jetbrains.annotations.NotNull;

import javax.persistence.*;
import java.io.Serializable;
import java.util.*;
import java.util.Objects;

import static com.evolveum.midpoint.repo.sql.data.common.RObjectTextInfo.TABLE_NAME;

/**
 * @author mederly
 */
@Ignore
@Entity
@IdClass(RObjectTextInfoId.class)
@Table(name = TABLE_NAME)
public class RObjectTextInfo implements Serializable {

    private static final Trace LOGGER = TraceManager.getTrace(RObjectTextInfo.class);

    public static final String TABLE_NAME = "m_object_text_info";
    public static final String COLUMN_OWNER_OID = "owner_oid";
    public static final String F_TEXT = "text";

    public static final int MAX_TEXT_SIZE = 255;

    private RObject owner;
    private String ownerOid;

    private String text;

    public RObjectTextInfo() {
    }

    public RObjectTextInfo(RObject owner, String text) {
        this.owner = owner;
        this.text = text;
    }

    @ForeignKey(name = "fk_object_text_info_owner")
    @MapsId("owner")
    @ManyToOne(fetch = FetchType.LAZY)
    @NotQueryable
    public RObject getOwner() {
        return owner;
    }

    @Id
    @Column(name = COLUMN_OWNER_OID, length = RUtil.COLUMN_LENGTH_OID)
    @NotQueryable
    public String getOwnerOid() {
        if (ownerOid == null && owner != null) {
            ownerOid = owner.getOid();
        }
        return ownerOid;
    }

    public void setOwner(RObject owner) {
        this.owner = owner;
    }

    public void setOwnerOid(String ownerOid) {
        this.ownerOid = ownerOid;
    }

    @Id
    @Column(name = "text", length = MAX_TEXT_SIZE)
    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (!(o instanceof RObjectTextInfo))
            return false;
        RObjectTextInfo that = (RObjectTextInfo) o;
        return Objects.equals(getOwnerOid(), that.getOwnerOid()) && Objects.equals(getText(), that.getText());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getOwnerOid(), getText());
    }

    public static <T extends ObjectType> Set<RObjectTextInfo> createItemsSet(@NotNull ObjectType object,
            @NotNull RObject repo, @NotNull RepositoryContext repositoryContext) {

        FullTextSearchConfigurationType config = repositoryContext.repositoryService
                .getFullTextSearchConfiguration();
        if (!FullTextSearchConfigurationUtil.isEnabled(config)) {
            return Collections.emptySet();
        }
        Set<ItemPath> paths = FullTextSearchConfigurationUtil.getFullTextSearchItemPaths(config, object.getClass());

        List<PrismValue> values = new ArrayList<>();
        for (ItemPath path : paths) {
            Object o = object.asPrismObject().find(path);
            if (o == null) {
                // shouldn't occur
            } else if (o instanceof PrismValue) {
                values.add((PrismValue) o);
            } else if (o instanceof Item) {
                values.addAll(((Item<?, ?>) o).getValues());
            } else {
                throw new IllegalStateException("Unexpected value " + o + " in " + object + " at " + path);
            }
        }

        List<String> allWords = new ArrayList<>(); // not a (hash) set in order to preserve order
        for (PrismValue value : values) {
            if (value == null) {
                continue;
            }
            if (value instanceof PrismPropertyValue) {
                Object realValue = value.getRealValue();
                if (realValue == null) {
                    // skip
                } else if (realValue instanceof String) {
                    append(allWords, (String) realValue, repositoryContext.prismContext);
                } else if (realValue instanceof PolyString) {
                    append(allWords, (PolyString) realValue, repositoryContext.prismContext);
                } else {
                    append(allWords, realValue.toString(), repositoryContext.prismContext);
                }
            }
        }
        LOGGER.trace("Indexing {}:\n  items: {}\n  values: {}\n  words:  {}", object, paths, values, allWords);
        return createItemsSet(repo, allWords);
    }

    private static Set<RObjectTextInfo> createItemsSet(RObject repo, List<String> allWords) {
        Set<RObjectTextInfo> rv = new HashSet<>();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < allWords.size(); i++) {
            String word = allWords.get(i);
            if (sb.length() + word.length() + 2 <= MAX_TEXT_SIZE) {
                sb.append(" ").append(word);
            } else {
                if (sb.length() > 0) {
                    sb.append(" ");
                    rv.add(new RObjectTextInfo(repo, sb.toString()));
                    sb = new StringBuilder();
                    i--; // to reiterate
                } else {
                    // a problem - too large string
                    LOGGER.warn("Word too long to be correctly indexed: {}", word);
                    rv.add(new RObjectTextInfo(repo, " " + word.substring(0, MAX_TEXT_SIZE - 2) + " "));
                    allWords.set(i, word.substring(MAX_TEXT_SIZE - 2));
                    i--; // to reiterate (with shortened word)
                }
            }
        }
        if (sb.length() > 0) {
            sb.append(" ");
            rv.add(new RObjectTextInfo(repo, sb.toString()));
        }
        return rv;
    }

    private static void append(List<String> allWords, String text, PrismContext prismContext) {
        if (StringUtils.isBlank(text)) {
            return;
        }
        String normalized = prismContext.getDefaultPolyStringNormalizer().normalize(text);
        String[] words = StringUtils.split(normalized);
        for (String word : words) {
            if (StringUtils.isNotBlank(word)) {
                if (!allWords.contains(word)) {
                    allWords.add(word);
                }
            }
        }
    }

    private static void append(List<String> allWords, PolyString text, PrismContext prismContext) {
        if (text != null) {
            append(allWords, text.getOrig(), prismContext);
        }
    }

    @Override
    public String toString() {
        return "RObjectTextInfo{" + "ownerOid='" + getOwnerOid() + '\'' + ", text='" + text + '\'' + '}';
    }
}