Skip to content

Commit 2b8f61a

Browse files
committed
Consolidated logic used to generate where statements in the get() and list() methods. Also prioritized getRecordset() in the CRUD methods.
1 parent 579cf4e commit 2b8f61a

File tree

1 file changed

+164
-101
lines changed

1 file changed

+164
-101
lines changed

src/javaxt/express/WebService.java

Lines changed: 164 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -342,41 +342,37 @@ protected Recordset getRecordset(ServiceRequest request, String op, Class c,
342342
/** Used to retrieve an object from the database. Returns a JSON object.
343343
*/
344344
private ServiceResponse get(Class c, ServiceRequest request, Database database) {
345-
try (Connection conn = database.getConnection()){
345+
try{
346+
347+
//Compile sql statement
348+
HashMap<String, Object> tablesAndFields = getTableAndFields(c);
349+
String tableName = (String) tablesAndFields.get("tableName");
350+
String sql = "select " + tableName + ".id from " + tableName +
351+
" where ";
352+
346353

347-
//Get model
348-
Object obj;
349354
Long id = request.getID();
350355
if (id==null){
351-
Method get = getMethod("get", c);
352-
String[] keys = request.getParameterNames();
353-
ArrayList<Object> params = new ArrayList<>();
354-
for (String key : keys){
355-
if (key.equals("_")) continue;
356-
params.add(key + "=");
357-
params.add(request.getParameter(key).toString());
358-
}
359-
Object[] arr = params.toArray(new Object[params.size()]);
360-
obj = get.invoke(null, new Object[]{arr});
356+
String where = getWhere(request, tablesAndFields);
357+
if (where==null) return new ServiceResponse(404);
358+
else sql += where;
361359
}
362360
else{
363-
obj = newInstance(c, id);
361+
sql += tableName + ".id=" + id;
364362
}
365-
if (obj==null) return new ServiceResponse(404);
366-
367363

368364

369365
//Apply filter
370-
id = null;
371-
try (Recordset rs = getRecordset(request, "get", c,
372-
"select id from " + getTableName(obj) +
373-
" where id=" + getMethod("getID", c).invoke(obj), conn)){
374-
if (!rs.EOF) id = rs.getValue(0).toLong();
366+
try (Connection conn = database.getConnection()){
367+
try (Recordset rs = getRecordset(request, "get", c, sql, conn)){
368+
if (rs.EOF) id = null;
369+
else id = rs.getValue("id").toLong();
370+
}
375371
}
376372
if (id==null) return new ServiceResponse(404);
377373

378374

379-
//Return response
375+
Object obj = newInstance(c, id);
380376
Method toJson = getMethod("toJson", c);
381377
return new ServiceResponse((JSONObject) toJson.invoke(obj));
382378
}
@@ -394,44 +390,14 @@ private ServiceResponse get(Class c, ServiceRequest request, Database database)
394390
private ServiceResponse list(Class c, ServiceRequest request, Database database){
395391

396392

397-
//Get tableName and spatial fields associated with the Model
393+
//Get tableName and fields associated with the Model
394+
HashMap<String, Object> tablesAndFields;
395+
HashSet<String> spatialFields;
398396
String tableName;
399-
HashMap<String, String> fieldMap = new HashMap<>();
400-
HashSet<String> spatialFields = new HashSet<>();
401397
try{
402-
Object obj = c.newInstance();
403-
404-
//Get tableName
405-
java.lang.reflect.Field field = obj.getClass().getSuperclass().getDeclaredField("tableName");
406-
field.setAccessible(true);
407-
tableName = (String) field.get(obj);
408-
409-
410-
//Get fieldMap
411-
field = obj.getClass().getSuperclass().getDeclaredField("fieldMap");
412-
field.setAccessible(true);
413-
HashMap<String, String> map = (HashMap<String, String>) field.get(obj);
414-
Iterator<String> it = map.keySet().iterator();
415-
while (it.hasNext()){
416-
String fieldName = it.next();
417-
String columnName = map.get(fieldName);
418-
fieldMap.put(fieldName, columnName);
419-
}
420-
fieldMap.put("id", "id");
421-
422-
423-
//Get spatial fields
424-
for (java.lang.reflect.Field f : obj.getClass().getDeclaredFields()){
425-
Class fieldType = f.getType();
426-
String packageName = fieldType.getPackage()==null ? "" :
427-
fieldType.getPackage().getName();
428-
429-
if (packageName.startsWith("javaxt.geospatial.geometry") ||
430-
packageName.startsWith("com.vividsolutions.jts.geom") ||
431-
packageName.startsWith("org.locationtech.jts.geom")){
432-
spatialFields.add(f.getName());
433-
}
434-
}
398+
tablesAndFields = getTableAndFields(c);
399+
tableName = (String) tablesAndFields.get("tableName");
400+
spatialFields = (HashSet<String>) tablesAndFields.get("spatialFields");
435401
}
436402
catch(Exception e){
437403
return getServiceResponse(e);
@@ -452,7 +418,7 @@ private ServiceResponse list(Class c, ServiceRequest request, Database database)
452418
}
453419
else{
454420
fieldName = StringUtils.camelCaseToUnderScore(fieldName);
455-
sql.append(fieldName);
421+
sql.append(tableName + "." + fieldName);
456422
}
457423
}
458424
}
@@ -461,33 +427,7 @@ private ServiceResponse list(Class c, ServiceRequest request, Database database)
461427
sql.append(tableName);
462428

463429

464-
String where = null;
465-
Filter filter = request.getFilter();
466-
if (!filter.isEmpty()){
467-
//System.out.println(filter.toJson().toString(4));
468-
ArrayList<String> arr = new ArrayList<>();
469-
for (Filter.Item item : filter.getItems()){
470-
String name = item.getField();
471-
Iterator<String> it = fieldMap.keySet().iterator();
472-
while (it.hasNext()){
473-
String fieldName = it.next();
474-
String columnName = fieldMap.get(fieldName);
475-
if (name.equalsIgnoreCase(fieldName) || name.equalsIgnoreCase(columnName)){
476-
String op = item.getOperation();
477-
javaxt.utils.Value v = item.getValue();
478-
arr.add("(" + columnName + " " + op + " " + v + ")");
479-
break;
480-
}
481-
}
482-
}
483-
if (!arr.isEmpty()){
484-
where = String.join(" and ", arr);
485-
//console.log(where);
486-
}
487-
}
488-
else{
489-
where = request.getWhere();
490-
}
430+
String where = getWhere(request, tablesAndFields);
491431
if (where!=null){
492432
sql.append(" where ");
493433
sql.append(where);
@@ -683,14 +623,37 @@ else if (format.equals("json")){
683623
*/
684624
private ServiceResponse save(Class c, ServiceRequest request, Database database) {
685625
try{
626+
627+
//Parse json
686628
JSONObject json = request.getJson();
687629
if (json==null || json.isEmpty()) throw new Exception("JSON is empty.");
630+
Long id = json.get("id").toLong();
631+
boolean isNew = id==null;
632+
633+
634+
//Apply filter
635+
HashMap<String, Object> tablesAndFields = getTableAndFields(c);
636+
String tableName = (String) tablesAndFields.get("tableName");
637+
String sql = "select " + tableName + ".id from " + tableName +
638+
" where " + tableName + ".id=" + (id==null ? -1 : id);
639+
try (Connection conn = database.getConnection()){
640+
try (Recordset rs = getRecordset(request, "save", c, sql, conn)){
641+
if (rs.EOF) id = null;
642+
else id = rs.getValue("id").toLong();
643+
}
644+
}
645+
if (id==null && !isNew) return new ServiceResponse(404);
646+
647+
648+
649+
//Reparse json
650+
json = request.getJson();
651+
id = json.get("id").toLong();
652+
isNew = id==null;
688653

689654

690655
//Create new instance of the class
691656
Object obj;
692-
Long id = json.get("id").toLong();
693-
boolean isNew = false;
694657
if (id!=null){
695658
obj = newInstance(c, id);
696659
Method update = c.getDeclaredMethod("update", JSONObject.class);
@@ -702,18 +665,6 @@ private ServiceResponse save(Class c, ServiceRequest request, Database database)
702665
}
703666

704667

705-
//Apply filter
706-
if (!isNew){
707-
try (Connection conn = database.getConnection()){
708-
try (Recordset rs = getRecordset(request, "save", c,
709-
"select id from " + getTableName(obj) +
710-
" where id=" + getMethod("getID", c).invoke(obj), conn)){
711-
if (!rs.EOF) id = rs.getValue(0).toLong();
712-
}
713-
}
714-
if (id==null) return new ServiceResponse(404);
715-
}
716-
717668

718669
//Call the save method
719670
Method save = getMethod("save", c);
@@ -727,7 +678,8 @@ private ServiceResponse save(Class c, ServiceRequest request, Database database)
727678

728679

729680
//Fire event
730-
if (isNew) onCreate(obj, request); else onUpdate(obj, request);
681+
if (isNew) onCreate(obj, request);
682+
else onUpdate(obj, request);
731683

732684

733685
//Return response
@@ -850,6 +802,114 @@ private String getTableName(Object obj) throws Exception {
850802
}
851803

852804

805+
//**************************************************************************
806+
//** getTableAndFields
807+
//**************************************************************************
808+
/** Returns the table name and fields associated with a model
809+
*/
810+
private HashMap<String, Object> getTableAndFields(Class c) throws Exception {
811+
812+
String tableName;
813+
HashMap<String, String> fieldMap = new HashMap<>();
814+
HashSet<String> stringFields = new HashSet<>();
815+
HashSet<String> spatialFields = new HashSet<>();
816+
817+
Object obj = c.newInstance(); //maybe clone instead?
818+
819+
//Get tableName
820+
java.lang.reflect.Field field = obj.getClass().getSuperclass().getDeclaredField("tableName");
821+
field.setAccessible(true);
822+
tableName = (String) field.get(obj);
823+
824+
825+
//Get fieldMap
826+
field = obj.getClass().getSuperclass().getDeclaredField("fieldMap");
827+
field.setAccessible(true);
828+
HashMap<String, String> map = (HashMap<String, String>) field.get(obj);
829+
Iterator<String> it = map.keySet().iterator();
830+
while (it.hasNext()){
831+
String fieldName = it.next();
832+
String columnName = map.get(fieldName);
833+
fieldMap.put(fieldName, columnName);
834+
}
835+
fieldMap.put("id", "id");
836+
837+
838+
//Get spatial fields
839+
for (java.lang.reflect.Field f : obj.getClass().getDeclaredFields()){
840+
Class fieldType = f.getType();
841+
String packageName = fieldType.getPackage()==null ? "" :
842+
fieldType.getPackage().getName();
843+
844+
if (packageName.startsWith("javaxt.geospatial.geometry") ||
845+
packageName.startsWith("com.vividsolutions.jts.geom") ||
846+
packageName.startsWith("org.locationtech.jts.geom")){
847+
spatialFields.add(f.getName());
848+
}
849+
850+
if (fieldType.equals(String.class)){
851+
stringFields.add(f.getName());
852+
}
853+
}
854+
855+
HashMap<String, Object> p = new HashMap<>();
856+
p.put("tableName", tableName);
857+
p.put("fieldMap", fieldMap);
858+
p.put("stringFields", stringFields);
859+
p.put("spatialFields", spatialFields);
860+
return p;
861+
}
862+
863+
864+
//**************************************************************************
865+
//** getWhere
866+
//**************************************************************************
867+
/** Used to compile a where statement
868+
*/
869+
private String getWhere(ServiceRequest request, HashMap<String, Object> tablesAndFields){
870+
871+
872+
String tableName = (String) tablesAndFields.get("tableName");
873+
HashMap<String, String> fieldMap = (HashMap<String, String>) tablesAndFields.get("fieldMap");
874+
HashSet<String> stringFields = (HashSet<String>) tablesAndFields.get("stringFields");
875+
876+
877+
String where = null;
878+
Filter filter = request.getFilter();
879+
if (!filter.isEmpty()){
880+
//System.out.println(filter.toJson().toString(4));
881+
ArrayList<String> arr = new ArrayList<>();
882+
for (Filter.Item item : filter.getItems()){
883+
String name = item.getField();
884+
Iterator<String> it = fieldMap.keySet().iterator();
885+
while (it.hasNext()){
886+
String fieldName = it.next();
887+
String columnName = fieldMap.get(fieldName);
888+
if (name.equalsIgnoreCase(fieldName) || name.equalsIgnoreCase(columnName)){
889+
String op = item.getOperation();
890+
String v = item.getValue().toString();
891+
892+
if (v!=null && stringFields.contains(fieldName)){
893+
v = "'" + v.replace("'","''") + "'";
894+
}
895+
896+
arr.add("(" + tableName + "." + columnName + " " + op + " " + v + ")");
897+
break;
898+
}
899+
}
900+
}
901+
if (!arr.isEmpty()){
902+
where = String.join(" and ", arr);
903+
}
904+
}
905+
else{
906+
where = request.getWhere();
907+
}
908+
return where;
909+
}
910+
911+
912+
853913
//**************************************************************************
854914
//** getServiceResponse
855915
//**************************************************************************
@@ -859,6 +919,9 @@ private ServiceResponse getServiceResponse(Exception e){
859919
if (e instanceof java.lang.reflect.InvocationTargetException){
860920
return new ServiceResponse(e.getCause());
861921
}
922+
else if (e instanceof SecurityException){
923+
return new ServiceResponse(403, "Not Authorized");
924+
}
862925
else{
863926
return new ServiceResponse(e);
864927
}

0 commit comments

Comments
 (0)