V1_0.java [src/java/d/crlmod/rusle2] Revision: default Date:
/*
* $Id: 1.0+65 V1_0.java 402d39c37049 2021-12-29 od $
*
* 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 d.crlmod.rusle2;
import crlmod.ServiceResources;
import static crlmod.ServiceResources.CR_LMOD_R2;
import csip.ModelDataService;
import csip.annotations.Description;
import csip.annotations.Name;
import csip.annotations.Resource;
import csip.annotations.State;
import static csip.annotations.State.RELEASED;
import csip.annotations.VersionInfo;
import csip.api.server.ServiceException;
import csip.utils.JSONUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.Path;
import org.codehaus.jettison.json.JSONArray;
/**
*
* @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
*/
@Name("RUSLE2")
@Description("Retrieves XML data files for any RUSLE2 object")
@VersionInfo("1.0")
@State(RELEASED)
@Path("d/rusle2/1.0")
@Resource(from = ServiceResources.class)
public class V1_0 extends ModelDataService {
static final String ID_KEY = "id";
static final String NAME_KEY = "name";
static final String PARTIAL_NAME_KEY = "partial_name";
static final String PATH_KEY = "path";
static final String PARTIAL_PATH_KEY = "partial_path";
static final String LIMIT_KEY = "limit";
private String[] ids;
private String[] names;
private String[] partial_names;
private String[] paths;
private String[] partial_paths;
private int limit;
private List<TableResult> searchResults = new ArrayList<>();
@Override
protected void preProcess() throws Exception {
boolean haveValidRequest = false;
// If we have the ids input key, don't check the other keys, that would not
// make logical sense to structure such a request.
if (parameter().has(ID_KEY)) {
ids = parameter().getStringArray(ID_KEY);
haveValidRequest = true;
} else {
// If we have a names list, no need to check for a partial names list
if (parameter().has(NAME_KEY)) {
names = parameter().getStringArray(NAME_KEY);
haveValidRequest = true;
} else {
if (parameter().has(PARTIAL_NAME_KEY)) {
partial_names = parameter().getStringArray(PARTIAL_NAME_KEY);
haveValidRequest = true;
}
}
// If we have a paths list, no need to check for a partial paths list
if (parameter().has(PATH_KEY)) {
paths = parameter().getStringArray(PATH_KEY);
haveValidRequest = true;
} else {
if (parameter().has(PARTIAL_PATH_KEY)) {
partial_paths = parameter().getStringArray(PARTIAL_PATH_KEY);
haveValidRequest = true;
}
}
}
// Shall we limit the return amount. Really only useful if the client
// requests a list of objects by specifying an empty ids list input.
limit = parameter().getInt(LIMIT_KEY, 0);
if (!haveValidRequest)
throw new ServiceException("Invalid input provided. Please check the required parameters documentation.");
}
@Override
protected void doProcess() throws Exception {
if ((null != ids) && (ids.length <= 0)) {
// ************************************************************************
// Client wants a list of available objects. Ideally, this should not be
// called by any model code. This will return a huge amount of data and a
// model should already know what it is looking for.
//
// This will return only a list of ID, Path, Name values, and will not
// return any XML data (result would be too large otherwise)
// ************************************************************************
String query = "SELECT " + ((limit > 0) ? " TOP " + limit : "") + " id, path, name, scienceDate FROM R2_Data ORDER BY path, name;";
try (Connection conn = resources().getJDBC(getJDBCId()); Statement stmnt = conn.createStatement();) {
try (ResultSet results = stmnt.executeQuery(query)) {
while (results.next()) {
searchResults.add(new TableResult(results, false));
}
}
}
} else {
if (null != ids) {
// Client wants data by Id
String query = "SELECT " + ((limit > 0) ? " TOP " + limit : "") + " id, path, name, scienceDate, xmlData FROM R2_Data WHERE ";
query += buildPreparedWhereIsList("id", ids) + " ORDER BY path, name;";
try (Connection conn = resources().getJDBC(getJDBCId()); PreparedStatement stmnt = conn.prepareStatement(query)) {
int counter = 1;
for (String id : ids) {
stmnt.setString(counter++, id);
}
try (ResultSet results = stmnt.executeQuery()) {
while (results.next()) {
searchResults.add(new TableResult(results, true));
}
}
}
} else {
// Client wants data by other fields. Query other fields.
String query = "SELECT " + ((limit > 0) ? " TOP " + limit : "") + " id, path, name, scienceDate, xmlData FROM R2_Data WHERE ";
boolean add = false;
if ((null != paths) && (paths.length >= 0)) {
add = true;
query += buildPreparedWhereIsList("path", paths);
}
if ((null != names) && (names.length >= 0)) {
query += ((add) ? " AND " : " ") + buildPreparedWhereIsList("name", names);
add = true;
}
if ((null != partial_paths) && (partial_paths.length >= 0)) {
query += ((add) ? " AND " : " ") + buildPreparedWhereLikeList("path", partial_paths);
add = true;
}
if ((null != partial_names) && (partial_names.length >= 0)) {
query += ((add) ? " AND " : " ") + buildPreparedWhereLikeList("name", partial_names);
add = true;
}
query += " ORDER BY path,name;";
try (Connection conn = resources().getJDBC(getJDBCId()); PreparedStatement stmnt = conn.prepareStatement(query)) {
int counter = 1;
if ((null != paths) && (paths.length >= 0)) {
for (String path : paths) {
stmnt.setString(counter++, path);
}
}
if ((null != names) && (names.length >= 0)) {
for (String name : names) {
stmnt.setString(counter++, name);
}
}
if ((null != partial_paths) && (partial_paths.length >= 0)) {
for (String path : partial_paths) {
stmnt.setString(counter++, "%" + path + "%");
}
}
if ((null != partial_names) && (partial_names.length >= 0)) {
for (String name : partial_names) {
stmnt.setString(counter++, "%" + name + "%");
}
}
try (ResultSet results = stmnt.executeQuery()) {
while (results.next()) {
searchResults.add(new TableResult(results, true));
}
}
}
}
}
}
@Override
protected void postProcess() throws Exception {
JSONArray rows = new JSONArray();
for (TableResult row : searchResults) {
rows.put(row.toJSON());
}
results().put("r2_data_list", rows);
}
protected String buildPreparedWhereIsList(String fieldName, String[] values) {
String where = "";
if ((null != values) && (values.length > 0)) {
where = fieldName + " IN (";
for (int i = 0; i < values.length; i++) {
where += "?";
if ((i + 1) < values.length)
where += ",";
}
where += ")";
}
return where;
}
protected String buildPreparedWhereLikeList(String fieldName, String[] values) {
String where = "";
if ((null != values) && (values.length > 0)) {
where = "(";
for (int i = 0; i < values.length; i++) {
where += fieldName + " LIKE ? ";
if ((i + 1) < values.length)
where += " OR ";
}
where += ")";
}
return where;
}
protected String getJDBCId() {
return CR_LMOD_R2;
}
@Override
protected Map<String, Object> getConfigInfo() {
return new LinkedHashMap<String, Object>() {
{
put(getJDBCId(), resources().getResolved(getJDBCId()));
}
};
}
private class TableResult {
String id;
String path;
String name;
String scienceDate;
String XML = null;
TableResult(ResultSet results, boolean getXML) throws SQLException {
id = results.getString("id");
path = results.getString("path");
name = results.getString("name");
scienceDate = results.getString("scienceDate");
if (getXML)
XML = results.getString("xmlData");
}
public JSONArray toJSON() {
JSONArray result = new JSONArray();
result.put(JSONUtils.data(ID_KEY, id, "The unique id for this path/name combination.", null));
result.put(JSONUtils.data(PATH_KEY, path, "The path for this object", null));
result.put(JSONUtils.data(NAME_KEY, name, "The name for this object.", null));
result.put(JSONUtils.data("science_date", scienceDate, "The date associated with this version of the XML file in this record.", null));
result.put(JSONUtils.data("xml_file", XML, "The formatted XML file, if any, for this path/name combination..", null));
return result;
}
}
}