960 likes | 1.11k Views
IA366 DDS Enterprise Application Framework. Alex Whitney Managing Principal Dynamic Data Solutions awhitney@dyn-data.com. Agenda. Why Enterprise Application Framework (EAF) Major Features Major Components and Services Demonstration. Why Did We Develop the EAF.
E N D
IA366DDS Enterprise Application Framework Alex Whitney Managing Principal Dynamic Data Solutions awhitney@dyn-data.com
Agenda • Why Enterprise Application Framework (EAF) • Major Features • Major Components and Services • Demonstration
Why Did We Develop the EAF • EAF was developed to help our customers guarantee the success of their EAServer development efforts • We felt that development community as a whole could benefit from this kind of functionality
Why Did We Develop EAF • We decided that the best solution would be to provide the DDS EAF as an open source offering to the PowerBuilder community • EAF is to EAS as PFC is to PowerBuilder • It gives developers a leg up on the development process • Utilize their time on solving business problems, not technical ones
Major Features • ResultSet Vs. Blob • No DataWindow syntax required on client • Logical Unit of Work • Single point of entry for all clients • Interface Manager & Business Object • HTMLDW Support • Multilingual support • Tracing and debugging support
Resultset Vs. Blob • ResultSets are Corba compliant and usable from many clients • Blobs require a PB Datastore or DataWindow at the client
No Datawindow Syntax Required on Client • Updates to client applications can be much simpler • Syntax is sent to client as requested • Options • Only Syntax • Only Data • Syntax and Data • Syntax As Needed
Logical Unit of Work • Implicit in how data is transmitted between client application and component • Data for multiple DataWindows are sent as a group • Both retrieves and updates can be grouped • One round trip between client and server for an update or retrieve
Client Business Object Business Object Update Request Interface Manager Component DataSet DataSet DataSet Session Manager Component Message Manager Component Business Object Component Business Object Component Business Object Component Database Logical Unit of Work
Single Point of Entry for All Clients • All data access is treated the same no matter what the client is • InterfaceManager Component delegates all requests as required • DataSet Object • BO Component
Web Client Business Object Business Object PowerBuilder Client Business Object Business Object Java Client Business Object Business Object Interface Manager Component DataSet C++ Client Business Object Business Object Session Manager Component Message Manager Component ActiveX Client Business Object Business Object Business Object Component Message Manager Message Manager Database Single Point of Entry for All Clients
Business Object • Allows a single point of validation for updates from multiple IM’s • Supports DataWindow validations as well as custom logic
Interface Manager Component Interface Manager Component DataSet Interface Manager Component Business Object Component Client Business Object Business Object Database Business Object
HTMLDW Support • Permits the developer to treat web clients just like a PB client • Same retrieval and update logic regardless of client
Multilingual Support • Display DataWindows and messages in a specific language that is tied to a session
Tracing and Debugging Support • Extensive support for writing information to the Jaguar log file • Can be controlled from the component’s Jaguar properties • com.sybase.jaguar.component.ddseafdebug=true • com.sybase.jaguar.component.ddseafdetailed=true • com.sybase.jaguar.component.ddseaftrace=true
Major Components and Services • DDSEAF_n_cst_component • Interface structure • InterfaceManager Component • BOManager Component • DataSet Object • InterfaceService Object • SessionManager Component • MessageManager Component • DDSEAF_n_cst_resultsetservice
DDSEAF_n_cst_component • Base class for all PB components • Database access • Methods for configuring a connection to the database • Methods for connecting and disconnecting • No default connection or disconnection logic at this level
DDSEAF_n_cst_component • Transaction management • SetComplete/SetAbort() wrappers • IsInTransaction() • IsTransactionAborted() • Logging • Reference to logging service object • Debugging • Automatic setting of debug variables from component properties
DDSEAF_n_cst_component • Error handling • Get/SetLastError() functions • Communication with other components via ObjectService reference variable • SessionManager • MessageManager
Interface Structure • Communication between server and client is handled via the Interface Structure • Structure allows multiple DataSets to be transferred between the client and InterfaceManager as a single LUW
InterfaceManager Component • Manages requests for data from client applications • Requests are for a single (or multiple) set of data (DataSet) • Each DataSet’s ResultSet is defined by: • A DataWindow object • A more sophisticated DataSet object
InterfaceManager Component • Can manage one to many DataSets • Each DataSet has zero to many associated BusinessObjects assigned to it • Updates are: • Delegated to a BO • Performed via a DataSet Object • Not allowed • Defined by DataSet configuration
InterfaceManager Component • LUW scoped to an InterfaceManager • LUW may not span multiple IM’s • The same DataSet can reside on multiple IM’s • BO’s may be called from multiple IM’s • Can work with all DataSets in a LUW
InterfaceManager Component • Example Constructor Code • // Set up the Transaction • ls_bo = ‘DDSEAF_Examples/BOCustomer’ • SQLCA.initialize('odbc', "UseContextObject = 'Yes',cachename='EASDemo'") • registerDataset('custpicklist', d_customerpicklist”) • registerDataset('customer', "d_customer", ‘’, ls_bo)
InterfaceManager Component • // Registers a DataSet object - Much more flexible than a single DataWindow object • lnv_customer = create ds_customer • registerDataset('customer', lnv_customer, ls_bo, ls_bo)
BOManager Component • Normally configured to manage all updates for a specific table • Supports DataWindow validation rules • Can apply data rules to the syntax of the DataWindow object prior to a retrieve • Supports the addition of custom logic
BOManager Component • Extract only the columns that belong to them for updating • Multi-table updates, where rows have a 1-to-1 relationship, are automatic if all BO’s that manage the tables are registered with the DataSet at the IM
BOManager Component • Example Constructor Code • // Set up the Transaction • SQLCA.initialize('odbc', "UseContextObject = 'Yes',cachename='EASDemo'") • // Set the dataobject • setDataobject("d_bocustomer")
DataSet Object • Allows for extensions to retrieval logic • If a BO is not used then the DataSet object can be used to extend update logic • Allows for customization of generated HTML
DataSet Object • Example Constructor Code • setDataobject('d_customer', 1) • setDataobject('d_customer_spanish', 2)
InterfaceService Object • Client side service object that manages interactions between the client and an InterfaceManager component • One InterfaceService per LUW • LUW normally scoped at window level • DataSets are configured to use either a DataWindow control or a DataStore as the target
InterfaceService Object • DataSets can be grouped • DataSets can belong to more than one group • Retrieves and updates can be done for: • A single DataSet or group • A series of DataSets or groups • All registered DataSets
InterfaceService Object • Update process performs accepttext() and checks for required fields before starting the update • Only DataSets that have changes are sent to the server • Only rows that have been updated, inserted or deleted are sent to the server
InterfaceService Object • Example Open Event Code • ll_rc = inv_interface.setConnection(icn_jaguar) • If ll_rc <> 1 Then MessageBox (this.ClassName(), "Call inv_interface.setConnection() failed!" + inv_interface.getLastError() + "~r~nRC=" + String(ll_rc)) Return • End If
InterfaceService Object • ll_rc = inv_interface.setInterfaceManager('IMCust') • // Register the DataSet(s) • ll_rc = inv_interface.registerDataset("customer", "customer", "windowgroup", dw_customer, inv_interface.RETRIEVE_FULLONNEED)
InterfaceService Object • Example Update code • ll_rc = inv_interface.update ("customer") • If ll_rc < 0 Then • MessageBox (this.ClassName(), & • "Call inv_interface.update() failed!~r~n~rn" + inv_interface.getLastError() + "~r~nRC=" + String(ll_rc)) • Return • End If
InterfaceService Object • // Cast to key value to the appropriate type and add the Retrieval Argument • ll_key = long(ls_key) • ll_rc = inv_interface.resetArguments( "customer") • ll_rc = inv_interface.addArgument ("customer", ll_key) • // Perform the request for retrieval • ll_rc = inv_interface.retrieve ("windowgroup")
SessionManager Component • Provides a way to store session specific information at the server • Written in Java for multithreaded support
MessageManager Component • Provides standardized message handling for both server and client • Written in Java for multithreaded support
DDSEAF_n_cst_resultsetservice • Provides conversion from DataWindow/Datastore to ResultSet style structure and back • Extracts all buffers from a DataStore/DataWindow and converts them to resultsets
DDSEAF_n_cst_resultsetservice • Does so by isolating each buffer(6 of them) • DELETED • NEW • MODIFIED_NEW • UNMODIFIED_ORIGINAL • MODIFIED_ORIGINAL • MODIFIED_CURRENT • Finds all DDDW columns and converts their contents to a ResultSet
DDSEAF_n_cst_resultsetservice • Reverses the process on the receiving end • Ensures that all status flags are properly set after being converted back to a DataStore /DataWindow
InterfaceManager Component • Public methods • retrieve ( ref s_interface astr_interface ) returns long • All DataSets in the retrieval list are retrieved • update ( ref s_interface astr_interface ) returns long • All DataSets in the update list are updated • generate ( ref s_htmldwprops htmldwprops ) returns string • Request for HTML DataWindow interface
InterfaceManager Component • Public methods • getregistered ( ref string as_datasetids[] ) returns long • Returns a list of all registered DataSets • getargumentdefinition ( string as_datasetid, ref string as_argnames[], ref string as_argdatatypes[] ) returns long • Returns the argument list and their datatypes for a DataSet
InterfaceManager Component • Configuration concepts and commonly used methods • Configure database connection • SQLCA.initialize('odbc', "UseContextObject = 'Yes',cachename='EASDemo'") • Configure DataSets • If a DataSet object is NOT specified then a default one will be created and used for the DataSet
InterfaceManager Component • Configure DataSets (continued) • Use customized DataSet object to alter default behavior • Retrieve only • DataSet is updated by the IM • Set data rules with a BO, Update via IM • Retrieve/update w/BO for update and BO for setting data rules. Data rules BO is optional