Utils.java [src/java/crlmod/utils] Revision: Date:
/*
* $Id$
*
* This file is part of the Cloud Services Integration Platform (CSIP),
* a Model-as-a-Service framework, API, and application suite.
*
* 2012-2024, OMSLab, Colorado State University.
*
* OMSLab licenses this file to you under the MIT license.
* See the LICENSE file in the project root for more information.
*/
package crlmod.utils;
import static crlmod.ServiceResources.*;
import csip.api.server.PayloadParameter;
import csip.api.server.ServiceException;
import csip.SessionLogger;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Level;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.codehaus.jettison.json.JSONException;
import org.w3c.dom.Document;
/**
*
* @author LYaege
*/
public class Utils {
public static String getTime() {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
return sdf.format(Calendar.getInstance().getTime());
}
public static boolean isNumeric(String str) {
return str.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal.
}
public static boolean isPositiveReal(String str) {
return str.matches("\\d+"); //match a number with optional '-' and decimal.
}
/**
* Converts unit input to a standardized unit for example "Bushels" will
* return 'bu.'
*
* @param unit The string that represents the harvest unit to be standardized
* @return The string the represents the standardized harvest unit.
*/
public static String norm_harv_units(String unit) {
if (unit.contains("Bushels") || unit.contains("bu")) {
return "bu.";
}
if (unit.contains("Cords")) {
return "cords";
}
if (unit.contains("tons sugar") || unit.contains("Ton")) {
return "tons";
}
if (unit.contains("box")) {
return "boxes";
}
if (unit.contains("lb") || unit.contains("pounds")) {
return "lbs";
}
if (unit.contains("Bundles")) {
return "Bdl";
}
return unit;
}
/**
*
* @param doc
* @return
*/
public static String getStringFromDocument(Document doc) {
try {
DOMSource domSource = new DOMSource(doc);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(domSource, result);
return writer.toString();
} catch (TransformerException ex) {
ExceptionUtils.printRootCauseStackTrace(ex);
return null;
}
}
/**
*
* @param params
* @param object_key
* @param object_name
* @param map
* @param LOG
* @return
* @throws JSONException
* @throws ServiceException
*/
public static String createWhere(List<String> params,
String object_key, String object_name,
PayloadParameter map,
SessionLogger LOG)
throws JSONException, ServiceException {
String where = "WHERE 1=1 \n";
//ID***************************************************
String[] ja_ids = map.getStringArray(KEY_ID, null);
if (ja_ids != null) {
String ids = "";
for (int i = 0; i < ja_ids.length; ++i) {
String id = ja_ids[i];
if (!id.equals("")) {
if (i == 0)
where += "AND (" + object_key + "_id = " + id + "\n";
else
where += "OR " + object_key + "_id = " + id + "\n";
if (i == ja_ids.length - 1)
where += ")";
ids += id + " ";
} else {
LOG.log(Level.INFO, "{0}: ID is an empty string", object_name);
}
}
params.add(object_key + "_id " + ids + " ");
} else {
LOG.log(Level.INFO, "{0}: no ID", object_name);
}
//Keywords*************************************************
String keywordStr = map.getString(KEY_KEYWORDS, null);
if (keywordStr != null) {
keywordStr = keywordStr.trim();
String[] keywords = keywordStr.split(" ");
if (keywords.length > 0 && !keywordStr.equals("")) {
String keys = "KEYWORDS: ";
for (int i = 0; i < keywords.length; i++) {
if (keywords[i].charAt(0) == '-') {
where += "AND " + object_key + "_name not LIKE '%" + keywords[i].substring(1) + "%'\n";
} else {
where += "AND " + object_key + "_name LIKE '%" + keywords[i] + "%'\n";
}
//for displayed error.
keys += "'" + keywords[i] + "'";
if (i < keywords.length - 1)
keys += ", or ";
}
keys += " ";
params.add(keys);
}
} else {
LOG.log(Level.INFO, "{0}: no keywords", object_name);
}
//Name *****************************************************
String[] ja_names = map.getStringArray(KEY_NAME, null);
if (ja_names != null) {
String names = "NAME: ";
for (int i = 0; i < ja_names.length; ++i) {
String nameStr = ja_names[i].trim();
if (!StringUtils.isEmpty(nameStr)) {
if (i == 0)
where += "AND (" + object_key + "_name = '" + nameStr + "'\n";
else
where += "OR " + object_key + "_name = '" + nameStr + "'\n";
if (i == ja_names.length - 1)
where += ")\n";
names += nameStr + ", or ";
} else
LOG.log(Level.INFO, "{0}: no names", object_name);
}
names = names.substring(0, names.length() - 5);
params.add(names);
} else {
LOG.log(Level.INFO, "{0}: no names", object_name);
}
//Path *************************************************
String[] ja_paths = map.getStringArray(KEY_PATH, null);
if (ja_paths != null) {
String paths = "PATH: ";
for (int i = 0; i < ja_paths.length; ++i) {
String path = ja_paths[i];
if (!StringUtils.isEmpty(path)) {
if (object_key != "man") {
if (i == 0)
where += "AND (" + object_key + "_group1 = '" + path + "'\n";
else
where += "OR " + object_key + "_group1 = '" + path + "'\n";
if (i == ja_paths.length - 1)
where += ")\n";
} else {
if (i == 0)
where += "AND (man_path = '" + path + "'\n";
else
where += "OR man_path = '" + path + "'\n";
if (i == ja_paths.length - 1)
where += ")\n";
}
paths += path + " ";
} else
LOG.log(Level.INFO, "{0}: no paths", object_name);
}
params.add(paths);
} else {
LOG.log(Level.INFO, "{0}: no paths", object_name);
}
//Patial Path *************************************************
String[] ja_partialPaths = map.getStringArray(KEY_PARTIAL_PATH, null);
//TODO: make this work with the negation character '-' to exclude rather than include values.
if (ja_partialPaths != null) {
String partialPaths = "PATH PART: ";
for (int i = 0; i < ja_partialPaths.length; ++i) {
String pathPart = ja_partialPaths[i];
if (!StringUtils.isEmpty(pathPart)) {
String negation = "";
if (pathPart.charAt(0) == '-') {
negation = "not";
pathPart = pathPart.substring(1);
}
if (!object_key.equals("man")) {
if (i == 0)
where += "AND (" + object_key + "_group1 " + negation + " LIKE '%" + pathPart + "%'\n";
else
where += "AND " + object_key + "_group1 " + negation + " LIKE '%" + pathPart + "%'\n";
if (i == ja_partialPaths.length - 1)
where += ")\n";
} else {
if (i == 0)
where += "AND (man_path " + negation + " LIKE '%" + pathPart + "%'\n";
else
where += "AND man_path " + negation + " LIKE '%" + pathPart + "%'\n";
if (i == ja_partialPaths.length - 1)
where += ")\n";
}
partialPaths += pathPart + " ";
} else
LOG.log(Level.INFO, "{0}: no paths", object_name);
}
params.add(partialPaths);
} else {
LOG.log(Level.INFO, "{0}: no paths", object_name);
}
//CMZ ***********************************************
String cmz = map.getString(KEY_CMZ, null);
if (cmz != null) {
cmz = cmz.trim();
where += "AND man_cmz LIKE '%" + cmz + "'\n"; // may have to change this to be more precise
params.add("CMZ: " + cmz + " ");
} else {
LOG.log(Level.INFO, "{0}: no cmz", object_name);
}
//STIR min/max***********************************************
String stirMIN = map.getString(KEY_STIR_MIN, "");
if (!stirMIN.isEmpty()) {
stirMIN = stirMIN.trim();
where += "AND man_stir > " + stirMIN + "\n";
params.add("STIR GREATER THAN: " + stirMIN + " ");
} else {
LOG.log(Level.INFO, "{0}: min stir", object_name);
}
String stirMAX = map.getString(KEY_STIR_MAX, "");
if (!stirMAX.isEmpty()) {
stirMAX = stirMAX.trim();
where += "AND man_stir < " + stirMAX + "\n";
params.add("STIR LESS THAN: " + stirMAX + "");
} else {
LOG.log(Level.INFO, "{0}: max stir", object_name);
}
return where;
}
/**
*
* @param params
* @param map
* @param LOG
* @param object_name
* @param object_prefix
* @return
* @throws JSONException
* @throws ServiceException
*/
public static String createOffsetAndLimits(List<String> params,
PayloadParameter map,
SessionLogger LOG,
String object_name,
String object_prefix) throws JSONException, ServiceException {
String offsetAndLimits = "ORDER BY " + object_prefix + "_name\n";
String off = map.getString(KEY_OFFSET, "0");
off = off.trim();
if (!off.equals("") && Utils.isPositiveReal(off) && Integer.parseInt(off) >= 0) {
//Removed this line to address IET issue #504712 in search of better error messaging.
//params.add("offset " + off + " ");
offsetAndLimits += "OFFSET " + off + " ROWS\n";
} else {
offsetAndLimits += "OFFSET 0 ROWS\n";
params.add("default offset of 0");
LOG.log(Level.INFO, object_name + ": offset set to default of 0. Offset parameter was either not set, or set to something non-numeric");
}
String lim = map.getString(KEY_LIMIT, "");
lim = lim.trim();
if (lim.equals("all")) {
LOG.log(Level.INFO, "{0}: all {1}s requested", new Object[]{object_name, object_name});
} else if (!lim.equals("") && Utils.isPositiveReal(lim)) {
int limInt = -1;
try {
limInt = Integer.parseInt(lim);
} catch (NumberFormatException ex) {
throw new IllegalArgumentException("Invalid number of records requested. Limit must be a positive integer between 1 and 100.");
}
if (limInt < 1) {
throw new IllegalArgumentException("Limit must be a positive integer between 1 and 100.");
}
if (limInt > 10000) {
limInt = 10000;
params.add("limit automatically adjusted to 100. This service only allows 100 rows to be requested at a time.");
}
//Removed line to address IEt error: #504712 in search of better error messages.
//params.add("limit " + limInt + "");
offsetAndLimits += "FETCH NEXT " + limInt + " ROWS ONLY\n";
} else if (lim.equals("")) {
LOG.log(Level.INFO, "{0}: no limit specified adujsting to 1", object_name);
offsetAndLimits += "FETCH NEXT 1 ROWS ONLY\n";
} else {
throw new IllegalArgumentException(object_name + ": Error - limit specified is not numeric. Limit must be a positive integer");
}
return offsetAndLimits;
}
}