xref: /OpenGrok/opengrok-indexer/src/main/java/org/opengrok/indexer/index/IndexAnalysisSettings.java (revision e779faac6ac01c406f41e81a4354cd6ed590f968)
1b5840353SAdam Hornáček /*
2b5840353SAdam Hornáček  * CDDL HEADER START
3b5840353SAdam Hornáček  *
4b5840353SAdam Hornáček  * The contents of this file are subject to the terms of the
5b5840353SAdam Hornáček  * Common Development and Distribution License (the "License").
6b5840353SAdam Hornáček  * You may not use this file except in compliance with the License.
7b5840353SAdam Hornáček  *
8b5840353SAdam Hornáček  * See LICENSE.txt included in this distribution for the specific
9b5840353SAdam Hornáček  * language governing permissions and limitations under the License.
10b5840353SAdam Hornáček  *
11b5840353SAdam Hornáček  * When distributing Covered Code, include this CDDL HEADER in each
12b5840353SAdam Hornáček  * file and include the License file at LICENSE.txt.
13b5840353SAdam Hornáček  * If applicable, add the following below this CDDL HEADER, with the
14b5840353SAdam Hornáček  * fields enclosed by brackets "[]" replaced with your own identifying
15b5840353SAdam Hornáček  * information: Portions Copyright [yyyy] [name of copyright owner]
16b5840353SAdam Hornáček  *
17b5840353SAdam Hornáček  * CDDL HEADER END
18b5840353SAdam Hornáček  */
19b5840353SAdam Hornáček 
20b5840353SAdam Hornáček /*
21b5840353SAdam Hornáček  * Copyright (c) 2018, Chris Fraire <cfraire@me.com>.
22b5840353SAdam Hornáček  */
239805b761SAdam Hornáček package org.opengrok.indexer.index;
24b5840353SAdam Hornáček 
25*e779faacSAdam Hornacek import org.opengrok.indexer.util.WhitelistObjectInputFilter;
26*e779faacSAdam Hornacek 
27b5840353SAdam Hornáček import java.io.ByteArrayInputStream;
28b5840353SAdam Hornáček import java.io.ByteArrayOutputStream;
29b5840353SAdam Hornáček import java.io.IOException;
30*e779faacSAdam Hornacek import java.io.ObjectInputFilter;
31b5840353SAdam Hornáček import java.io.ObjectInputStream;
32b5840353SAdam Hornáček import java.io.ObjectOutputStream;
33b5840353SAdam Hornáček import java.io.Serializable;
3491f8f84fSVladimir Kotal import java.util.Collections;
3591f8f84fSVladimir Kotal import java.util.HashMap;
3691f8f84fSVladimir Kotal import java.util.Map;
37b5840353SAdam Hornáček 
38b5840353SAdam Hornáček /**
39b5840353SAdam Hornáček  * Represents a serializable gathering of some top-level metadata concerning the
40b5840353SAdam Hornáček  * operation of {@link IndexDatabase} -- and persisted therein too -- which are
41b5840353SAdam Hornáček  * re-compared upon each indexing run since changes to them might require
42b5840353SAdam Hornáček  * re-indexing particular files or in certain cases all files.
43b5840353SAdam Hornáček  */
44b5840353SAdam Hornáček public final class IndexAnalysisSettings implements Serializable {
45b5840353SAdam Hornáček 
4691f8f84fSVladimir Kotal     private static final long serialVersionUID = 1172403004716059609L;
47b5840353SAdam Hornáček 
48*e779faacSAdam Hornacek     private static final ObjectInputFilter serialFilter = new WhitelistObjectInputFilter(IndexAnalysisSettings.class);
49*e779faacSAdam Hornacek 
50b5840353SAdam Hornáček     private String projectName;
51b5840353SAdam Hornáček 
52b5840353SAdam Hornáček     /**
53ff44f24aSAdam Hornáček      * Nullable to allow easing this object into existing OpenGrok indexes
54ff44f24aSAdam Hornáček      * without forcing a re-indexing.
55b5840353SAdam Hornáček      * @serial
56b5840353SAdam Hornáček      */
57b5840353SAdam Hornáček     private Integer tabSize;
58b5840353SAdam Hornáček 
59b5840353SAdam Hornáček     /**
60ff44f24aSAdam Hornáček      * Nullable to allow easing this object into existing OpenGrok indexes
61ff44f24aSAdam Hornáček      * without forcing a re-indexing.
62b5840353SAdam Hornáček      * @serial
63b5840353SAdam Hornáček      */
64b5840353SAdam Hornáček     private Long analyzerGuruVersion;
65b5840353SAdam Hornáček 
66b5840353SAdam Hornáček     /**
67ff44f24aSAdam Hornáček      * Nullable because otherwise custom de-serialization does not work, as a
6891f8f84fSVladimir Kotal      * {@code final} initialized value may not actually happen because Java
69ff44f24aSAdam Hornáček      * de-serialization circumvents normal construction.
7091f8f84fSVladimir Kotal      * @serial
7191f8f84fSVladimir Kotal      */
7291f8f84fSVladimir Kotal     private Map<String, Long> analyzersVersions = new HashMap<>();
7391f8f84fSVladimir Kotal 
7491f8f84fSVladimir Kotal     /**
75b5840353SAdam Hornáček      * Gets the project name to be used to distinguish different instances of
76b5840353SAdam Hornáček      * {@link IndexAnalysisSettings} that might be returned by a Lucene
77b5840353SAdam Hornáček      * {@code MultiReader} search across projects.
78b5840353SAdam Hornáček      * @return projectName
79b5840353SAdam Hornáček      */
getProjectName()80b5840353SAdam Hornáček     public String getProjectName() {
81b5840353SAdam Hornáček         return projectName;
82b5840353SAdam Hornáček     }
83b5840353SAdam Hornáček 
84b5840353SAdam Hornáček     /**
85b5840353SAdam Hornáček      * Sets the project name to be used to distinguish different instances of
86b5840353SAdam Hornáček      * {@link IndexAnalysisSettings} that might be returned by a Lucene
87b5840353SAdam Hornáček      * {@code MultiReader} search across projects.
8881b586e6SVladimir Kotal      * @param value project name
89b5840353SAdam Hornáček      */
setProjectName(String value)90b5840353SAdam Hornáček     public void setProjectName(String value) {
91b5840353SAdam Hornáček         this.projectName = value;
92b5840353SAdam Hornáček     }
93b5840353SAdam Hornáček 
getTabSize()94b5840353SAdam Hornáček     public Integer getTabSize() {
95b5840353SAdam Hornáček         return tabSize;
96b5840353SAdam Hornáček     }
97b5840353SAdam Hornáček 
setTabSize(Integer value)98b5840353SAdam Hornáček     public void setTabSize(Integer value) {
99b5840353SAdam Hornáček         this.tabSize = value;
100b5840353SAdam Hornáček     }
101b5840353SAdam Hornáček 
getAnalyzerGuruVersion()102b5840353SAdam Hornáček     public Long getAnalyzerGuruVersion() {
103b5840353SAdam Hornáček         return analyzerGuruVersion;
104b5840353SAdam Hornáček     }
105b5840353SAdam Hornáček 
setAnalyzerGuruVersion(Long value)106b5840353SAdam Hornáček     public void setAnalyzerGuruVersion(Long value) {
107b5840353SAdam Hornáček         this.analyzerGuruVersion = value;
108b5840353SAdam Hornáček     }
109b5840353SAdam Hornáček 
110b5840353SAdam Hornáček     /**
111ff44f24aSAdam Hornáček      * Gets the version number for the specified file type name if it exists.
11281b586e6SVladimir Kotal      * @param fileTypeName name of the file type
11391f8f84fSVladimir Kotal      * @return a defined value or {@code null} if unknown
11491f8f84fSVladimir Kotal      */
getAnalyzerVersion(String fileTypeName)11591f8f84fSVladimir Kotal     public Long getAnalyzerVersion(String fileTypeName) {
11691f8f84fSVladimir Kotal         return analyzersVersions.get(fileTypeName);
11791f8f84fSVladimir Kotal     }
11891f8f84fSVladimir Kotal 
11991f8f84fSVladimir Kotal     /**
12091f8f84fSVladimir Kotal      * Gets an unmodifiable view of the map of file type names to version
12191f8f84fSVladimir Kotal      * numbers.
12291f8f84fSVladimir Kotal      * @return a defined instance
12391f8f84fSVladimir Kotal      */
getAnalyzersVersions()12491f8f84fSVladimir Kotal     public Map<String, Long> getAnalyzersVersions() {
12591f8f84fSVladimir Kotal         return Collections.unmodifiableMap(analyzersVersions);
12691f8f84fSVladimir Kotal     }
12791f8f84fSVladimir Kotal 
12891f8f84fSVladimir Kotal     /**
12991f8f84fSVladimir Kotal      * Replaces the contents of the instance's map with the {@code values}.
13091f8f84fSVladimir Kotal      * @param values a defined instance
13191f8f84fSVladimir Kotal      */
setAnalyzersVersions(Map<String, Long> values)13291f8f84fSVladimir Kotal     public void setAnalyzersVersions(Map<String, Long> values) {
13391f8f84fSVladimir Kotal         analyzersVersions.clear();
13491f8f84fSVladimir Kotal         analyzersVersions.putAll(values);
13591f8f84fSVladimir Kotal     }
13691f8f84fSVladimir Kotal 
13791f8f84fSVladimir Kotal     /**
138b5840353SAdam Hornáček      * Creates a binary representation of this object.
139b5840353SAdam Hornáček      * @return a byte array representing this object
140b5840353SAdam Hornáček      * @throws  IOException Any exception thrown by the underlying
141b5840353SAdam Hornáček      * OutputStream.
142b5840353SAdam Hornáček      */
serialize()143b5840353SAdam Hornáček     public byte[] serialize() throws IOException {
144*e779faacSAdam Hornacek         try (ByteArrayOutputStream bytes = new ByteArrayOutputStream(); var oos = new ObjectOutputStream(bytes)) {
145*e779faacSAdam Hornacek             oos.writeObject(this);
146b5840353SAdam Hornáček             return bytes.toByteArray();
147b5840353SAdam Hornáček         }
148*e779faacSAdam Hornacek     }
149b5840353SAdam Hornáček 
150b5840353SAdam Hornáček     /**
151b5840353SAdam Hornáček      * De-serializes a binary representation of an {@link IndexAnalysisSettings}
152b5840353SAdam Hornáček      * object.
153b5840353SAdam Hornáček      * @param bytes a byte array containing the serialization
154b5840353SAdam Hornáček      * @return a defined instance
155b5840353SAdam Hornáček      * @throws IOException Any of the usual Input/Output related exceptions.
156b5840353SAdam Hornáček      * @throws ClassNotFoundException Class of a serialized object cannot be
157b5840353SAdam Hornáček      * found.
158b5840353SAdam Hornáček      * @throws ClassCastException if the array contains an object of another
159b5840353SAdam Hornáček      * type than {@code IndexAnalysisSettings}
160b5840353SAdam Hornáček      */
deserialize(byte[] bytes)161*e779faacSAdam Hornacek     public static IndexAnalysisSettings deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
162*e779faacSAdam Hornacek         try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
163*e779faacSAdam Hornacek             in.setObjectInputFilter(serialFilter);
164b5840353SAdam Hornáček             return (IndexAnalysisSettings) in.readObject();
165b5840353SAdam Hornáček         }
166*e779faacSAdam Hornacek     }
167b5840353SAdam Hornáček 
readObject(ObjectInputStream in)168b5840353SAdam Hornáček     private void readObject(ObjectInputStream in) throws ClassNotFoundException,
169b5840353SAdam Hornáček             IOException {
170b5840353SAdam Hornáček 
171b5840353SAdam Hornáček         boolean hasValue = in.readBoolean();
172b5840353SAdam Hornáček         String vstring = in.readUTF();
173b5840353SAdam Hornáček         projectName = hasValue ? vstring : null;
174b5840353SAdam Hornáček 
175b5840353SAdam Hornáček         hasValue = in.readBoolean();
176b5840353SAdam Hornáček         int vint = in.readInt();
177b5840353SAdam Hornáček         tabSize = hasValue ? vint : null;
178b5840353SAdam Hornáček 
179b5840353SAdam Hornáček         hasValue = in.readBoolean();
180b5840353SAdam Hornáček         long vlong = in.readLong();
181b5840353SAdam Hornáček         analyzerGuruVersion = hasValue ? vlong : null;
18291f8f84fSVladimir Kotal 
18391f8f84fSVladimir Kotal         /**
18491f8f84fSVladimir Kotal          * De-serialization circumvents normal construction, so the following
18591f8f84fSVladimir Kotal          * field could be null.
18691f8f84fSVladimir Kotal          */
18791f8f84fSVladimir Kotal         if (analyzersVersions == null) {
18891f8f84fSVladimir Kotal             analyzersVersions = new HashMap<>();
18991f8f84fSVladimir Kotal         }
19091f8f84fSVladimir Kotal         int analyzerCount = in.readInt();
19191f8f84fSVladimir Kotal         for (int i = 0; i < analyzerCount; ++i) {
19291f8f84fSVladimir Kotal             vstring = in.readUTF();
19391f8f84fSVladimir Kotal             vlong = in.readLong();
19491f8f84fSVladimir Kotal             analyzersVersions.put(vstring, vlong);
19591f8f84fSVladimir Kotal         }
196b5840353SAdam Hornáček     }
197b5840353SAdam Hornáček 
writeObject(ObjectOutputStream out)198b5840353SAdam Hornáček     private void writeObject(ObjectOutputStream out) throws IOException {
199b5840353SAdam Hornáček         out.writeBoolean(projectName != null); // hasValue
200b5840353SAdam Hornáček         out.writeUTF(projectName == null ? "" : projectName);
201b5840353SAdam Hornáček 
202b5840353SAdam Hornáček         out.writeBoolean(tabSize != null); // hasValue
203b5840353SAdam Hornáček         out.writeInt(tabSize == null ? 0 : tabSize);
204b5840353SAdam Hornáček 
205b5840353SAdam Hornáček         out.writeBoolean(analyzerGuruVersion != null); // hasValue
206b5840353SAdam Hornáček         out.writeLong(analyzerGuruVersion == null ? 0 : analyzerGuruVersion);
20791f8f84fSVladimir Kotal 
20891f8f84fSVladimir Kotal         int analyzerCount = analyzersVersions.size();
20991f8f84fSVladimir Kotal         out.writeInt(analyzerCount);
21091f8f84fSVladimir Kotal         for (Map.Entry<String, Long> entry : analyzersVersions.entrySet()) {
21191f8f84fSVladimir Kotal             out.writeUTF(entry.getKey());
21291f8f84fSVladimir Kotal             out.writeLong(entry.getValue());
21391f8f84fSVladimir Kotal             --analyzerCount;
21491f8f84fSVladimir Kotal         }
21591f8f84fSVladimir Kotal         if (analyzerCount != 0) {
21691f8f84fSVladimir Kotal             throw new IllegalStateException("analyzersVersions were modified");
21791f8f84fSVladimir Kotal         }
218b5840353SAdam Hornáček     }
219b5840353SAdam Hornáček }
220