1497eb8c9SChris Fraire /* 2497eb8c9SChris Fraire * CDDL HEADER START 3497eb8c9SChris Fraire * 4497eb8c9SChris Fraire * The contents of this file are subject to the terms of the 5497eb8c9SChris Fraire * Common Development and Distribution License (the "License"). 6497eb8c9SChris Fraire * You may not use this file except in compliance with the License. 7497eb8c9SChris Fraire * 8497eb8c9SChris Fraire * See LICENSE.txt included in this distribution for the specific 9497eb8c9SChris Fraire * language governing permissions and limitations under the License. 10497eb8c9SChris Fraire * 11497eb8c9SChris Fraire * When distributing Covered Code, include this CDDL HEADER in each 12497eb8c9SChris Fraire * file and include the License file at LICENSE.txt. 13497eb8c9SChris Fraire * If applicable, add the following below this CDDL HEADER, with the 14497eb8c9SChris Fraire * fields enclosed by brackets "[]" replaced with your own identifying 15497eb8c9SChris Fraire * information: Portions Copyright [yyyy] [name of copyright owner] 16497eb8c9SChris Fraire * 17497eb8c9SChris Fraire * CDDL HEADER END 18497eb8c9SChris Fraire */ 19497eb8c9SChris Fraire 20497eb8c9SChris Fraire /* 21497eb8c9SChris Fraire * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. 22*5d9f3aa0SAdam Hornáček * Portions Copyright (c) 2011, Jens Elkner. 23*5d9f3aa0SAdam Hornáček * Portions Copyright (c) 2017, 2019, Chris Fraire <cfraire@me.com>. 24497eb8c9SChris Fraire */ 25497eb8c9SChris Fraire package org.opengrok.indexer.search; 26497eb8c9SChris Fraire 27497eb8c9SChris Fraire import org.apache.lucene.index.IndexReader; 28497eb8c9SChris Fraire import org.opengrok.indexer.configuration.Project; 29497eb8c9SChris Fraire import org.opengrok.indexer.index.IndexAnalysisSettings3; 30497eb8c9SChris Fraire import org.opengrok.indexer.index.IndexAnalysisSettingsAccessor; 31497eb8c9SChris Fraire import org.opengrok.indexer.index.IndexedSymlink; 32497eb8c9SChris Fraire 33497eb8c9SChris Fraire import java.io.IOException; 34497eb8c9SChris Fraire import java.util.Collections; 35497eb8c9SChris Fraire import java.util.Comparator; 36497eb8c9SChris Fraire import java.util.HashMap; 37497eb8c9SChris Fraire import java.util.Map; 38497eb8c9SChris Fraire import java.util.TreeMap; 39497eb8c9SChris Fraire 40497eb8c9SChris Fraire /** 41497eb8c9SChris Fraire * Represents a helper class for accessing settings. 42497eb8c9SChris Fraire * @author Jens Elkner 43497eb8c9SChris Fraire */ 44497eb8c9SChris Fraire public class SettingsHelper { 45497eb8c9SChris Fraire 46497eb8c9SChris Fraire private final IndexReader reader; 47497eb8c9SChris Fraire 48497eb8c9SChris Fraire /** 49497eb8c9SChris Fraire * Key is Project name or empty string for null Project. 50497eb8c9SChris Fraire */ 51497eb8c9SChris Fraire private Map<String, IndexAnalysisSettings3> mappedAnalysisSettings; 52497eb8c9SChris Fraire 53497eb8c9SChris Fraire /** 54497eb8c9SChris Fraire * Key is Project name or empty string for null Project. Map is ordered by 55497eb8c9SChris Fraire * canonical length (ASC) and then canonical value (ASC). 56497eb8c9SChris Fraire */ 57497eb8c9SChris Fraire private Map<String, Map<String, IndexedSymlink>> mappedIndexedSymlinks; 58497eb8c9SChris Fraire SettingsHelper(IndexReader reader)59497eb8c9SChris Fraire public SettingsHelper(IndexReader reader) { 60497eb8c9SChris Fraire if (reader == null) { 61497eb8c9SChris Fraire throw new IllegalArgumentException("reader is null"); 62497eb8c9SChris Fraire } 63497eb8c9SChris Fraire this.reader = reader; 64497eb8c9SChris Fraire } 65497eb8c9SChris Fraire 66497eb8c9SChris Fraire /** 67497eb8c9SChris Fraire * Gets any mapped symlinks (after having called {@link #getSettings(String)}). 68497eb8c9SChris Fraire * @return either a defined map or {@code null} 69497eb8c9SChris Fraire */ getSymlinks(String projectName)70135114a6SChris Fraire public Map<String, IndexedSymlink> getSymlinks(String projectName) throws IOException { 71135114a6SChris Fraire getSettings(projectName); 72135114a6SChris Fraire String projectKey = projectName != null ? projectName : ""; 73135114a6SChris Fraire Map<String, IndexedSymlink> indexSymlinks = mappedIndexedSymlinks.get(projectKey); 74497eb8c9SChris Fraire if (indexSymlinks != null) { 75497eb8c9SChris Fraire return Collections.unmodifiableMap(indexSymlinks); 76497eb8c9SChris Fraire } 77497eb8c9SChris Fraire return null; 78497eb8c9SChris Fraire } 79497eb8c9SChris Fraire 80497eb8c9SChris Fraire /** 81497eb8c9SChris Fraire * Gets the persisted tabSize via {@link #getSettings(String)} if 82497eb8c9SChris Fraire * available or returns the {@code proj} tabSize if available -- or zero. 83497eb8c9SChris Fraire * @param proj a defined instance or {@code null} if no project is active 84497eb8c9SChris Fraire * @return tabSize 85497eb8c9SChris Fraire * @throws IOException if an I/O error occurs querying the initialized 86497eb8c9SChris Fraire * reader 87497eb8c9SChris Fraire */ getTabSize(Project proj)88497eb8c9SChris Fraire public int getTabSize(Project proj) throws IOException { 89497eb8c9SChris Fraire String projectName = proj != null ? proj.getName() : null; 90497eb8c9SChris Fraire IndexAnalysisSettings3 settings = getSettings(projectName); 91497eb8c9SChris Fraire int tabSize; 92497eb8c9SChris Fraire if (settings != null && settings.getTabSize() != null) { 93497eb8c9SChris Fraire tabSize = settings.getTabSize(); 94497eb8c9SChris Fraire } else { 95497eb8c9SChris Fraire tabSize = proj != null ? proj.getTabSize() : 0; 96497eb8c9SChris Fraire } 97497eb8c9SChris Fraire return tabSize; 98497eb8c9SChris Fraire } 99497eb8c9SChris Fraire 100497eb8c9SChris Fraire /** 101497eb8c9SChris Fraire * Gets the settings for a specified project. 102497eb8c9SChris Fraire * @param projectName a defined instance or {@code null} if no project is 103497eb8c9SChris Fraire * active (or empty string to mean the same thing) 104497eb8c9SChris Fraire * @return a defined instance or {@code null} if none is found 105497eb8c9SChris Fraire * @throws IOException if an I/O error occurs querying the initialized reader 106497eb8c9SChris Fraire */ getSettings(String projectName)107497eb8c9SChris Fraire public IndexAnalysisSettings3 getSettings(String projectName) throws IOException { 108497eb8c9SChris Fraire if (mappedAnalysisSettings == null) { 109497eb8c9SChris Fraire IndexAnalysisSettingsAccessor dao = new IndexAnalysisSettingsAccessor(); 110497eb8c9SChris Fraire IndexAnalysisSettings3[] setts = dao.read(reader, Short.MAX_VALUE); 111497eb8c9SChris Fraire map(setts); 112497eb8c9SChris Fraire } 113497eb8c9SChris Fraire 114135114a6SChris Fraire String projectKey = projectName != null ? projectName : ""; 115135114a6SChris Fraire return mappedAnalysisSettings.get(projectKey); 116497eb8c9SChris Fraire } 117497eb8c9SChris Fraire map(IndexAnalysisSettings3[] setts)118497eb8c9SChris Fraire private void map(IndexAnalysisSettings3[] setts) { 119497eb8c9SChris Fraire 120497eb8c9SChris Fraire Map<String, IndexAnalysisSettings3> settingsMap = new HashMap<>(); 121497eb8c9SChris Fraire Map<String, Map<String, IndexedSymlink>> symlinksMap = new HashMap<>(); 122497eb8c9SChris Fraire 123497eb8c9SChris Fraire for (IndexAnalysisSettings3 settings : setts) { 124497eb8c9SChris Fraire String projectName = settings.getProjectName(); 125135114a6SChris Fraire String projectKey = projectName != null ? projectName : ""; 126135114a6SChris Fraire settingsMap.put(projectKey, settings); 127135114a6SChris Fraire symlinksMap.put(projectKey, mapSymlinks(settings)); 128497eb8c9SChris Fraire } 129497eb8c9SChris Fraire mappedAnalysisSettings = settingsMap; 130497eb8c9SChris Fraire mappedIndexedSymlinks = symlinksMap; 131497eb8c9SChris Fraire } 132497eb8c9SChris Fraire mapSymlinks(IndexAnalysisSettings3 settings)133497eb8c9SChris Fraire private Map<String, IndexedSymlink> mapSymlinks(IndexAnalysisSettings3 settings) { 134497eb8c9SChris Fraire 135497eb8c9SChris Fraire Map<String, IndexedSymlink> res = new TreeMap<>( 136497eb8c9SChris Fraire Comparator.comparingInt(String::length).thenComparing(o -> o)); 137497eb8c9SChris Fraire for (IndexedSymlink entry : settings.getIndexedSymlinks().values()) { 138497eb8c9SChris Fraire res.put(entry.getCanonical(), entry); 139497eb8c9SChris Fraire } 140497eb8c9SChris Fraire return res; 141497eb8c9SChris Fraire } 142497eb8c9SChris Fraire } 143