xref: /OpenGrok/opengrok-indexer/src/main/java/org/opengrok/indexer/search/SettingsHelper.java (revision 5d9f3aa0ca3da3a714233f987fa732f62c0965f6)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * See LICENSE.txt included in this distribution for the specific
9  * language governing permissions and limitations under the License.
10  *
11  * When distributing Covered Code, include this CDDL HEADER in each
12  * file and include the License file at LICENSE.txt.
13  * If applicable, add the following below this CDDL HEADER, with the
14  * fields enclosed by brackets "[]" replaced with your own identifying
15  * information: Portions Copyright [yyyy] [name of copyright owner]
16  *
17  * CDDL HEADER END
18  */
19 
20 /*
21  * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
22  * Portions Copyright (c) 2011, Jens Elkner.
23  * Portions Copyright (c) 2017, 2019, Chris Fraire <cfraire@me.com>.
24  */
25 package org.opengrok.indexer.search;
26 
27 import org.apache.lucene.index.IndexReader;
28 import org.opengrok.indexer.configuration.Project;
29 import org.opengrok.indexer.index.IndexAnalysisSettings3;
30 import org.opengrok.indexer.index.IndexAnalysisSettingsAccessor;
31 import org.opengrok.indexer.index.IndexedSymlink;
32 
33 import java.io.IOException;
34 import java.util.Collections;
35 import java.util.Comparator;
36 import java.util.HashMap;
37 import java.util.Map;
38 import java.util.TreeMap;
39 
40 /**
41  * Represents a helper class for accessing settings.
42  * @author Jens Elkner
43  */
44 public class SettingsHelper {
45 
46     private final IndexReader reader;
47 
48     /**
49      * Key is Project name or empty string for null Project.
50      */
51     private Map<String, IndexAnalysisSettings3> mappedAnalysisSettings;
52 
53     /**
54      * Key is Project name or empty string for null Project. Map is ordered by
55      * canonical length (ASC) and then canonical value (ASC).
56      */
57     private Map<String, Map<String, IndexedSymlink>> mappedIndexedSymlinks;
58 
SettingsHelper(IndexReader reader)59     public SettingsHelper(IndexReader reader) {
60         if (reader == null) {
61             throw new IllegalArgumentException("reader is null");
62         }
63         this.reader = reader;
64     }
65 
66     /**
67      * Gets any mapped symlinks (after having called {@link #getSettings(String)}).
68      * @return either a defined map or {@code null}
69      */
getSymlinks(String projectName)70     public Map<String, IndexedSymlink> getSymlinks(String projectName) throws IOException {
71         getSettings(projectName);
72         String projectKey = projectName != null ? projectName : "";
73         Map<String, IndexedSymlink> indexSymlinks = mappedIndexedSymlinks.get(projectKey);
74         if (indexSymlinks != null) {
75             return Collections.unmodifiableMap(indexSymlinks);
76         }
77         return null;
78     }
79 
80     /**
81      * Gets the persisted tabSize via {@link #getSettings(String)} if
82      * available or returns the {@code proj} tabSize if available -- or zero.
83      * @param proj a defined instance or {@code null} if no project is active
84      * @return tabSize
85      * @throws IOException if an I/O error occurs querying the initialized
86      * reader
87      */
getTabSize(Project proj)88     public int getTabSize(Project proj) throws IOException {
89         String projectName = proj != null ? proj.getName() : null;
90         IndexAnalysisSettings3 settings = getSettings(projectName);
91         int tabSize;
92         if (settings != null && settings.getTabSize() != null) {
93             tabSize = settings.getTabSize();
94         } else {
95             tabSize = proj != null ? proj.getTabSize() : 0;
96         }
97         return tabSize;
98     }
99 
100     /**
101      * Gets the settings for a specified project.
102      * @param projectName a defined instance or {@code null} if no project is
103      * active (or empty string to mean the same thing)
104      * @return a defined instance or {@code null} if none is found
105      * @throws IOException if an I/O error occurs querying the initialized reader
106      */
getSettings(String projectName)107     public IndexAnalysisSettings3 getSettings(String projectName) throws IOException {
108         if (mappedAnalysisSettings == null) {
109             IndexAnalysisSettingsAccessor dao = new IndexAnalysisSettingsAccessor();
110             IndexAnalysisSettings3[] setts = dao.read(reader, Short.MAX_VALUE);
111             map(setts);
112         }
113 
114         String projectKey = projectName != null ? projectName : "";
115         return mappedAnalysisSettings.get(projectKey);
116     }
117 
map(IndexAnalysisSettings3[] setts)118     private void map(IndexAnalysisSettings3[] setts) {
119 
120         Map<String, IndexAnalysisSettings3> settingsMap = new HashMap<>();
121         Map<String, Map<String, IndexedSymlink>> symlinksMap = new HashMap<>();
122 
123         for (IndexAnalysisSettings3 settings : setts) {
124             String projectName = settings.getProjectName();
125             String projectKey = projectName != null ? projectName : "";
126             settingsMap.put(projectKey, settings);
127             symlinksMap.put(projectKey, mapSymlinks(settings));
128         }
129         mappedAnalysisSettings = settingsMap;
130         mappedIndexedSymlinks = symlinksMap;
131     }
132 
mapSymlinks(IndexAnalysisSettings3 settings)133     private Map<String, IndexedSymlink> mapSymlinks(IndexAnalysisSettings3 settings) {
134 
135         Map<String, IndexedSymlink> res = new TreeMap<>(
136                 Comparator.comparingInt(String::length).thenComparing(o -> o));
137         for (IndexedSymlink entry : settings.getIndexedSymlinks().values()) {
138             res.put(entry.getCanonical(), entry);
139         }
140         return res;
141     }
142 }
143