/* * Licensed under the Apache License, Version 2.0 (the "License"); * * You may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * limitations under the License. * * Contributions from 2013-2017 where performed either by US government * employees, or under US Veterans Health Administration contracts. * * US Veterans Health Administration contributions by government employees * are work of the U.S. Government and are not subject to copyright * protection in the United States. Portions contributed by government * employees are USGovWork (17USC ยง105). Not subject to copyright. * * Contribution by contractors to the US Veterans Health Administration * during this period are contractually contributed under the * Apache License, Version 2.0. * * See: https://www.usa.gov/government-works * * Contributions prior to 2013: * * Copyright (C) International Health Terminology Standards Development Organisation. * Licensed under the Apache License, Version 2.0. * */ package sh.isaac.api; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Optional; //~--- non-JDK imports -------------------------------------------------------- import org.apache.commons.lang3.StringUtils; import org.jvnet.hk2.annotations.Contract; import sh.isaac.api.constants.Constants; import sh.isaac.api.observable.coordinate.ObservableEditCoordinate; import sh.isaac.api.observable.coordinate.ObservableLanguageCoordinate; import sh.isaac.api.observable.coordinate.ObservableLogicCoordinate; import sh.isaac.api.observable.coordinate.ObservableStampCoordinate; import sh.isaac.api.observable.coordinate.ObservableTaxonomyCoordinate; //~--- interfaces ------------------------------------------------------------- /** * An interface used for system configuration. Services started by the * {@link LookupService} will utilize an implementation of this service in order * to configure themselves. * * @author <a href="mailto:daniel.armbrust.list@gmail.com">Dan Armbrust</a> */ @Contract public interface ConfigurationService { /** * Enable verbose debug. * * @return true if verbose debug has been enabled. This default implementation allows the * feature to be enabled by setting the system property {@link Constants#ISAAC_DEBUG} to 'true' */ public default boolean enableVerboseDebug() { final String value = System.getProperty(Constants.ISAAC_DEBUG); if (StringUtils.isNotBlank(value)) { return value.trim() .equalsIgnoreCase("true"); } else { return false; } } /** * There are some cases where validators and such cannot be properly executed if we are in bootstrap mode - building * the system for the first time. The default implementation of this returns false. * * @return true, if successful */ public default boolean inBootstrapMode() { return false; } /** * When building a DB, we don't want to index per commit, or write changeset files, among other things. * * Note that this mode can be enabled-only only. If you enable dbBuildMode, the mode cannot be turned off later. * * @return true, if successful */ public default boolean inDBBuildMode() { return false; } //~--- set methods --------------------------------------------------------- /** * See {@link #inBootstrapMode()}. */ public default void setBootstrapMode() { throw new UnsupportedOperationException(); } //~--- get methods --------------------------------------------------------- /** * Gets the chronicle folder path. * * @return The root folder of the database - one would expect to find a * data-store specific folder such as "cradle" inside this folder. The * default implementation returns the result of * {@link #getDataStoreFolderPath()} + {@link Constants#DEFAULT_CHRONICLE_FOLDER} * * The returned path exists on disk at the time that this method returns. */ public default Path getChronicleFolderPath() { Path result; final Optional<Path> rootPath = getDataStoreFolderPath(); if (!rootPath.isPresent()) { throw new IllegalStateException( "The ConfigurationService implementation has not been configured by a call to setDataStoreFolderPath()," + " and the system property " + Constants.DATA_STORE_ROOT_LOCATION_PROPERTY + " has not been set. Cannot construct the chronicle folder path."); } else { result = rootPath.get() .resolve(Constants.DEFAULT_CHRONICLE_FOLDER); } try { Files.createDirectories(result); } catch (final IOException e) { throw new RuntimeException(e); } return result; } //~--- set methods --------------------------------------------------------- /** * See {@link #inDBBuildMode()}. */ public default void setDBBuildMode() { throw new UnsupportedOperationException(); } //~--- get methods --------------------------------------------------------- /** * Gets the data store folder path. * * @return The root folder of the database - the returned path should contain * subfolders of * {@link Constants#DEFAULT_CHRONICLE_FOLDER} and * {@link Constants#DEFAULT_SEARCH_FOLDER}. * * * This method will return (in the following order): * * - The value specified by a call to {@link #setDataStoreFolderPath(Path)} * - a path constructed from the value of * {@link Constants#DATA_STORE_ROOT_LOCATION_PROPERTY} if * {@link #setDataStoreFolderPath(Path)} was never called * - Nothing if * {@link Constants#DATA_STORE_ROOT_LOCATION_PROPERTY} has not been set. * * If a value is returned, the returned path will exist on disk at the time * that this method returns. */ public Optional<Path> getDataStoreFolderPath(); //~--- set methods --------------------------------------------------------- /** * Specify the root folder of the database. The specified folder should * contain subfolders of {@link Constants#DEFAULT_CHRONICLE_FOLDER} and * {@link Constants#DEFAULT_SEARCH_FOLDER}. * * This method can only be utilized prior to the first call to * {@link LookupService#startupIsaac()} * * @param dataStoreFolderPath the new data store folder path * @throws IllegalStateException if this is called after the system has * already started. * @throws IllegalArgumentException if the provided dbFolderPath is an * existing file, rather than a folder. */ public void setDataStoreFolderPath(Path dataStoreFolderPath) throws IllegalStateException, IllegalArgumentException; /** * Sets the default classifier. When changed, other default objects that * reference this object will be updated accordingly. Default: The value to * use if another value is not provided. * * @param conceptId the new default classifier */ void setDefaultClassifier(int conceptId); /** * Sets the default description-logic profile. When changed, other default * objects that reference this object will be updated accordingly. Default: * The value to use if another value is not provided. * * @param conceptId either a nid or conceptSequence */ void setDefaultDescriptionLogicProfile(int conceptId); /** * Sets the default description type preference list for description * retrieval. When changed, other default objects that reference this object * will be updated accordingly. Default: The value to use if another value * is not provided. * * @param descriptionTypePreferenceList prioritized preference list of * description type sequences */ void setDefaultDescriptionTypePreferenceList(int[] descriptionTypePreferenceList); /** * Sets the default dialect preference list for description retrieval. When * changed, other default objects that reference this object will be updated * accordingly. Default: The value to use if another value is not provided. * * @param dialectAssemblagePreferenceList prioritized preference list of * dialect assemblage sequences */ void setDefaultDialectAssemblagePreferenceList(int[] dialectAssemblagePreferenceList); //~--- get methods --------------------------------------------------------- /** * Gets the default edit coordinate. * * @return an {@code ObservableEditCoordinate} based on the configuration * defaults. */ ObservableEditCoordinate getDefaultEditCoordinate(); //~--- set methods --------------------------------------------------------- /** * Sets the default inferred definition assemblage. When changed, other * default objects that reference this object will be updated accordingly. * Default: The value to use if another value is not provided. * * @param conceptId either a nid or conceptSequence */ void setDefaultInferredAssemblage(int conceptId); /** * Sets the default language for description retrieval. When changed, other * default objects that reference this object will be updated accordingly. * Default: The value to use if another value is not provided. * * @param conceptId either a nid or conceptSequence */ void setDefaultLanguage(int conceptId); //~--- get methods --------------------------------------------------------- /** * Gets the default language coordinate. * * @return an {@code ObservableLanguageCoordinate} based on the * configuration defaults. */ ObservableLanguageCoordinate getDefaultLanguageCoordinate(); /** * Gets the default logic coordinate. * * @return an {@code ObservableLogicCoordinate} based on the configuration * defaults. */ ObservableLogicCoordinate getDefaultLogicCoordinate(); //~--- set methods --------------------------------------------------------- /** * Sets the default module for editing operations. When changed, other * default objects that reference this object will be updated accordingly. * Default: The value to use if another value is not provided. * * @param conceptId either a nid or conceptSequence */ void setDefaultModule(int conceptId); /** * Sets the default path for editing operations. When changed, other default * objects that reference this object will be updated accordingly. Default: * The value to use if another value is not provided. * * @param conceptId either a nid or conceptSequence */ void setDefaultPath(int conceptId); //~--- get methods --------------------------------------------------------- /** * Gets the default stamp coordinate. * * @return an {@code ObservableStampCoordinate} based on the configuration * defaults. */ ObservableStampCoordinate getDefaultStampCoordinate(); //~--- set methods --------------------------------------------------------- /** * Sets the default stated definition assemblage. When changed, other * default objects that reference this object will be updated accordingly. * Default: The value to use if another value is not provided. * * @param conceptId either a nid or conceptSequence */ void setDefaultStatedAssemblage(int conceptId); //~--- get methods --------------------------------------------------------- /** * Gets the default taxonomy coordinate. * * @return an {@code ObservableTaxonomyCoordinate} based on the * configuration defaults. */ ObservableTaxonomyCoordinate getDefaultTaxonomyCoordinate(); //~--- set methods --------------------------------------------------------- /** * Sets the default time for viewing versions of components When changed, * other default objects that reference this object will be updated * accordingly. Default: The value to use if another value is not provided. * * @param timeInMs Time in milliseconds since unix epoch. Long.MAX_VALUE is * used to represent the latest versions. */ void setDefaultTime(long timeInMs); /** * Sets the default user for editing and role-based access control. When * changed, other default objects that reference this object will be updated * accordingly. Default: The value to use if another value is not provided. * * @param conceptId either a nid or conceptSequence */ void setDefaultUser(int conceptId); //~--- get methods --------------------------------------------------------- /** * Return the known (if any) details to utilize to make a GIT server connection. * The returned URL should point to the root of the git server - not to a particular repository. * * @return the git configuration */ public default Optional<RemoteServiceInfo> getGitConfiguration() { return Optional.empty(); } //~--- set methods --------------------------------------------------------- /** * Specify the details to be returned by {@link #getGitConfiguration()}. This method is optional, and may not be supported * (in which case, it throws an {@link UnsupportedOperationException}) * * @param rsi the new git configuration */ public default void setGitConfiguration(RemoteServiceInfo rsi) { throw new UnsupportedOperationException(); } //~--- get methods --------------------------------------------------------- /** * Gets the search folder path. * * @return The root folder of the search data store - one would expect to * find a data-store specific folder such as "lucene" inside this folder. * The default implementation returns either: * * A path as specified exactly via * {@link Constants#SEARCH_ROOT_LOCATION_PROPERTY} (if the property is set) * or the result of * {@link #getDataStoreFolderPath()} + {@link Constants#DEFAULT_SEARCH_FOLDER} * * The returned path exists on disk at the time that this method returns. */ public default Path getSearchFolderPath() { Path result; final Optional<Path> rootPath = getDataStoreFolderPath(); if (!rootPath.isPresent()) { throw new IllegalStateException( "The ConfigurationService implementation has not been configured by a call to setDataStoreFolderPath()," + " and the system property " + Constants.DATA_STORE_ROOT_LOCATION_PROPERTY + " has not been set. Cannot construct the search folder path."); } else { result = rootPath.get() .resolve(Constants.DEFAULT_SEARCH_FOLDER); } try { Files.createDirectories(result); } catch (final IOException e) { throw new RuntimeException(e); } return result; } }