
com.wci.umls.server.helpers.ConfigUtility Maven / Gradle / Ivy
/*
* Copyright 2016 West Coast Informatics, LLC
*/
package com.wci.umls.server.helpers;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Properties;
import java.util.Scanner;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status.Family;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
/**
* Loads and serves configuration.
*/
public class ConfigUtility {
/** The Constant DEFAULT. */
public final static String DEFAULT = "DEFAULT";
/** The date format. */
public final static FastDateFormat DATE_FORMAT =
FastDateFormat.getInstance("yyyyMMdd");
/** The Constant DATE_FORMAT2. */
public final static FastDateFormat DATE_FORMAT2 =
FastDateFormat.getInstance("yyyy_MM_dd");
/** The Constant DATE_FORMAT3. */
public final static FastDateFormat DATE_FORMAT3 =
FastDateFormat.getInstance("yyyy");
/** The Constant PUNCTUATION. */
public final static String PUNCTUATION =
" \t-({[)}]_!@#%&*\\:;\"',.?/~+=|<>$`^";
/** The Constant PUNCTUATION_REGEX. */
public final static String PUNCTUATION_REGEX =
"[ \\t\\-\\(\\{\\[\\)\\}\\]_!@#%&\\*\\\\:;\\\"',\\.\\?\\/~\\+=\\|<>$`^]";
/** The config. */
public static Properties config = null;
/** The transformer for DOM -> XML. */
private static Transformer transformer;
/** The date format. */
public final static FastDateFormat format =
FastDateFormat.getInstance("yyyyMMdd");
static {
try {
TransformerFactory factory = TransformerFactory.newInstance();
transformer = factory.newTransformer();
// Indent output.
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount",
"4");
// Skip XML declaration header.
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
} catch (TransformerConfigurationException e) {
throw new RuntimeException(e);
}
}
/**
* Indicates whether or not the server is active.
*
* @return true
if so, false
otherwise
* @throws Exception the exception
*/
public static boolean isServerActive() throws Exception {
if (config == null)
config = ConfigUtility.getConfigProperties();
try {
// Attempt to logout to verify service is up (this works like a "ping").
Client client = ClientBuilder.newClient();
WebTarget target = client
.target(config.getProperty("base.url") + "/security/logout/dummy");
Response response = target.request(MediaType.APPLICATION_JSON).get();
if (response.getStatusInfo().getFamily() == Family.SUCCESSFUL) {
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
}
}
/**
* Indicates whether or not analysis mode is the case.
*
* @return true
if so, false
otherwise
* @throws Exception the exception
*/
public static boolean isAnalysisMode() throws Exception {
try {
if (config == null)
config = ConfigUtility.getConfigProperties();
return "true".equals(config.getProperty("analysis.mode").toString());
} catch (Throwable e) {
return false;
}
}
/**
* Reset config properties. Needed for testing so we can reset the state of
* config.properties and reload it.
*/
public static void resetConfigProperties() {
config = null;
}
/**
* Returns the config properties.
* @return the config properties
*
* @throws Exception the exception
*/
public static Properties getConfigProperties() throws Exception {
if (isNull(config)) {
// Need to determine the label (default "umls")
String label = "umls";
Properties labelProp = new Properties();
// If no resource is available, go with the default
// ONLY setups that explicitly intend to override the setting
// cause it to be something other than the default.
InputStream input =
ConfigUtility.class.getResourceAsStream("/label.prop");
if (input != null) {
labelProp.load(input);
// If a run.config.label override can be found, use it
String candidateLabel = labelProp.getProperty("run.config.label");
// If the default, uninterpolated value is used, stick again with the
// default
if (candidateLabel != null
&& !candidateLabel.equals("${run.config.label}")) {
label = candidateLabel;
}
} else {
Logger.getLogger(ConfigUtility.class.getName())
.info(" label.prop resource cannot be found, using default");
}
Logger.getLogger(ConfigUtility.class.getName())
.info(" run.config.label = " + label);
// Now get the properties from the corresponding setting
// This is a complicated mechanism to support multiple simulataneous
// installations within the same container (e.g. tomcat).
// Default setups do not require this.
String configFileName = System.getProperty("run.config." + label);
Logger.getLogger(ConfigUtility.class.getName())
.info(" run.config." + label + " = " + configFileName);
config = new Properties();
FileReader in = new FileReader(new File(configFileName));
config.load(in);
in.close();
Logger.getLogger(ConfigUtility.class).info(" properties = " + config);
}
return config;
}
/**
* New handler instance.
*
* @param the
* @param handler the handler
* @param handlerClass the handler class
* @param type the type
* @return the object
* @throws Exception the exception
*/
@SuppressWarnings("unchecked")
public static T newHandlerInstance(String handler, String handlerClass,
Class type) throws Exception {
if (handlerClass == null) {
throw new Exception("Handler class " + handlerClass + " is not defined");
}
Class> toInstantiate = Class.forName(handlerClass);
if (toInstantiate == null) {
throw new Exception("Unable to find class " + handlerClass);
}
Object o = null;
try {
o = toInstantiate.newInstance();
} catch (Exception e) {
e.printStackTrace();
// do nothing
}
if (o == null) {
throw new Exception("Unable to instantiate class " + handlerClass
+ ", check for default constructor.");
}
if (type.isAssignableFrom(o.getClass())) {
return (T) o;
}
throw new Exception("Handler is not assignable from " + type.getName());
}
/**
* Instantiates a handler using standard setup and configures it with
* properties.
*
* @param the
* @param property the property
* @param handlerName the handler name
* @param type the type
* @return the t
* @throws Exception the exception
*/
public static T newStandardHandlerInstanceWithConfiguration(
String property, String handlerName, Class type) throws Exception {
// Instantiate the handler
// property = "metadata.service.handler" (e.g)
// handlerName = "SNOMED" (e.g.)
String classKey = property + "." + handlerName + ".class";
if (config.getProperty(classKey) == null) {
throw new Exception("Unexpected null classkey " + classKey);
}
String handlerClass = config.getProperty(classKey);
Logger.getLogger(ConfigUtility.class).debug("Instantiate " + handlerClass);
T handler =
ConfigUtility.newHandlerInstance(handlerName, handlerClass, type);
// Look up and build properties
Properties handlerProperties = new Properties();
handlerProperties.setProperty("security.handler", handlerName);
for (Object key : config.keySet()) {
// Find properties like "metadata.service.handler.SNOMED.class"
if (key.toString().startsWith(property + "." + handlerName + ".")) {
String shortKey = key.toString()
.substring((property + "." + handlerName + ".").length());
Logger.getLogger(ConfigUtility.class).debug(" property " + shortKey
+ " = " + config.getProperty(key.toString()));
handlerProperties.put(shortKey, config.getProperty(key.toString()));
}
}
handler.setProperties(handlerProperties);
return handler;
}
/**
* Returns the graph for string.
*
* @param the generic type
* @param xml the xml
* @param graphClass the graph class
* @return the graph for string
* @throws JAXBException the JAXB exception
*/
@SuppressWarnings("unchecked")
public static T getGraphForString(String xml, Class graphClass)
throws JAXBException {
JAXBContext context = JAXBContext.newInstance(graphClass);
Unmarshaller unmarshaller = context.createUnmarshaller();
return (T) unmarshaller.unmarshal(new StreamSource(new StringReader(xml)));
}
/**
* Returns the graph for json.
*
* @param the generic type
* @param json the json
* @param graphClass the graph class
* @return the graph for json
* @throws Exception the exception
*/
public static T getGraphForJson(String json, Class graphClass)
throws Exception {
InputStream in =
new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector introspector =
new JaxbAnnotationIntrospector(mapper.getTypeFactory());
mapper.setAnnotationIntrospector(introspector);
return mapper.readValue(in, graphClass);
}
/**
* Returns the graph for file.
*
* @param the generic type
* @param file the file
* @param graphClass the graph class
* @return the graph for file
* @throws FileNotFoundException the file not found exception
* @throws JAXBException the JAXB exception
*/
@SuppressWarnings("resource")
public static T getGraphForFile(File file, Class graphClass)
throws FileNotFoundException, JAXBException {
return getGraphForString(
new Scanner(file, "UTF-8").useDelimiter("\\A").next(), graphClass);
}
/**
* Returns the graph for stream.
*
* @param the generic type
* @param in the in
* @param graphClass the graph class
* @return the graph for stream
* @throws FileNotFoundException the file not found exception
* @throws JAXBException the JAXB exception
*/
@SuppressWarnings("resource")
public static T getGraphForStream(InputStream in, Class graphClass)
throws FileNotFoundException, JAXBException {
return getGraphForString(
new Scanner(in, "UTF-8").useDelimiter("\\A").next(), graphClass);
}
/**
* Returns the XML string for for graph object.
*
* @param object the object
* @return the string for for graph
* @throws JAXBException the JAXB exception
*/
public static String getStringForGraph(Object object) throws JAXBException {
StringWriter writer = new StringWriter();
JAXBContext jaxbContext = null;
jaxbContext = JAXBContext.newInstance(object.getClass());
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.marshal(object, writer);
return writer.toString();
}
/**
* Returns the json for graph.
*
* @param object the object
* @return the json for graph
* @throws Exception the exception
*/
public static String getJsonForGraph(Object object) throws Exception {
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector introspector =
new JaxbAnnotationIntrospector(mapper.getTypeFactory());
mapper.setAnnotationIntrospector(introspector);
return mapper.writeValueAsString(object);
}
/**
* Returns the node for string.
*
* @param xml the xml
* @return the node for string
* @throws ParserConfigurationException the parser configuration exception
* @throws SAXException the SAX exception
* @throws IOException Signals that an I/O exception has occurred.
*/
public static Node getNodeForString(String xml)
throws ParserConfigurationException, SAXException, IOException {
InputStream in =
new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
// Parse XML file.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(in);
Node rootNode = document.getFirstChild();
return rootNode;
}
/**
* Returns the node for file.
*
* @param file the file
* @return the node for file
* @throws ParserConfigurationException the parser configuration exception
* @throws SAXException the SAX exception
* @throws IOException Signals that an I/O exception has occurred.
*/
public static Node getNodeForFile(File file)
throws ParserConfigurationException, SAXException, IOException {
InputStream in = new FileInputStream(file);
// Parse XML file.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(in);
Node rootNode = document.getFirstChild();
in.close();
return rootNode;
}
/**
* Returns the string for node.
*
* @param root the root node
* @return the string for node
* @throws TransformerException the transformer exception
* @throws ParserConfigurationException the parser configuration exception
*/
public static String getStringForNode(Node root)
throws TransformerException, ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
document.appendChild(document.importNode(root, true));
DOMSource source = new DOMSource(document);
StringWriter out = new StringWriter();
StreamResult result = new StreamResult(out);
transformer.transform(source, result);
return out.toString();
}
/**
* Returns the graph for node.
*
* @param node the node
* @param graphClass the graph class
* @return the graph for node
* @throws JAXBException the JAXB exception
* @throws TransformerException the transformer exception
* @throws ParserConfigurationException the parser configuration exception
*/
public static Object getGraphForNode(Node node, Class> graphClass)
throws JAXBException, TransformerException, ParserConfigurationException {
return getGraphForString(getStringForNode(node), graphClass);
}
/**
* Returns the node for graph.
*
* @param object the object
* @return the node for graph
* @throws ParserConfigurationException the parser configuration exception
* @throws SAXException the SAX exception
* @throws IOException Signals that an I/O exception has occurred.
* @throws JAXBException the JAXB exception
*/
public static Node getNodeForGraph(Object object)
throws ParserConfigurationException, SAXException, IOException,
JAXBException {
return getNodeForString(getStringForGraph(object));
}
/**
* Pretty format.
*
* @param input the input
* @param indent the indent
* @return the string
*/
public static String prettyFormat(String input, int indent) {
try {
Source xmlInput = new StreamSource(new StringReader(input));
StringWriter stringWriter = new StringWriter();
StreamResult xmlOutput = new StreamResult(stringWriter);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", indent);
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(xmlInput, xmlOutput);
return xmlOutput.getWriter().toString();
} catch (Exception e) {
// simple exception handling, please review it
throw new RuntimeException(e);
}
}
/**
* Merge-sort two files.
*
* @param files1 the first set of files
* @param files2 the second set of files
* @param comp the comparator
* @param dir the sort dir
* @param headerLine the header_line
* @return the sorted {@link File}
* @throws IOException Signals that an I/O exception has occurred.
*/
public static File mergeSortedFiles(File files1, File files2,
Comparator comp, File dir, String headerLine) throws IOException {
final BufferedReader in1 = new BufferedReader(new FileReader(files1));
final BufferedReader in2 = new BufferedReader(new FileReader(files2));
final File outFile = File.createTempFile("t+~", ".tmp", dir);
final BufferedWriter out = new BufferedWriter(new FileWriter(outFile));
String line1 = in1.readLine();
String line2 = in2.readLine();
String line = null;
if (!headerLine.isEmpty()) {
line = headerLine;
out.write(line);
out.newLine();
}
while (line1 != null || line2 != null) {
if (line1 == null) {
line = line2;
line2 = in2.readLine();
} else if (line2 == null) {
line = line1;
line1 = in1.readLine();
} else if (comp.compare(line1, line2) < 0) {
line = line1;
line1 = in1.readLine();
} else {
line = line2;
line2 = in2.readLine();
}
// if a header line, do not write
if (!line.startsWith("id")) {
out.write(line);
out.newLine();
}
}
out.flush();
out.close();
in1.close();
in2.close();
return outFile;
}
/**
* Delete directory.
*
* @param path the path
* @return true, if successful
*/
static public boolean deleteDirectory(File path) {
if (path.exists()) {
File[] files = path.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDirectory(files[i]);
} else {
files[i].delete();
}
}
}
return (path.delete());
}
/**
* Sends email.
*
* @param subject the subject
* @param from the from
* @param recipients the recipients
* @param body the body
* @param details the details
* @param authFlag the auth flag
* @throws Exception the exception
*/
public static void sendEmail(String subject, String from, String recipients,
String body, Properties details, boolean authFlag) throws Exception {
// avoid sending mail if disabled
if ("false".equals(details.getProperty("mail.enabled"))) {
// do nothing
return;
}
Session session = null;
if (authFlag) {
Authenticator auth = new SMTPAuthenticator();
session = Session.getInstance(details, auth);
} else {
session = Session.getInstance(details);
}
MimeMessage msg = new MimeMessage(session);
if (body.contains(" the
* @param classes the classes
* @param clazz the clazz
* @param sortField the sort field
* @throws Exception the exception
*/
public static void reflectionSort(List classes, Class clazz,
String sortField) throws Exception {
final Method getMethod = clazz.getMethod("get"
+ sortField.substring(0, 1).toUpperCase() + sortField.substring(1));
if (getMethod.getReturnType().isAssignableFrom(Comparable.class)) {
throw new Exception("Referenced sort field is not comparable");
}
Collections.sort(classes, new Comparator() {
@SuppressWarnings({
"rawtypes", "unchecked"
})
@Override
public int compare(T o1, T o2) {
try {
Comparable f1 = (Comparable) getMethod.invoke(o1, new Object[] {});
Comparable f2 = (Comparable) getMethod.invoke(o2, new Object[] {});
return f1.compareTo(f2);
} catch (Exception e) {
// do nothing
}
return 0;
}
});
}
/**
* To arabic.
*
* @param number the number
* @return the int
* @throws Exception the exception
*/
public static int toArabic(String number) throws Exception {
if (number.isEmpty())
return 0;
if (number.startsWith("M"))
return 1000 + toArabic(number.substring(1));
if (number.startsWith("CM"))
return 900 + toArabic(number.substring(2));
if (number.startsWith("D"))
return 500 + toArabic(number.substring(1));
if (number.startsWith("CD"))
return 400 + toArabic(number.substring(2));
if (number.startsWith("C"))
return 100 + toArabic(number.substring(1));
if (number.startsWith("XC"))
return 90 + toArabic(number.substring(2));
if (number.startsWith("L"))
return 50 + toArabic(number.substring(1));
if (number.startsWith("XL"))
return 40 + toArabic(number.substring(2));
if (number.startsWith("X"))
return 10 + toArabic(number.substring(1));
if (number.startsWith("IX"))
return 9 + toArabic(number.substring(2));
if (number.startsWith("V"))
return 5 + toArabic(number.substring(1));
if (number.startsWith("IV"))
return 4 + toArabic(number.substring(2));
if (number.startsWith("I"))
return 1 + toArabic(number.substring(1));
throw new Exception("something bad happened");
}
/**
* Indicates whether or not roman numeral is the case.
*
* @param number the number
* @return true
if so, false
otherwise
*/
public static boolean isRomanNumeral(String number) {
return number
.matches("^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$");
}
/**
* Returns the indent for level.
*
* @param level the level
* @return the indent for level
*/
public static String getIndentForLevel(int level) {
StringBuilder sb = new StringBuilder().append(" ");
for (int i = 0; i < level; i++) {
sb.append(" ");
}
return sb.toString();
}
/**
* This method is intended to bypass some incorrect static code analysis from
* the FindBugs Eclipse plugin.
*
* @param o the o
* @return true
if so, false
otherwise
*/
public static boolean isNull(Object o) {
return o == null;
}
/**
* Capitalize.
*
* @param value the value
* @return the string
*/
public static String capitalize(String value) {
if (value == null) {
return value;
}
return value.substring(0, 1).toUpperCase() + value.substring(1);
}
/**
* Converts string field to case-insensitive string of tokens with punctuation
* removed For example, "HIV Infection" becomes "hiv infection", while
* "1,2-hydroxy" becomes "1 2 hydroxy".
*
* @param value the value
* @return the string
*/
public static String normalize(String value) {
final String[] splitStrs = value.toLowerCase().split(PUNCTUATION_REGEX);
return String.join(" ", splitStrs).trim().replaceAll(" +", " ");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy