All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.nemerosa.ontrack.boot.ProjectSearchProvider.kt Maven / Gradle / Ivy

There is a newer version: 4.4.5
Show newest version
package net.nemerosa.ontrack.boot

import com.fasterxml.jackson.databind.JsonNode
import net.nemerosa.ontrack.model.events.Event
import net.nemerosa.ontrack.model.events.EventFactory
import net.nemerosa.ontrack.model.events.EventListener
import net.nemerosa.ontrack.model.structure.*
import net.nemerosa.ontrack.ui.controller.URIBuilder
import org.springframework.stereotype.Component

/**
 * Minimum length of a token to compare with project names by content.
 */
const val PROJECT_SEARCH_PROVIDER_TOKEN_MIN_LENGTH = 3

/**
 * Projects search index name
 */
const val PROJECT_SEARCH_INDEX = "projects"

/**
 * Search result type
 */
const val PROJECT_SEARCH_RESULT_TYPE = "project"

/**
 * Matches against projects either by name or by content if the
 * search token is at least [PROJECT_SEARCH_PROVIDER_TOKEN_MIN_LENGTH] characters long.
 */
@Component
class ProjectSearchProvider(
        private val uriBuilder: URIBuilder,
        private val structureService: StructureService,
        private val searchIndexService: SearchIndexService
) : SearchIndexer, EventListener {

    override val searchResultType = SearchResultType(
            feature = CoreExtensionFeature.INSTANCE.featureDescription,
            id = PROJECT_SEARCH_RESULT_TYPE,
            name = "Project",
            description = "Project name in Ontrack"
    )

    override val indexerName: String = "Projects"

    override val indexName: String = PROJECT_SEARCH_INDEX

    override val indexMapping: SearchIndexMapping = indexMappings {
        +ProjectSearchItem::name to keyword { scoreBoost = 4.0 } to text { scoreBoost = 3.0 }
        +ProjectSearchItem::description to text()
    }

    override fun indexAll(processor: (ProjectSearchItem) -> Unit) {
        structureService.projectList.forEach { project ->
            processor(project.asSearchItem())
        }
    }

    override fun toSearchResult(id: String, score: Double, source: JsonNode): SearchResult? {
        return structureService.findProjectByID(ID.of(id.toInt()))?.run {
            SearchResult(
                    title = entityDisplayName,
                    description = description ?: "",
                    uri = uriBuilder.getEntityURI(this),
                    page = uriBuilder.getEntityPage(this),
                    accuracy = score,
                    type = searchResultType
            )
        }
    }

    override fun onEvent(event: Event) {
        when (event.eventType) {
            EventFactory.NEW_PROJECT -> {
                val project = event.getEntity(ProjectEntityType.PROJECT)
                searchIndexService.createSearchIndex(this, project.asSearchItem())
            }
            EventFactory.UPDATE_PROJECT -> {
                val project = event.getEntity(ProjectEntityType.PROJECT)
                searchIndexService.updateSearchIndex(this, project.asSearchItem())
            }
            EventFactory.DELETE_PROJECT -> {
                val projectId = event.getIntValue("project_id")
                searchIndexService.deleteSearchIndex(this, projectId)
            }
        }
    }

    private fun Project.asSearchItem() = ProjectSearchItem(this)

}

class ProjectSearchItem(
        override val id: String,
        val name: String,
        val description: String
) : SearchItem {
    constructor(project: Project) : this(
            id = project.id.toString(),
            name = project.name,
            description = project.description ?: ""
    )

    override val fields: Map = mapOf(
            "name" to name,
            "description" to description
    )

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy