xref: /OpenGrok/opengrok-indexer/src/main/java/org/opengrok/indexer/search/SettingsHelper.java (revision 5d9f3aa0ca3da3a714233f987fa732f62c0965f6)
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