Java API
To view LWJUS-List javadoc, click here
To view LWJUS-common javadoc, click here.

LWJUS-common is a utilities package for java application, it provides a provider/implementation framework allows client to plug in their preferred implantations for interfaces.
The following interfaces and implementations are shipped in package:
  • - Logging and Auditing interface with JUL implementation.
  • - Configure interface with file implementation, support encryption of sensitive data such as password
  • - Encryption/Eecryption API with AES implementation
  • - JSON interface to convert between String and Object with Jackson (fastxml) implementation
  • - Datasource provider with Apache DBCP2 implementation


REST API


To Get the List Definition:
GET http://{server}:{port}/{appContext}/rest/list/definition/{list name}
Sample Response:
{ "name" : "department", "attributes" : [ { "name" : "name", "properties" : { "display" : "Department ID" } }, { "name" : "display", "properties" : { "display" : "Department Name" } }, { "name" : "manager", "properties" : { "display" : "Manager Name" } }, { "name" : "title", "properties" : { "display" : "Title" } } ], "sortBys" : [ { "name" : "department", "properties" : { "display" : "Sort by Department" } }, { "name" : "title", "properties" : { "display" : "Sort by Title" } }, { "name" : "name", "properties" : { "display" : "Sort by Manager Name" } } ], "filters" : [ { "name" : "department", "properties" : { "types" : "String", "display" : "Department is", "optionName" : "deptOption" } } ], "mutualExclusiveFilters" : null, "requiredFilterSets" : null, "filterDependency" : null, "properties" : { } }
To Get List Data
POST http://{server}:{port}/{appContext}/rest/list/data { "attributes" : [ "name", "display", "manager", "title" ], "includeTotal" : false, "listName" : "department", "sortBy" : "name", "environment" : { "connectionName" : "default" }, "filters" : { "department" : [ "d005" ] } }
Sample Response:
{ "total" : -1, "data" : [ [ "d005", "Development", "DeForest Hagimont", "Technique Leader" ], [ "d005", "Development", "Leon DasSarma", "Manager" ] ] }


Configuration

                  
Config File

The default application config file is app.cfg, can be placed on classpath. This can be overwriten by JVM option -DAPP_CFG_FILE={absolute path}
Data Source Configuration
The data source name can be specified in list request (request.environment.connectionName='dsname'), if none, the default data source is used. If connection pool/data source is configured in app server, specify the JNDI name in configuration. E.g. #the default datasource datasource_jndi_name=jndi/data_source1 #other named datasource datasource_jndi_name.name1=jndi/data_source2 The Apache DBCP is configured as a provider for data source OOTB, see the sample configurations below: #the default datasource DBCPDataSourceImpl.default.driver=com.mysql.cj.jdbc.Driver DBCPDataSourceImpl.default.url=jdbc:mysql://localhost:3306/employees?useLegacyDatetimeCode=false&serverTimezone=UTC DBCPDataSourceImpl.default.user=root #password can be encrypted using EncryptionUtils, just pass the output as the value of password, e.g. #DBCPDataSourceImpl.default.password=<ENCRYPTED>PEVLEYCK==I......EKAE= DBCPDataSourceImpl.default.password=password DBCPDataSourceImpl.default.min=5 DBCPDataSourceImpl.default.max=50 #other named datasource DBCPDataSourceImpl.name1.driver=... ... DBCPDataSourceImpl.name1.max=50
List Configuration
All configuraitons for RDBMS start with ListRDBMSImpl. Common configurations: #max size of rows returned. ListRDBMSImpl.max_list_size=5000 #setup interceptors if need change request or response, see java DOC for details. ListRDBMSImpl.interceptors=com.package1.Class1,com.package2.Class2 List specific configuraitons: A main "SQL" must be setup for each list, see sample below. ListRDBMSImpl.[list].employee.sql=select {attributes} from employees e, current_dept_emp de, departments d where {empId} and {lastName} and {firstName} and {gender} and {department} and {active} and de.emp_no = e.emp_no and d.dept_no = de.dept_no order by {orderBy} {pageOffsetLimit} In above line, employee is the list name, sql is the property name for main "SQL". The "SQL" contains placeholders {...} for attributes, filter, order by. The list configurations specifis all attributes a list can return; the list request at runtime contains the attributes the client wants, {attributes} will be replaced with the SQL for requested attributes only. The placeholders in where clause are filters, the "SQL" contains all possible filters; the request specify the used filters at runtime, those filters are not in request are ignored. If no filter in where clause, the where keyword will be removed as well. The {orderBy} placeholder is replaced with specified filter in request; if none, the order by keywords are removed. The {pageOffsetLimit} is for pagination, see detail in filter section. If support pagination, the sql_for_total "SQL" can be used return total item number, e.g. ListRDBMSImpl.[list].employee.sql_for_total=select count(1) from employees e, current_dept_emp de, departments d where {empId} and {lastName} and {firstName} and {gender} and {department} and {active} and de.emp_no = e.emp_no and d.dept_no = de.dept_no You can specify other customized attribute as well, e.g. ListRDBMSImpl.[list].employee.display=Employee List Attribute configurations: The sql and type must be configured for each attribute, below is the sql for firstName. ListRDBMSImpl.[list].employee.[attribute].firstName.sql=e.first_name ListRDBMSImpl.[list].employee.[attribute].firstName.type=String Other attributes can be configured as well, e.g. ListRDBMSImpl.[list].employee.[attribute].firstName.display=First Name Note, "display" property is used by the OOTB smart table client to display table column name. Filter configuration: Sql and types must be configured for filter ListRDBMSImpl.[list].employee.[filter].firstName.sql=e.first_name like ? #for the type String.SW, a '%' will be appened to filter value for RDBMS. ListRDBMSImpl.[list].employee.[filter].firstName.types=String.SW Other customized properties can be defined ListRDBMSImpl.[list].employee.[filter].firstName.display=First Name starts with Note, "display" property is used by the OOTB smart table client to display the filter label. ListRDBMSImpl.[list].employee.[filter].firstName.placeholder=E.g. Maya Note, "placeholder" property is used by the OOTB smart table client to generate the input text's placeholder. If you force a filter to be passed in, you can specify .required=true. For pagination filter, there are two cases. Case 1 : use LIMIT/OFFSET. #below is SQL for mysql ListRDBMSImpl.[list].employee.[filter].pageOffsetLimit.sql=LIMIT ?,? #for Oracle 12c #ListRDBMSImpl.[list].employee.[filter].pageOffsetLimit.sql=OFFSET ? ROWS FETCH NEXT ? ROWS ONLY #for early version of Oracle, use rownum approach, need configure two filter pageStart and pageEnd. ListRDBMSImpl.[list].employee.[filter].pageOffsetLimit.types=Integer,Integer ListRDBMSImpl.[list].employee.[filter].pageOffsetLimit.required=true Case 2: use ROWNUM for old Oracle. ListRDBMSImpl.[list].list1.sql=select {attributes} from (select rownum r__num, a.* from (select {attributes} from some_table where {filter1} and ({filter2} or {filter3}) order by {orderBy}) a where {pageEnd}) where {pageStart} ListRDBMSImpl.[list].list1.[filter].pageStart.sql=r__num > ? ListRDBMSImpl.[list].list1.[filter].pageStart.types=Integer ListRDBMSImpl.[list].list1.[filter].pageEnd.sql=rownum <= ? ListRDBMSImpl.[list].list1.[filter].pageEnd.types=Integer Note, if you build your own client, you can use any name for pagination filter. The OOTB smart table client uses the fixed name pageStart, pageEnd, and pageOffsetLimit. Order by configuration: Sql must be configured, e.g. ListRDBMSImpl.[list].employee.[sort_by].lastName.sql=e.last_name,e.first_name "display" is used by OOTB client to display label. ListRDBMSImpl.[list].employee.[sort_by].lastName.display=Sort by Last Name ListRDBMSImpl.[list].employee.[sort_by].lastNameDesc.sql=e.last_name desc,e.first_name desc ListRDBMSImpl.[list].employee.[sort_by].lastNameDesc.display=Sort by Last Name Descending Other list configurations: ListRDBMSImpl.[list].list1.mutual_exclusive_filters=f1:f2,f5:f6:f7 The above line specifies filter f1 and f2 cannot be passed in at the same time, same for f5,f6, and f7. ListRDBMSImpl.[list].list1.filter_dependencies=f6:f8,f1:f3:f5 The above line specifies if f6 presents in request, f8 must also exist. If f1 exists, f3 and f5 must exist. If f3 exists, f5 must exist. ListRDBMSImpl.[list].list1.required_filters=f10:f12,f15:f16:f17 The above line specifies at least one of f10 and f12 must exist in request, and one of f15,f16 and f17 must exists.
LDAP List
LDAP data source is also implemented. The default REST URL base for LDAP list is http://{server}:{port}/{app_context}}/rest/ldaplist LDAP connection: ldap_cfg.default.java.naming.provider.url=ldap://localhost:389 ldap_cfg.default.java.naming.security.principal=cn=Directory Manager ldap_cfg.default.java.naming.security.credentials=<ENCRYPTED>W09aj==,jKELKAAELAJFEAAKeKK ldap_cfg.otherLdap.java.naming.provider.url=ldap://someserver:389 ... #LDAP List cfg ListLDAPImpl.max_list_size=500 ListLDAPImpl.interceptors=com.lwjus.sample.Interceptor1 #configure a "user" list. ListLDAPImpl.[list].user.base_filter=objectClass=person ListLDAPImpl.[list].user.base=ou=people,ou=lwjus,dc=com Attribute configurations: ListLDAPImpl.[list].user.[attribute].uid.type=String ListLDAPImpl.[list].user.[attribute].uid.display=User ID #Here "uid" is the ldap attribute name. ListLDAPImpl.[list].user.[attribute].nsAccountLock.type=String ListLDAPImpl.[list].user.[attribute].nsAccountLock.display=Locked #Here "nsAccountLock" is the ldap attribute name. ... Filter configurations: ListLDAPImpl.[list].user.[filter].uidFilter.query=uid=? ListLDAPImpl.[list].user.[filter].uidFilter.types=String ListLDAPImpl.[list].user.[filter].uidFilter.display=UID like (use * for wild card) ListLDAPImpl.[list].user.[filter].uidFilter.required=true Order by configurations: ListLDAPImpl.[list].user.[sort_by].userAsc.attribute=uid ListLDAPImpl.[list].user.[sort_by].userAsc.display=UID Ascending ListLDAPImpl.[list].user.[sort_by].userDesc.attribute=uid ListLDAPImpl.[list].user.[sort_by].userDesc.descending=true ListLDAPImpl.[list].user.[sort_by].userDesc.display=UID Descending Note, LDAP list's sorting and pagination are done in memrory after retrieving data (less than configured max record) from LDAP. LDAP list use pageStart and pageEnd to specify pagination parameters.