blob: 060f9fbf33a145257e5f019c39fcd630b2f573ce [file] [log] [blame]
/**
* 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.
*/
package org.apache.atlas.odf.core;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.atlas.odf.api.settings.KafkaConsumerConfig;
import org.apache.atlas.odf.api.settings.ODFSettings;
import org.apache.atlas.odf.api.settings.SettingsManager;
import org.apache.atlas.odf.core.configuration.ConfigContainer;
import org.apache.atlas.odf.json.JSONUtils;
import org.apache.wink.json4j.JSONObject;
import org.apache.atlas.odf.api.discoveryservice.AnalysisRequestTracker;
import org.apache.atlas.odf.api.discoveryservice.DiscoveryServiceProperties;
public class Utils {
static Logger logger = Logger.getLogger(Utils.class.getName());
private static final List<Class<? extends Object>> MERGABLE_CLASSES = Arrays.asList(ConfigContainer.class, KafkaConsumerConfig.class, ODFSettings.class, DiscoveryServiceProperties.class);
public static void mergeODFPOJOs(Object source, Object update) {
if (!source.getClass().isAssignableFrom(update.getClass())) {
return;
}
Method[] sourceMethods = source.getClass().getDeclaredMethods();
for (Method getterMethod : sourceMethods) {
if (getterMethod.getName().startsWith("get") || getterMethod.getName().startsWith("is")) {
String setterMethodName = getterMethod.getName().replaceFirst("get", "set");
if (getterMethod.getName().startsWith("is")) {
setterMethodName = setterMethodName.replaceFirst("is", "set");
}
try {
Method setterMethod = source.getClass().getDeclaredMethod(setterMethodName, getterMethod.getReturnType());
Object updateValue = getterMethod.invoke(update);
if (updateValue != null) {
Object sourceValue = getterMethod.invoke(source);
if (sourceValue != null && MERGABLE_CLASSES.contains(updateValue.getClass())) {
//Value is another POJO, must also try merging these instead of overwriting
mergeODFPOJOs(sourceValue, updateValue);
setterMethod.invoke(source, sourceValue);
} else if (sourceValue instanceof Map && updateValue instanceof Map) {
Map updateJSON = (Map) updateValue;
Map sourceJSON = (Map) sourceValue;
for (Object key : updateJSON.keySet()) {
sourceJSON.put(key, updateJSON.get(key));
}
setterMethod.invoke(source, sourceJSON);
} else {
setterMethod.invoke(source, updateValue);
}
}
} catch (NoSuchMethodException e) {
throw new RuntimeException(MessageFormat.format("Objects of type {0} and {1} could not be merged, no matching method found for {2}!", source.getClass().getName(), update
.getClass().getName(), getterMethod.getName()), e);
} catch (SecurityException e) {
throw new RuntimeException(MessageFormat.format("Objects of type {0} and {1} could not be merged, method {2} could not be accessed (SecurityException)!", source.getClass()
.getName(), update.getClass().getName(), setterMethodName), e);
} catch (IllegalAccessException e) {
throw new RuntimeException(MessageFormat.format("Objects of type {0} and {1} could not be merged, method {2} could not be accessed! (IllegalAccessException)", source.getClass()
.getName(), update.getClass().getName(), getterMethod.getName()), e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(MessageFormat.format("Objects of type {0} and {1} could not be merged, method {2} does not accept the right parameters!", source.getClass().getName(),
update.getClass().getName(), setterMethodName), e);
} catch (InvocationTargetException e) {
e.printStackTrace();
throw new RuntimeException(MessageFormat.format("Objects of type {0} and {1} could not be merged, method {2} or {3} could not be invoked!", source.getClass().getName(), update
.getClass().getName(), getterMethod.getName(), setterMethodName), e);
}
}
}
}
public static Properties readConfigProperties(String path) {
// TODO cache this in static variables, it doesn't change at runtime
InputStream is = Utils.class.getClassLoader().getResourceAsStream(path);
if (is == null) {
return null;
}
Properties props = new Properties();
try {
props.load(is);
} catch (IOException e) {
throw new RuntimeException(e);
}
return props;
}
public static void setCurrentTimeAsLastModified(AnalysisRequestTracker tracker) {
tracker.setLastModified(System.currentTimeMillis());
}
public static String getExceptionAsString(Throwable exc) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
exc.printStackTrace(pw);
String st = sw.toString();
return st;
}
public static String collectionToString(Collection<?> coll, String separator) {
StringBuffer buf = null;
for (Object o : coll) {
if (buf == null) {
buf = new StringBuffer("[ ");
} else {
buf.append(separator);
}
buf.append(o.toString());
}
buf.append(" ]");
return buf.toString();
}
public static <T> boolean containsOnly(List<T> l, T[] elements) {
for (T t : l) {
boolean containsOnlyElements = false;
for (T el : elements) {
if (t.equals(el)) {
containsOnlyElements = true;
break;
}
}
if (!containsOnlyElements) {
return false;
}
}
return true;
}
public static <T> boolean containsNone(List<T> l, T[] elements) {
for (T t : l) {
boolean containsAnyElement = false;
for (T el : elements) {
if (t.equals(el)) {
containsAnyElement = true;
break;
}
}
if (containsAnyElement) {
return true;
}
}
return false;
}
public static List<String> splitString(String s, char separator) {
List<String> l = new ArrayList<String>();
if (s != null) {
StringTokenizer tok = new StringTokenizer(s, String.valueOf(separator));
while (tok.hasMoreTokens()) {
l.add(tok.nextToken());
}
}
return l;
}
public static String getInputStreamAsString(InputStream is, String encoding) {
try {
final int n = 2048;
byte[] b = new byte[0];
byte[] temp = new byte[n];
int bytesRead;
while ((bytesRead = is.read(temp)) != -1) {
byte[] newB = new byte[b.length + bytesRead];
System.arraycopy(b, 0, newB, 0, b.length);
System.arraycopy(temp, 0, newB, b.length, bytesRead);
b = newB;
}
String s = new String(b, encoding);
return s;
} catch (IOException exc) {
return getExceptionAsString(exc);
}
}
public static void mergeJSONObjects(JSONObject source, JSONObject target) {
if (source != null && target != null) {
target.putAll(source);
}
}
public static <T> T getValue(T value, T defaultValue) {
if (value == null) {
return defaultValue;
}
return value;
}
public static String getSystemPropertyExceptionIfMissing(String propertyName) {
Environment env = new ODFInternalFactory().create(Environment.class);
String value = env.getProperty(propertyName);
if (value == null) {
String msg = MessageFormat.format("System property ''{0}'' is not set", propertyName);
logger.log(Level.SEVERE, msg);
throw new RuntimeException(msg);
}
return value;
}
public static int getIntEnvironmentProperty(String propertyName, int defaultValue) {
Environment env = new ODFInternalFactory().create(Environment.class);
String value = env.getProperty(propertyName);
if (value == null) {
return defaultValue;
}
try {
return Integer.parseInt(value);
} catch(NumberFormatException exc) {
return defaultValue;
}
}
public static void runSystemCommand(String command) {
logger.log(Level.INFO, "Running system command: " + command);
try {
Runtime r = Runtime.getRuntime();
Process p = r.exec(command);
p.waitFor();
BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = b.readLine()) != null) {
logger.log(Level.INFO, "System command out: " + line);
}
b.close();
} catch(IOException | InterruptedException e) {
logger.log(Level.INFO, "Error executing system command.", e);
}
}
public static ConfigContainer readConfigurationFromClasspath(String jsonFileInClasspath) {
InputStream is = SettingsManager.class.getClassLoader().getResourceAsStream(jsonFileInClasspath);
try {
JSONObject configJSON = new JSONObject(is);
ConfigContainer config = JSONUtils.fromJSON(configJSON.write(), ConfigContainer.class);
return config;
} catch (Exception exc) {
throw new RuntimeException(exc);
}
}
public static String joinStrings(List<String> l, char separator) {
String result = null;
if ((l != null) && !l.isEmpty()) {
StringBuilder buf = null;
for (String s : l) {
if (buf == null) {
buf = new StringBuilder();
} else {
buf.append(separator);
}
buf.append(s);
}
result = buf.toString();
}
return result;
}
public static String getEnvironmentProperty(String name, String defaultValue) {
Environment env = new ODFInternalFactory().create(Environment.class);
String s = env.getProperty(name);
return s != null ? s : defaultValue;
}
public static long getEnvironmentProperty(String name, long defaultValue) {
Environment env = new ODFInternalFactory().create(Environment.class);
String s = env.getProperty(name);
if (s == null) {
return defaultValue;
}
try {
return Long.parseLong(s);
} catch(NumberFormatException exc) {
String msg = MessageFormat.format("Property ''{0}'' could not be converted to an integer", new Object[]{name});
logger.log(Level.WARNING, msg);
return defaultValue;
}
}
}