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