Java tutorial
/** * This Source Code Form is subject to the terms of the Mozilla Public License, * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. * * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS * graphic logo is a trademark of OpenMRS Inc. */ package com.k_joseph.apps.multisearch.solr; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.io.FileUtils; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.request.CoreAdminRequest; import org.apache.solr.client.solrj.response.CoreAdminResponse; import org.apache.solr.common.params.CoreAdminParams.CoreAdminAction; import org.apache.solr.common.util.NamedList; import com.k_joseph.apps.multisearch.api.MultiSearchService; import com.k_joseph.apps.multisearch.solrServer.EmbeddedSolrServerCreator; /** * Contains all functionalities needed to add an entry of a new field into schema.xml file */ public class AddCustomFieldsToSchema { /** * Generates a field entry to be added to the schema.xml file that looks like: <field * name="cc_filter_query" type="text_general" indexed="true" stored="true" required="false" /> * * @param fieldName, the field name to be added * @param indexed, is the field to be indexed * @param type, the datatype for the field * @param stored, is the field to be stored * @param required, is the field to be required * @return generated field entry */ public static String generateAWellWrittenFieldEntry(List<String> fieldNames, String typeForAllFields, boolean indexedForAllFields, boolean storedForAllFields, boolean requiredForAllFields, MultiSearchService multiSearchService, boolean fieldsExistInSchemaAlready) { String indexedString = "false"; String storedString = "false"; String requiredString = "false"; if (indexedForAllFields) { indexedString = "true"; } if (storedForAllFields) { storedString = "true"; } if (requiredForAllFields) { requiredString = "true"; } String fieldEntry = ""; for (int i = 0; i < fieldNames.size(); i++) { if (!fieldsExistInSchemaAlready && !multiSearchService.getAllFieldsSetInSchemaByDefault().contains(fieldNames.get(i))) { //the two tabs at the start are for proper formatting of the text field after added to the file fieldEntry += "\t\t<field name=\"" + fieldNames.get(i) + "\" type=\"" + typeForAllFields + "\" indexed=\"" + indexedString + "\" stored=\"" + storedString + "\" required=\"" + requiredString + "\" />\n"; } else fieldEntry = null; } return fieldEntry; } /** * Generates copy field entries to be added to schema.xml file, one would look like: <copyField * source="concept_class_name" dest="text" /> * * @return */ public static String generateWellWrittenCopyFieldEntries(List<String> sources, MultiSearchService multiSearchService, boolean copyFieldsExistInSchemaAlready) { //Entry looks like: <copyField source="concept_class_name" dest="text" /> String copyFieldEntries = ""; for (int i = 0; i < sources.size(); i++) { if (!copyFieldsExistInSchemaAlready && !multiSearchService.getAllFieldsSetInSchemaByDefault().contains(sources.get(i))) { copyFieldEntries += "\t<copyField source=\"" + sources.get(i) + "\" dest=\"text\" />\n"; } else copyFieldEntries = null; } return copyFieldEntries; } /** * Reads the schema file line by line and edits it to add a new field entry * * @param schemaFileLocation * @param fieldEntry, the field entry line, use * {@link #generateAWellWrittenFieldEntry(String, String, boolean, boolean, boolean)} * @return new lines of the file in a List */ public static void readSchemaFileLineByLineAndWritNewFieldEntries(String schemaFileLocation, String newSchemaFilePath, String fieldEntry, String copyFieldEntry, SolrServer solrServer) { //reading file line by line in Java using BufferedReader FileInputStream fis = null; BufferedReader reader = null; boolean replacedSchemaWithBackUp = replaceSchemaFileWithItsBackup(schemaFileLocation); if (replacedSchemaWithBackUp) { System.out.println("Successfully replaced the schema.xml file with a previously backed-up copy"); } try { fis = new FileInputStream(schemaFileLocation); reader = new BufferedReader(new InputStreamReader(fis)); System.out.println("Reading " + schemaFileLocation + " file line by line using BufferedReader"); File newSchemaFile = new File(newSchemaFilePath); if (newSchemaFile.exists()) newSchemaFile.delete(); String line = reader.readLine(); while (line != null) { FileWriter fileWritter = new FileWriter(newSchemaFile, true); BufferedWriter bufferWritter = new BufferedWriter(fileWritter); //write to the file from here. if (line.equals("\t\t<!-- Fields from modules and other projects starts here -->")) { bufferWritter.write("\t\t<!-- Fields from modules and other projects starts here -->\n" + fieldEntry + "\n"); bufferWritter.close(); } else if (line.equals("\t<!-- Starting customly added copyfields -->")) { bufferWritter .write("\n\t<!-- Starting customly added copyfields -->\n" + copyFieldEntry + "\n"); bufferWritter.close(); } else { bufferWritter.write(line + "\n"); bufferWritter.close(); } line = reader.readLine(); } } catch (FileNotFoundException ex) { Logger.getLogger(AddCustomFieldsToSchema.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(AddCustomFieldsToSchema.class.getName()).log(Level.SEVERE, null, ex); } finally { try { reader.close(); fis.close(); } catch (IOException ex) { Logger.getLogger(AddCustomFieldsToSchema.class.getName()).log(Level.SEVERE, null, ex); } } copyNewSchemaFileToPreviouslyUsed(schemaFileLocation, newSchemaFilePath); CoreAdminRequest adminRequest = new CoreAdminRequest(); reloadSolrServer(solrServer, adminRequest); } /** * Replace the schema file with a previously backed up copy that contains newly added fields and * copyfields, Invoking this method needs to be followed by * {@link #reloadSolrServer(SolrServer, CoreAdminRequest)} * * @param schemaFileLocation */ public static boolean replaceSchemaFileWithItsBackup(String schemaFileLocation) { String currentBackupSchemaLocation = EmbeddedSolrServerCreator.properties.getSolrHome() + File.separator + "backup" + File.separator + "schema.xml"; boolean replaced = false; File currentBackupSchemaFile = new File(currentBackupSchemaLocation); if (currentBackupSchemaFile.exists()) { try { FileUtils.copyFile(new File(currentBackupSchemaLocation), new File(schemaFileLocation)); replaced = true; } catch (IOException e) { System.out.println("Error generated" + e); } } return replaced; } /** * Used to Reload the SolrServer after changes are made to the schema.xml among other * configuration files * * @param solrServer * @param adminRequest */ public static void reloadSolrServer(SolrServer solrServer, CoreAdminRequest adminRequest) { adminRequest.setAction(CoreAdminAction.RELOAD); CoreAdminResponse adminResponse; try { adminResponse = adminRequest.process(solrServer); @SuppressWarnings("unused") NamedList<NamedList<Object>> coreStatus = adminResponse.getCoreStatus(); } catch (SolrServerException e) { System.out.println("Error generated" + e); } catch (IOException e) { System.out.println("Error generated" + e); } } /** * Overwrites the previous schema file with the newly generated * * @param previousSchema currently used schema file * @param newSchema to be used instead of the previous */ private static void copyNewSchemaFileToPreviouslyUsed(String previousSchema, String newSchema) { File previousSchemaFile = new File(previousSchema); File newSchemaFile = new File(newSchema); if (previousSchemaFile.exists() && newSchemaFile.exists()) { String chartSearchBackUpPath = System.getProperty("user.home") + File.separator + ".multiSearch" + File.separator + "backup"; File chartSearchBackUp = new File(chartSearchBackUpPath); if (!chartSearchBackUp.exists()) { chartSearchBackUp.mkdir(); } previousSchemaFile.delete(); newSchemaFile.renameTo(previousSchemaFile); try { //Backing up the new schema file for easy retrieval after restarting or upgrading the module //TODO support an option clickat the UI where by the user can Reload the solrserver, //this would mean updating the schema file with back-up before the Reloading is done FileUtils.copyFileToDirectory(newSchemaFile, chartSearchBackUp); } catch (IOException e) { System.out.println("Error generated" + e); } } } }