@@ -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