<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5606774739693012337</id><updated>2011-07-08T02:15:16.699-07:00</updated><title type='text'>Martin Taal at Openbravo</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mtopenbravo.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mtopenbravo.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Martin Taal</name><uri>http://www.blogger.com/profile/09522816133131499716</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://2.bp.blogspot.com/_s9bF0uJ_pxo/SWHZO15HsuI/AAAAAAAAAAM/4DGOFgBvDBc/S220/mtaal_photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>9</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5606774739693012337.post-1223484020507332089</id><published>2010-01-28T01:55:00.000-08:00</published><updated>2010-02-02T01:21:50.031-08:00</updated><title type='text'>Integrating the Data Access Layer with Openbravo XSQL and ConnectionProvider</title><content type='html'>&lt;div&gt;More and more developers are using the &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide/Concepts/Data_Access_Layer"&gt;Data Access Layer&lt;/a&gt; (DAL) for coding business logic in the Openbravo application. I sometimes get questions related to how to integrate DAL constructs with standard Openbravo approaches like Stored Procedures and XSQL generated classes. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As there are several options I felt it was time to spend a blog on this. In this blog I will discuss a number of 'good-to-know' classes which can be handy when you want to integrate DAL with the classic Openbravo approaches.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The first one to cover is the probably the most important one: the &lt;a href="https://code.openbravo.com/erp/devel/pi/file/94d1960e6863/src/org/openbravo/service/db/DalConnectionProvider.java"&gt;DalConnectionProvider&lt;/a&gt;. The DalConnectionProvider can be used when you call utility methods which need a ConnectionProvider object. The great thing of the DalConnectionProvider is that it shares the same connection and transaction as the DAL itself. Let's take an example. This one is from the &lt;a href="http://forge.openbravo.com/projects/massinvoicing"&gt;MassInvoicing&lt;/a&gt; module, computing the DocumentNo for a new invoice:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt;// create a new invoice object&lt;br /&gt;final Invoice invoice = OBProvider.getInstance().get(Invoice.class);&lt;br /&gt;// set some properties for the invoice&lt;br /&gt;invoice.setOrganization(org);&lt;br /&gt;invoice.setBusinessPartner(bp);&lt;br /&gt;invoice.setInvoiceDate(invoiceDate);&lt;br /&gt;invoice.setAccountingDate(invoiceDate);&lt;br /&gt;// .... code truncated for clarity&lt;br /&gt;&lt;br /&gt;// now compute a documentno, in the same database transaction&lt;br /&gt;final String documentNo = Utility.getDocumentNo(conn, &lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt;&lt;span style="font-weight: bold;"&gt;new DalConnectionProvider()&lt;/span&gt;,&lt;/span&gt; &lt;span style="font-size:85%;"&gt;vars, "", Invoice.TABLE_NAME, &lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center; font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;invoice.getDocumentType().getId(), &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center; font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;invoice.getDocumentType().getId(), false, true);&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt;invoice.setDocumentNo(documentNo);&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The above code creates an invoice and then calls a stored procedure using the DalConnectionProvider as the connect provider. As the same transaction is used any updates done by the stored procedure can be committed together with the rest of your work. As you can see the DalConnectionProvider is easy to work with as it does not need any extra parameters, you can create and use it directly.&lt;br /&gt;Sometimes it makes sense to call OBDal.getInstance().flush() before calling a stored procedure. This ensures that Hibernate has flushed all your changes to the database so that the stored procedure can see them.  Also read the remark at the end of this blog!&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The next two are somewhat related: &lt;a href="https://code.openbravo.com/erp/devel/pi/file/94d1960e6863/src/org/openbravo/service/db/CallProcess.java"&gt;CallProcess&lt;/a&gt; and &lt;a href="https://code.openbravo.com/erp/devel/pi/file/94d1960e6863/src/org/openbravo/service/db/CallStoredProcedure.java"&gt;CallStoredProcedure&lt;/a&gt;, they both call/run database logic in the database. The first, the CallProcess, can be used to call a process (defined in AD_PROCESS) directly. You can get a CallProcess by calling CallProcess.getInstance() (there is one instance shared by all threads). Again an example from the MassInvoicing module, calling the C_Order_Post process for a list of invoices:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt;// get an AD_Process instance, 111 is the C_Invoice_Post process&lt;br /&gt;final org.openbravo.model.ad.ui.Process process = OBDal.getInstance().get(org.openbravo.model.ad.ui.Process.class, "111");&lt;br /&gt;&lt;br /&gt;// iterate over the invoices and post them&lt;br /&gt;for (Invoice invoice : invoices) {&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt;&lt;br /&gt;final ProcessInstance processInstance = &lt;span style="font-weight: bold;"&gt;CallProcess.getInstance().call(process,&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style="text-align: center; font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt; invoice.getId(), new HashMap&lt;string,&gt;&amp;lt;String, String&amp;gt;());&lt;/string,&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt;    // the processInstance now contains the result&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt;    final String errorMsg = processInstance.getErrorMsg();&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt;    final Object result = processInstance.getResult();&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt;    final String recordID = processInstance.getRecordID();&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt;    // code truncated for clarity&lt;br /&gt;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The last parameter in the CallProcess.call method is a map of parameters, these are placed in the ad_pinstance_para table. &lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;The CallStoredProcedure class makes it possible to call any stored procedure in the database in a java programmer friendly way. The nice thing of this class is that you can pass in actual java objects as parameters, so you don't need to worry about String conversions. The return is also a type-specific java object. This code snippet shows its usage (calling the C_Divide stored procedure):&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=";font-family:'courier new';font-size:85%;"  &gt;&lt;span class="Apple-style-span"&gt;// set some parameters&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=";font-family:'courier new';font-size:85%;"  &gt;&lt;span class="Apple-style-span"&gt;final List&lt;object&gt; parameters = new ArrayList();&lt;/object&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=";font-family:'courier new';font-size:85%;"  &gt;parameters.add(new BigDecimal("10.1"));&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=";font-family:'courier new';font-size:85%;"  &gt;&lt;span class="Apple-style-span"&gt;parameters.add(new BigDecimal("2.0"));&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=";font-family:'courier new';font-size:85%;"  &gt;&lt;span class="Apple-style-span"&gt;// the procedure name&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=";font-family:'courier new';font-size:85%;"  &gt;&lt;span class="Apple-style-span"&gt;final String procedureName = "C_Divide";&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=";font-family:'courier new';font-size:85%;"  &gt;&lt;span class="Apple-style-span"&gt;// calling the procedure and getting the result&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;meta equiv="content-type" content="text/html; charset=utf-8"&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=";font-family:'courier new';font-size:85%;"  &gt;&lt;span class="Apple-style-span"&gt;final BigDecimal bigDecimal = (BigDecimal)CallStoredProcedure.getInstance().call(procedureName, parameters, null);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;The last one to discuss: the &lt;a href="https://code.openbravo.com/erp/devel/pi/file/94d1960e6863/src/org/openbravo/erpCommon/utility/OBObjectFieldProvider.java"&gt;OBObjectFieldProvider&lt;/a&gt; class makes it possible to wrap an Openbravo business object in a FieldProvider interface. The FieldProvider is used throughout the Openbravo system to wrap data read from the database (for example through a XSQL generated class). The OBObjectFieldProvider is useful when you read business objects through the DAL and need to pass them on to code expecting a FieldProvider.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The discussed classes are all documented with javadoc describing the meaning of parameters and methods and you can ofcourse study the source code directly. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Before concluding this blog, as a last tip: The DAL (Hibernate) queues actions to the database. So when updating the database through DAL and then calling a stored procedure using a DalConnectionProvider make sure to call OBDal.getInstance().flush() before calling the stored procedure. This flushes the queue to the database and ensures that the stored procedures sees your changes. Also when you want to work with the results from the stored procedure and read them back through the DAL read this &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide/Common_Issues,_Tips_and_Tricks#DAL_Queries_do_not_return_or_do_not_see_changes_in_the_database"&gt;tip&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As always I hope this is an interesting read, feedback is always welcomed. If you have any questions or remarks visit the &lt;a href="http://forge.openbravo.com/plugins/espforum/browse.php?group_id=100&amp;amp;forumid=549512"&gt;Openbravo forge forum&lt;/a&gt; and post them there.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Happy Coding!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5606774739693012337-1223484020507332089?l=mtopenbravo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mtopenbravo.blogspot.com/feeds/1223484020507332089/comments/default' title='Reacties plaatsen'/><link rel='replies' type='text/html' href='http://mtopenbravo.blogspot.com/2010/01/integrating-data-access-layer-with.html#comment-form' title='0 reacties'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/1223484020507332089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/1223484020507332089'/><link rel='alternate' type='text/html' href='http://mtopenbravo.blogspot.com/2010/01/integrating-data-access-layer-with.html' title='Integrating the Data Access Layer with Openbravo XSQL and ConnectionProvider'/><author><name>Martin Taal</name><uri>http://www.blogger.com/profile/09522816133131499716</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://2.bp.blogspot.com/_s9bF0uJ_pxo/SWHZO15HsuI/AAAAAAAAAAM/4DGOFgBvDBc/S220/mtaal_photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5606774739693012337.post-8975594003329459608</id><published>2009-11-05T14:04:00.000-08:00</published><updated>2010-04-07T06:45:49.242-07:00</updated><title type='text'>Module: Integrating JBoss Seam and Openbravo</title><content type='html'>The &lt;a href="http://forge.openbravo.com/projects/openbravoseam"&gt;Openbravo Seam module&lt;/a&gt; integrates &lt;a href="http://www.seamframework.org/"&gt;Seam&lt;/a&gt; with Openbravo, making it possible to develop Seam applications on top of Openbravo. The OB Seam module is a special module in that it provides custom implementations of specific Openbravo core (&lt;a href="http://wiki.openbravo.com/wiki/Projects/Data_Access_Layer/DAL_Developers_Manual"&gt;DAL&lt;/a&gt;) classes. This is a good example of the extendability provided by Openbravo modularity!&lt;br /&gt;&lt;br /&gt;The OB Seam module implements two specific Seam/Openbravo integration points:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Session/Transaction handling&lt;/li&gt;&lt;li&gt;User context as a Seam component.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Session/Transaction handling&lt;/span&gt;: Openbravo uses a so-called &lt;a href="https://www.hibernate.org/43.html"&gt;open-session-in-view&lt;/a&gt; pattern (one Hibernate session per HTTP request), while Seam mainly uses an EntityManager (is equivalent to a Hibernate session) per &lt;a href="http://magazine.redhat.com/2007/10/31/continuing-the-conversation-understanding-seam-nested-conversations/"&gt;conversation&lt;/a&gt;. The OB Seam module makes it possible to use these two concepts next to eachother. Openbravo Seam automatically detects that a Hibernate session is opened as part of a Seam conversation or independently from a Seam conversation. In the latter case the session-in-view pattern is automatically applied, in the first case Seam takes care of transaction handling.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_s9bF0uJ_pxo/SrfttxJJDbI/AAAAAAAAAC4/jMwMGhXENzE/s1600-h/seam-entities.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 214px;" src="http://2.bp.blogspot.com/_s9bF0uJ_pxo/SrfttxJJDbI/AAAAAAAAAC4/jMwMGhXENzE/s320/seam-entities.png" alt="" id="BLOGGER_PHOTO_ID_5384033250086292914" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The user context as a Seam component&lt;/span&gt;: the module makes the &lt;a href="http://wiki.openbravo.com/wiki/Projects/Data_Access_Layer/DAL_Developers_Manual#User_Context"&gt;OBContext&lt;/a&gt; object available through the &lt;a href="https://code.openbravo.com/erp/mods/org.openbravo.base.seam/file/c67de96652fe/src/org/openbravo/base/seam/core/OBUserContext.java"&gt;OBUserContext&lt;/a&gt; component. The module contains an example of a Seam authenticator which authenticates a user/password against the Openbravo user database, the authenticator adds the Openbravo role in the Seam identity object.&lt;br /&gt;&lt;br /&gt;The OB Seam module is shipped with a small example app (developed with RichFaces/JSF) which allows a user to login with his/her Openbravo account and then view the content of all tables available for the current role of the user. The user can switch role to view the content of other tables. The table view is a paging grid with a detail view.&lt;br /&gt;&lt;br /&gt;After installing the module (read the install tips &lt;a href="http://forge.openbravo.com/plugins/mwiki/index.php/Openbravoseam/DevelopersManual#Openbravo_Version_and_Install_Tips"&gt;here&lt;/a&gt;) and starting Openbravo you can reach the example app through this url:&lt;br /&gt;&lt;a href="http://localhost:8080/openbravo/web/org.openbravo.base.seam/page/show-entities.xhtml"&gt;http://localhost:8080/openbravo/web/org.openbravo.base.seam/page/show-entities.xhtml&lt;/a&gt;.&lt;br /&gt;Make sure that the browser has enough horizontal space (the grid/detail are layed out horizontally) then login using your Openbravo login/pwd (for example: Openbravo/openbravo).&lt;br /&gt;&lt;br /&gt;To help you getting started, there is a short developers manual available &lt;a href="http://forge.openbravo.com/plugins/mwiki/index.php/Openbravoseam/DevelopersManual"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The module is available through the central repository. I invite you to try it out, it should be easy to extend the example app. As always feel free to share your experience with us!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Update April 2010&lt;/h3&gt;&lt;br /&gt;To facilitate the download size, the original Seam module has been split in several modules:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://wiki.openbravo.com/wiki/Projects/Seam"&gt;Base Seam&lt;/a&gt;: the original Seam module now provides the main backend integration with Openbravo but no jsf/user interface parts.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://wiki.openbravo.com/wiki/Projects/SeamRichFaces"&gt;Seam Richfaces&lt;/a&gt;: provides the JSF and Richfaces parts of Seam.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://wiki.openbravo.com/wiki/Projects/SeamTest"&gt;Seam Test&lt;/a&gt;: provides the Seam test environment.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5606774739693012337-8975594003329459608?l=mtopenbravo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mtopenbravo.blogspot.com/feeds/8975594003329459608/comments/default' title='Reacties plaatsen'/><link rel='replies' type='text/html' href='http://mtopenbravo.blogspot.com/2009/11/module-integrating-jboss-seam-and.html#comment-form' title='0 reacties'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/8975594003329459608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/8975594003329459608'/><link rel='alternate' type='text/html' href='http://mtopenbravo.blogspot.com/2009/11/module-integrating-jboss-seam-and.html' title='Module: Integrating JBoss Seam and Openbravo'/><author><name>Martin Taal</name><uri>http://www.blogger.com/profile/09522816133131499716</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://2.bp.blogspot.com/_s9bF0uJ_pxo/SWHZO15HsuI/AAAAAAAAAAM/4DGOFgBvDBc/S220/mtaal_photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_s9bF0uJ_pxo/SrfttxJJDbI/AAAAAAAAAC4/jMwMGhXENzE/s72-c/seam-entities.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5606774739693012337.post-2205179182170596902</id><published>2009-10-26T15:23:00.000-07:00</published><updated>2009-11-10T07:35:33.421-08:00</updated><title type='text'>Module: Openbravo JSON REST Webservice!</title><content type='html'>As some of you may know we are currently prototyping a new &lt;a href="http://mtopenbravo.blogspot.com/2009/08/selecting-new-user-interface.html"&gt;user interface library&lt;/a&gt;. As part of the development for the new &lt;a href="http://planet.openbravo.com/?author=6"&gt;user interface&lt;/a&gt; we have developed a &lt;a href="http://en.wikipedia.org/wiki/JSON"&gt;JSON&lt;/a&gt; &lt;a href="http://www.google.com/search?q=rest"&gt;REST&lt;/a&gt; webservice module.&lt;br /&gt;&lt;br /&gt;This module is a very good example on how you can extend the Openbravo webservice functionality using Openbravo modularity. It shows how easy it is to extend Openbravo not only when coding your functionality but also when configuring your services (extending web.xml and other configuration files).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt; is a light-weight data-exchange format used extensively for client-service communication in web based applications. The JSON REST module is similar to the standard &lt;a href="http://mtopenbravo.blogspot.com/2009/02/openbravo-250-rest-webservices.html"&gt;Openbravo XML REST&lt;/a&gt; webservice in that it makes Openbravo information available through a webservice supporting CRUD operations.&lt;br /&gt;&lt;br /&gt;The module can be downloaded from the forge &lt;a href="http://forge.openbravo.com/projects/openbravojsonrest/module"&gt;here&lt;/a&gt; or can be installed from the central repository. After installing the module and restarting Openbravo you can try out the webservice directly. For example enter the following url in the address-bar of the browser:&lt;br /&gt;&lt;br /&gt;http://localhost:8080/openbravo/org.openbravo.service.json.jsonrest/Country/100&lt;br /&gt;&lt;br /&gt;This call will retrieve the Country business object with id 100 as a JSON string. You can save the returned content and open it in a text editor. The JSON will look like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;{"_identifier":"United States","entityName":"Country","$ref":"Country\/100","id":"100","client":{"_identifier":"System","entityName":"ADClient","$ref":"ADClient\/0","id":"0","active":true},"organization":{"_identifier":"*","entityName":"Organization","$ref":"Organization\/0","id":"0","active":true},"active":true,"creationDate":"2009-10-26T19:20:06","createdBy":{"_identifier":"System","entityName":"ADUser","$ref":"ADUser\/0","id":"0","active":true},"updated":"2009-10-26T19:20:06","updatedBy":{"_identifier":"System","entityName":"ADUser","$ref":"ADUser\/0","id":"0","active":true},"name":"United States","description":"United States of America","iSOCountryCode":"US","hasRegions":true,"regionName":"State","phoneNoFormat":"Y","addressPrintFormat":"@C@, @R@ @P@","additionalPostalCode":false,"default":true,"language":{"_identifier":"English (USA)","entityName":"ADLanguage","$ref":"ADLanguage\/192","id":"192","active":true},"currency":{"_identifier":"USD","entityName":"Currency","$ref":"Currency\/100","id":"100","active":true}}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Each of the properties of the Country object is present for example. client, id, iSOCountryCode etc. Openbravo JSON REST adds some special properties: _identifier and $ref which can be useful on the client. Each foreign key reference is also represented in a special way. for example the Country refers to the English (USA) language, the reference to that language is represented like this in the JSON string:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;"language":{"_identifier":"English (USA)","entityName":"ADLanguage","$ref":"ADLanguage\/192","id":"192","active":true}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;the 'language' is the property of the Country then within brackets the information of the language object itself is present. Adding this information in the returned JSON string has as advantage that it is not needed to do extra requests from client to server to display all the details of the Country object (including referenced objects).&lt;br /&gt;&lt;br /&gt;The JSON REST service also supports query and paging parameters, some examples:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://localhost:8080/openbravo/org.openbravo.service.json.jsonrest/Country"&gt;http://localhost:8080/openbravo/org.openbravo.service.json.jsonrest/Country&lt;/a&gt;: this will return all countries&lt;/li&gt;&lt;li&gt;&lt;a href="http://localhost:8080/openbravo/org.openbravo.service.json.jsonrest/Country?_startRow=10&amp;amp;_endRow=50&amp;amp;_sortBy=name"&gt;http://localhost:8080/openbravo/org.openbravo.service.json.jsonrest/Country?_startRow=10&amp;amp;_endRow=50&amp;amp;_sortBy=name&lt;/a&gt;   this will return 40 countries (rows 10 to 50) sorted by name&lt;/li&gt;&lt;li&gt;&lt;a href="http://localhost:8080/openbravo/org.openbravo.service.json.jsonrest/Country?name=United&amp;amp;_textMatchStyle=startsWith"&gt;http://localhost:8080/openbravo/org.openbravo.service.json.jsonrest/Country?name=United&amp;amp;_textMatchStyle=startsWith&lt;/a&gt; this url will return all countries which start with United (which are for example United Arab Emirates, United Kingdom and United States).&lt;/li&gt;&lt;li&gt;&lt;a href="http://localhost:8080/openbravo/org.openbravo.service.json.jsonrest/Country?_where=currency.iSOCode='USD'"&gt;http://localhost:8080/openbravo/&lt;/a&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); -webkit-text-decorations-in-effect: none; "&gt;&lt;a href="http://localhost:8080/openbravo/org.openbravo.service.json.jsonrest/Country?_where=currency.iSOCode='USD'"&gt;org.openbravo.service.json.&lt;/a&gt;&lt;/span&gt;&lt;a href="http://localhost:8080/openbravo/org.openbravo.service.json.jsonrest/Country?_where=currency.iSOCode='USD'"&gt;jsonrest/Country?_where=currency.iSOCode='USD'&lt;/a&gt; returns all countries which have a currency with the isocode USD. The _where parameter can contain a valid HQL where-clause. contain all the clauses supported by HQL. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;See the &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide/Concepts/JSON_Web_Services"&gt;JSON REST Developers Manual&lt;/a&gt; for more details on the querying capabilities and on the format of the returned information. The JSON REST module uses the same &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide/Concepts/REST_Web_Services#Login_and_Security"&gt;authentication and authorization&lt;/a&gt; functionality as the &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide/Concepts/REST_Web_Services"&gt;XML REST&lt;/a&gt; webservice functionality and the &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide/Concepts/Data_Access_Layer"&gt;data-access-layer&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The JSON REST service also supports insert, update and removal of information. To insert a new Country you have to post a message like shown below to the Openbravo application and use the POST HTTP method. To try this directly in your browser you can make use of a Firefox plugin like &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2691"&gt;poster&lt;/a&gt;.&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;{data: {"entityName":"Country","active":true,"name":"Test","description":"Test Country","iSOCountryCode":"ZZ","hasRegions":true,"regionName":"State","phoneNoFormat":"Y","addressP&lt;/span&gt;&lt;span style="font-size:85%;"&gt;rintFormat":"@C@, @R@ @P@","additionalPostalCode":false,"language":{"id":"192"},"currency":{"id":"100"}}}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_s9bF0uJ_pxo/SuYrGttK1iI/AAAAAAAAAD4/qEJYTKWYpnw/s1600-h/Screenshot-Poster.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 293px;" src="http://1.bp.blogspot.com/_s9bF0uJ_pxo/SuYrGttK1iI/AAAAAAAAAD4/qEJYTKWYpnw/s320/Screenshot-Poster.png" alt="" id="BLOGGER_PHOTO_ID_5397048597798376994" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;You see the result below. The system replies with a response JSON object which contains all the data of the inserted Country. The important one to take note of is the id.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_s9bF0uJ_pxo/SuYrddLO5lI/AAAAAAAAAEA/AEKZdk1PlOk/s1600-h/Screenshot-Response.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 306px; height: 320px;" src="http://4.bp.blogspot.com/_s9bF0uJ_pxo/SuYrddLO5lI/AAAAAAAAAEA/AEKZdk1PlOk/s320/Screenshot-Response.png" alt="" id="BLOGGER_PHOTO_ID_5397048988498060882" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;We will be using the id  in the next step to update the name of the Country to a better one (if you try this your self, the id will be for sure different!).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;{data: {"entityName":"Country","id":"FF80818124923C2C0124923D39A80002","name":"My Great Test Country"}}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The response will return the complete JSON object with a status code (0 for success).&lt;br /&gt;&lt;br /&gt;Then to clean up, let's delete the newly created country. Use this url (replacing the id part with your id) and do a DELETE HTTP method request:&lt;br /&gt;&lt;br /&gt;http://localhost:8080/openbravo/org.openbravo.service.json.jsonrest/Country/FF80818124923C2C0124923D39A80002&lt;br /&gt;&lt;br /&gt;A response with status 0 is returned with the deleted object as the data entry. This clean up action concludes this short tutorial. I hope you found it interesting.&lt;br /&gt;&lt;br /&gt;As always we welcome feedback. We will be using this module as part of our new Openbravo user interface development and extend it further based on new requirements.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5606774739693012337-2205179182170596902?l=mtopenbravo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mtopenbravo.blogspot.com/feeds/2205179182170596902/comments/default' title='Reacties plaatsen'/><link rel='replies' type='text/html' href='http://mtopenbravo.blogspot.com/2009/10/module-openbravo-json-rest-webservice.html#comment-form' title='0 reacties'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/2205179182170596902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/2205179182170596902'/><link rel='alternate' type='text/html' href='http://mtopenbravo.blogspot.com/2009/10/module-openbravo-json-rest-webservice.html' title='Module: Openbravo JSON REST Webservice!'/><author><name>Martin Taal</name><uri>http://www.blogger.com/profile/09522816133131499716</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://2.bp.blogspot.com/_s9bF0uJ_pxo/SWHZO15HsuI/AAAAAAAAAAM/4DGOFgBvDBc/S220/mtaal_photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_s9bF0uJ_pxo/SuYrGttK1iI/AAAAAAAAAD4/qEJYTKWYpnw/s72-c/Screenshot-Poster.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5606774739693012337.post-8986685631260601806</id><published>2009-09-16T06:31:00.000-07:00</published><updated>2009-09-15T19:45:41.595-07:00</updated><title type='text'>Selecting a new User Interface Framework/Library (comparing dojo, extjs and smartclient)</title><content type='html'>Openbravo is planning to re-design and re-implement the current user interface using both new user interface design paradigms as well as using new technology in a different  &lt;a href="http://wiki.openbravo.com/wiki/ERP/3.00/Projects/User_Interface_Model_and_Architecture#Client-Server_Architecture"&gt;architecture&lt;/a&gt;. The user experience re-design is being done by Rob Goris with some great &lt;a href="http://planet.openbravo.com/?author=6"&gt;results&lt;/a&gt; and a lot of &lt;a href="http://forge.openbravo.com/plugins/espforum/browse.php?group_id=100&amp;amp;forumid=886353"&gt;response&lt;/a&gt; from the community.&lt;br /&gt;&lt;br /&gt;On the more technical side we are currently in the process of selecting a new user interface framework/library. As many people have noted it is a difficult task to select a user interface framework. There are many good frameworks out there and also many people with strong opinions on what framework is the best. In the end of-course the main deciding factor is if a framework fits to the specific requirements of a web-based ERP.&lt;br /&gt;&lt;br /&gt;Next to the obvious selection criteria (open-source, mature, large community, cross-browser, etc.) there are also Openbravo specific selection criteria which play a role in the process:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;a framework should support our target architecture&lt;/li&gt;&lt;li&gt;a framework must work in a model-driven architecture with runtime re-generation of the user interface (in our new approach the user interface should be re-generated without restarting the application)&lt;/li&gt;&lt;li&gt;a framework should preferably be targeted for data-oriented web ui's (powerfull grids/forms/tabs play a vital role in these types of user interfaces).&lt;/li&gt;&lt;/ul&gt;We have decided to do this selection process in three steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;define a long list of user interface libraries&lt;/li&gt;&lt;li&gt;select a shorter list based on specific selection criteria&lt;/li&gt;&lt;li&gt;get the list down to a small number libraries and do a more detailed comparison and analysis&lt;/li&gt;&lt;/ol&gt;For the long list we considered a total of 22 different frameworks (see the complete list &lt;a href="http://wiki.openbravo.com/wiki/ERP/3.00/Projects/UI_Technology#Long_List"&gt;here&lt;/a&gt;). In the first cycle we cut down the long list to four, using &lt;a href="http://wiki.openbravo.com/wiki/ERP/3.00/Projects/UI_Technology#Selection_Criteria"&gt;these&lt;/a&gt; selection criteria. Based on further analysis and also some community feedback we decided on our final short list: &lt;a href="http://www.dojotoolkit.org/"&gt;dojo&lt;/a&gt;, &lt;a href="http://www.extjs.com/"&gt;extjs&lt;/a&gt; and &lt;a href="http://www.smartclient.com/"&gt;smartclient&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;At the moment we are in the last stage of the selection process and are doing a more thorough analysis of both dojo, extjs and smartclient. The process and conclusions can be found &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.60/Projects/UI_Technology/Analysis_extjs_dojo#Comparison"&gt;here&lt;/a&gt; (this page is under construction). The detailed analysis is being done by building targeted prototypes and studying available information such as the documentation, sample code, forum posts, tutorials and other information sources.&lt;br /&gt;&lt;br /&gt;As always we are interested in your feedback. Feel free to check out &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.60/Projects/UI_Technology/Analysis_extjs_dojo"&gt;this page&lt;/a&gt; and to give your own opinion and experience in &lt;a href="http://forge.openbravo.com/plugins/espforum/view.php?group_id=100&amp;amp;forumid=886353&amp;amp;topicid=6995962"&gt;this&lt;/a&gt; forum post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5606774739693012337-8986685631260601806?l=mtopenbravo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mtopenbravo.blogspot.com/feeds/8986685631260601806/comments/default' title='Reacties plaatsen'/><link rel='replies' type='text/html' href='http://mtopenbravo.blogspot.com/2009/08/selecting-new-user-interface.html#comment-form' title='0 reacties'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/8986685631260601806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/8986685631260601806'/><link rel='alternate' type='text/html' href='http://mtopenbravo.blogspot.com/2009/08/selecting-new-user-interface.html' title='Selecting a new User Interface Framework/Library (comparing dojo, extjs and smartclient)'/><author><name>Martin Taal</name><uri>http://www.blogger.com/profile/09522816133131499716</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://2.bp.blogspot.com/_s9bF0uJ_pxo/SWHZO15HsuI/AAAAAAAAAAM/4DGOFgBvDBc/S220/mtaal_photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5606774739693012337.post-2743559619006535314</id><published>2009-08-27T05:57:00.000-07:00</published><updated>2009-08-31T02:34:33.910-07:00</updated><title type='text'>Openbravo 2.50: The Developers Guide</title><content type='html'>Openbravo 2.50 has been released a few months ago, so some of you may have already noticed that as part of this release we created a completely new &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide"&gt;developers guide&lt;/a&gt;. This blog is to help spread the word even further that the developers guide is a great resource of information available for those of you who are customizing or developing on Openbravo 2.50.&lt;br /&gt;&lt;br /&gt;The  &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide"&gt;developers guide&lt;/a&gt; consists of different sections providing valuable information for starting developers, medium experienced as well as Openbravo expert developers. Here is an overview of these sections.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide/Introduction"&gt;introduction&lt;/a&gt; is relevant when starting development with Openbravo (see the Development Environment and Development Concepts sections) and for developers wanting to know more about the changes from 2.40 to 2.50 (see what's new and howto upgrade).&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide/HowTos"&gt;how-to&lt;/a&gt; sections describe Openbravo development topics using a focused development goal. There are how-tos on modularity, extending the datamodel, adding windows and webservices, the data access layer and more.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide/Fundamentals_and_Concepts"&gt;fundamentals and concepts&lt;/a&gt; chapter gives a detailed description of all relevant Openbravo ERP development concepts. The content ranges from common development topics (such as the project structure, build tasks) to modularity and the application dictionary. Each of the main layers of the application is discussed: database, middle-tier and web-tier with webservices.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide/Reference"&gt;reference&lt;/a&gt; section consists of a detailed description of the data model from different points of view: the database model, the entity model, the hibernate mapping and the REST XML Schema. In addition javadoc and other reference-like topics are discussed in this section.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide/Examples"&gt;examples&lt;/a&gt; section contains examples of existing code in the Openbravo ERP application. The purpose of this chapter is to give directions for the reader to study current Openbravo code and use that as the basis for own custom code&lt;br /&gt;&lt;br /&gt;A very useful section is the &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide/Common_Issues%2C_Tips_and_Tricks"&gt;tips and tricks&lt;/a&gt; section. The tips and tricks are based on experience and user questions and solutions in the forums.&lt;br /&gt;&lt;br /&gt;I hope that the developers guide is useful for you as a developer. Feel free to give feedback on the guide, especially if certain parts can be improved or if you miss certain information.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide"&gt;Happy reading!&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5606774739693012337-2743559619006535314?l=mtopenbravo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mtopenbravo.blogspot.com/feeds/2743559619006535314/comments/default' title='Reacties plaatsen'/><link rel='replies' type='text/html' href='http://mtopenbravo.blogspot.com/2009/08/openbravo-250-developers-guide.html#comment-form' title='0 reacties'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/2743559619006535314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/2743559619006535314'/><link rel='alternate' type='text/html' href='http://mtopenbravo.blogspot.com/2009/08/openbravo-250-developers-guide.html' title='Openbravo 2.50: The Developers Guide'/><author><name>Martin Taal</name><uri>http://www.blogger.com/profile/09522816133131499716</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://2.bp.blogspot.com/_s9bF0uJ_pxo/SWHZO15HsuI/AAAAAAAAAAM/4DGOFgBvDBc/S220/mtaal_photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5606774739693012337.post-8643434649970142313</id><published>2009-04-28T03:57:00.000-07:00</published><updated>2009-04-28T05:25:37.791-07:00</updated><title type='text'>Openbravo 2.50: Using the Model in your Application Code</title><content type='html'>As you may know Openbravo follows a &lt;a href="http://en.wikipedia.org/wiki/Model-driven_engineering"&gt;Model-Driven-Development&lt;/a&gt; (MDD) approach. The main theme of MDD is generating an application from a model. An aspect which is often ignored by traditional MDD methods is the availability of the model at runtime. Openbravo specifically pays attention to the runtime model and makes it available through an easy-to-use api.&lt;br /&gt;&lt;br /&gt;The main advantage of a runtime-model is that it is possible to develop very generic application functionality at model-level. Writing code at model-level is far more efficient than writing specific code for each table. Another advantage of model-level code is that it is often robust for model changes.&lt;br /&gt;&lt;br /&gt;Here are some examples of generic application functionality which can make use of the runtime model:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;security&lt;/li&gt;&lt;li&gt;import and export logic&lt;/li&gt;&lt;li&gt;archiving&lt;/li&gt;&lt;li&gt;tracking/tracing of changes&lt;/li&gt;&lt;/ul&gt;Some main concepts of the Openbravo runtime model:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The runtime model consists of a set of Entities.&lt;/li&gt;&lt;li&gt;An &lt;a href="https://code.openbravo.com/erp/devel/pi/file/35434a3a8037/src/org/openbravo/base/model/Entity.java"&gt;Entity&lt;/a&gt; is a domain concept like an Order or a Product. Currently in Openbravo an Entity is the same as a table (each table has an Entity representing it and vice versa).&lt;/li&gt;&lt;li&gt;An Entity has  a list of &lt;a href="https://code.openbravo.com/erp/devel/pi/file/35434a3a8037/src/org/openbravo/base/model/Property.java"&gt;Properties&lt;/a&gt;, for example an id, a name, a description. Some properties are primitives (string, number, etc.), some are single references (from an Order to a Currency), some are many references (from an Order to all its OrderLines). &lt;/li&gt;&lt;/ul&gt; To make use of the runtime model it is good to understand the Openbravo business object class model.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_s9bF0uJ_pxo/SexkqQ99pjI/AAAAAAAAACY/R-WoNbh3t2Y/s1600-h/runtime_model.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 199px;" src="http://1.bp.blogspot.com/_s9bF0uJ_pxo/SexkqQ99pjI/AAAAAAAAACY/R-WoNbh3t2Y/s320/runtime_model.png" alt="" id="BLOGGER_PHOTO_ID_5326743136544597554" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;As you can see, each &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide/Concepts/Data_Access_Layer#Openbravo_Business_Objects"&gt;business object&lt;/a&gt; (order, product, etc.) inherits from the &lt;a href="https://code.openbravo.com/erp/devel/pi/file/35434a3a8037/src/org/openbravo/base/structure/BaseOBObject.java"&gt;BaseOBObject&lt;/a&gt; class. The BaseOBObject class offers a number of important methods:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;getEntity(): to get access to the domain concept (=table) represented by this java class&lt;/li&gt;&lt;li&gt;get(String propName): get the value of a certain property&lt;/li&gt;&lt;li&gt;set(String propName, Object value): set the value of a certain property&lt;/li&gt;&lt;li&gt;getIdentifier(): returns a readable name for the business object&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;So while the specific subclass has specific set and get methods for each property, the main super class has generic set and get methods to set/get the value of all properties of a business object.&lt;br /&gt;&lt;br /&gt;In a runtime model-driven-development approach the code uses the runtime model and accesses objects as a generic BaseOBObject. In Openbravo 2.50 access to the runtime model is provided by the &lt;a href="https://code.openbravo.com/erp/devel/pi/file/35434a3a8037/src/org/openbravo/base/model/ModelProvider.java"&gt;ModelProvider&lt;/a&gt; class.&lt;br /&gt;&lt;br /&gt;I will illustrate the use of the ModelProvider class and the Openbravo runtime model in general with some example code.  This sample code exports all data in an Openbravo instance in just a few lines of code, the code executes the following steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;get all Entities from the ModelProvider&lt;/li&gt;&lt;li&gt;for each Entity get all records/instances from the databases&lt;br /&gt;&lt;/li&gt;&lt;li&gt;for each instance iterate over its properties and read the property value&lt;/li&gt;&lt;li&gt;create a string representation of that property value&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;// as we read all entities, be an administrator to prevent&lt;br /&gt;// security exceptions&lt;br /&gt;OBContext.getOBContext().setInAdministratorMode(true);&lt;br /&gt;&lt;br /&gt;// iterate over all entities&lt;br /&gt;for (Entity entity : ModelProvider.getInstance().getModel()) {&lt;br /&gt;&lt;br /&gt;// query for all objects of the entity and iterate over them&lt;br /&gt;final List&lt;baseobobject&gt; businessObjects = OBDal.getInstance().createCriteria(&lt;br /&gt; entity.getName()).list();&lt;br /&gt;for (BaseOBObject businessObject : businessObjects) {&lt;br /&gt;&lt;br /&gt;final StringBuilder line = new StringBuilder();&lt;br /&gt;&lt;br /&gt;// place the entity name so for each line it is known what type is exported there&lt;br /&gt;line.append(entity.getName());&lt;br /&gt;&lt;br /&gt;// and iterate over all the properties of the entity&lt;br /&gt;for (Property property : entity.getProperties()) {&lt;br /&gt; // ignore these type of properties, as the children are exported separately&lt;br /&gt; if (property.isOneToMany()) {&lt;br /&gt;   continue;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; line.append(SEPARATOR);&lt;br /&gt;&lt;br /&gt; // get the current value&lt;br /&gt; final Object value = businessObject.get(property.getName());&lt;br /&gt; // handle null&lt;br /&gt; if (value == null) {&lt;br /&gt;   continue;&lt;br /&gt; }&lt;br /&gt; // export primitives in the same way as xml primitives&lt;br /&gt; if (property.isPrimitive()) {&lt;br /&gt;   line.append(XMLTypeConverter.getInstance().toXML(value));&lt;br /&gt; } else {&lt;br /&gt;   // export the id of a referenced business object&lt;br /&gt;   line.append(((BaseOBObject) value).getId());&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;writer.append(line + "\n");&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/baseobobject&gt;&lt;/span&gt;&lt;/pre&gt;The data is appended to the writer object (which can be a FileWriter), with the BigBazaar Openbravo sample data this results in a file of about 13mb. The XMLTypeConverter is an Openbravo class which correctly converts primitive types such as a Date, a number, etc. to a String.&lt;br /&gt;&lt;br /&gt;You can copy the above code directly in a test case and run it (set the writer and SEPARATOR variables). For how-to create a test case in Openbravo see this &lt;a href="http://wiki.openbravo.com/wiki/ERP/2.50/Developers_Guide/How_to_create_testcases"&gt;how-to&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;An additional nice feature of the Openbravo runtime model is that all tables added by modules are automatically made part of the runtime model. So for Openbravo in the runtime model, there is no difference between an Openbravo core Entity/table or a custom module table/Entity.&lt;br /&gt;&lt;br /&gt;The runtime model is used extensively by the &lt;a href="http://mtopenbravo.blogspot.com/2009/01/openbravo-250-data-access-layer-in.html"&gt;Data Access Layer&lt;/a&gt; and &lt;a href="http://mtopenbravo.blogspot.com/2009/02/openbravo-250-rest-webservices.html"&gt;REST web services&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Well I hope that this blog gives some inspiration to try out coding at model level and to make use of the Openbravo runtime model. Thanks for reading, and feel free to ask any (detailed) questions on the Openbravo &lt;a href="http://forge.openbravo.com/plugins/espforum/browse.php?group_id=100&amp;amp;forumid=549512"&gt;deverlopers forum&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5606774739693012337-8643434649970142313?l=mtopenbravo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mtopenbravo.blogspot.com/feeds/8643434649970142313/comments/default' title='Reacties plaatsen'/><link rel='replies' type='text/html' href='http://mtopenbravo.blogspot.com/2009/04/openbravo-250-using-model-in-your.html#comment-form' title='0 reacties'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/8643434649970142313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/8643434649970142313'/><link rel='alternate' type='text/html' href='http://mtopenbravo.blogspot.com/2009/04/openbravo-250-using-model-in-your.html' title='Openbravo 2.50: Using the Model in your Application Code'/><author><name>Martin Taal</name><uri>http://www.blogger.com/profile/09522816133131499716</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://2.bp.blogspot.com/_s9bF0uJ_pxo/SWHZO15HsuI/AAAAAAAAAAM/4DGOFgBvDBc/S220/mtaal_photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_s9bF0uJ_pxo/SexkqQ99pjI/AAAAAAAAACY/R-WoNbh3t2Y/s72-c/runtime_model.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5606774739693012337.post-428985801430828461</id><published>2009-03-02T00:56:00.000-08:00</published><updated>2009-03-02T08:57:45.855-08:00</updated><title type='text'>Openbravo 2.50: REST Webservices</title><content type='html'>In this post I will talk about new very exciting functionality in Openbravo 2.50: full &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt; web services support for all tables in the Openbravo datamodel (including the tables added by modules).&lt;br /&gt;&lt;br /&gt;I will first start with a general overview and then some examples of web service calls which you can try directly in your browser. The post is concluded with a short description on how to add your own REST-like web services and a number of interesting links on REST.&lt;br /&gt;&lt;br /&gt;Openbravo REST provides a CRUD-like interface so that external applications can retrieve, update, create and delete business objects through standard &lt;a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods"&gt;HTTP requests&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Some benefits of using a REST approach:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; favors identifying and addressing resources which fits to the data-centric nature of the provided apis (a resource corresponds to a business object) &lt;/li&gt;&lt;li&gt; has actions (POST, PUT, DELETE, GET) which correspond to standard CRUD actions &lt;/li&gt;&lt;li&gt; allows linking to specific business objects or to sets of business objects. This is a very powerfull feature of a REST approach and it allows for easy navigation between business objects. &lt;/li&gt;&lt;li&gt; is simple to develop and use, and very lightweight from an architectural point of view &lt;/li&gt;&lt;/ul&gt;The Openbravo REST webservice operates on Business Objects in Openbravo. Before continuing let's first explain what a Business Object is (in Openbravo). A business object can be a simple entity (==table) such as a currency which just has basic primitive fields. On the other hand it can also be a structure of entities, for example an order header with its order line.&lt;br /&gt;&lt;br /&gt;Openbravo REST web services provide the following functionality:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; retrieve a single business object or a list of business objects using a standard HTTP GET request&lt;br /&gt;&lt;/li&gt;&lt;li&gt;querying, filtering, paging and sorting of lists of business objects, again through standard HTTP requests&lt;br /&gt;&lt;/li&gt;&lt;li&gt; update of an existing business object or multiple business objects through XML and a HTTP POST or PUT operation &lt;/li&gt;&lt;li&gt; creation of new business objects through a POST/PUT operation&lt;/li&gt;&lt;li&gt; export and import of data: xml files which contain a mix of different types of business objects and a mix of new and existing business object &lt;/li&gt;&lt;li&gt;delete operation using either a url pointing to a specific business object which needs to be removed or a XML document which contains business objects (as full xml or as partial xml) which need to be removed.&lt;/li&gt;&lt;/ul&gt;This functionality can be used for standard integration scenario's, but it can also be used to develop another UI on top of Openbravo using an alternative UI-technology (e.g. Flex).&lt;br /&gt;&lt;br /&gt;The Openbravo REST web services use the same access/authorizations as the standard Openbravo application. Before calling a web service the caller must log in. The login functionality is provided by the Openbravo REST framework. All REST actions are then executed in the context of a client/organization and current role of the user.&lt;br /&gt;&lt;br /&gt;Now let's go to some examples. When you have Openbravo running then you can try these out directly in your browser by entering the urls in your browser's address bar. Note that the examples assume that Openbravo runs locally on port 8080, it maybe necessary to replace the localhost:8080 part with your own server name/port. The examples assume that the web service user has access to the Country and Currency tables.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Query for all Countries: &lt;/li&gt;&lt;/ul&gt;&lt;a href="http://localhost:8080/openbravo/ws/dal/Country" target="wstest"&gt;http://localhost:8080/openbravo/ws/dal/Country&lt;/a&gt;&lt;ul&gt;&lt;li&gt;Get a specific Country (in this case Spain):&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a href="http://localhost:8080/openbravo/ws/dal/Country/106" target="wstest"&gt;http://localhost:8080/openbravo/ws/dal/Country/106&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Note that the xml returned contains both the Country and its children (Regions), i.e. a business object structure.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;An ordered example, query for all countries and return them ordered by ibanCode and regionName:&lt;/li&gt;&lt;/ul&gt;&lt;a href="http://localhost:8080/openbravo/ws/dal/Country?orderBy=iBANCode,regionName" target="wstest"&gt;http://localhost:8080/openbravo/ws/dal/Country?orderBy=iBANCode,regionName&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The same example with paging, returns 10 Countries starting from the 19th:&lt;/li&gt;&lt;/ul&gt;&lt;a href="http://localhost:8080/openbravo/ws/dal/Country?orderBy=iBANCode,regionName&amp;amp;firstResult=19&amp;amp;maxResult=10" target="wstest"&gt;http://localhost:8080/openbravo/ws/dal/Country?orderBy=iBANCode,regionName&amp;amp;firstResult=19&amp;amp;maxResult=10&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Do some filtering, only return countries which have a Currency with id 102 and a iBANLength of minimum 23:&lt;/li&gt;&lt;/ul&gt;&lt;a href="http://localhost:8080/openbravo/ws/dal/Country?where=currency=%27102%27%20and%20iBANLength%3E=23" target="wstest"&gt;http://localhost:8080/openbravo/ws/dal/Country?where=currency='102' and iBANLength&gt;=23&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(the where parameter can contain a &lt;a href="http://www.hibernate.org/hib_docs/reference/en/html/queryhql.html"&gt;Hibernate Query Language&lt;/a&gt; where clause)&lt;br /&gt;&lt;br /&gt;After trying some examples, the next question is which web services are provided by Openbravo, i.e. what url's are valid, what are the entity names and XML property names, what is valid xml? To answer this question Openbravo REST has a special web service which can be called. This web service generates a XML Schema of the available business objects and their elements (including the tables added by custom/external modules). You can try it yourselve on your local running Openbravo instance:&lt;br /&gt;&lt;a href="http://localhost:8080/openbravo/ws/dal/schema"&gt;http://localhost:8080/openbravo/ws/dal/schema&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;These first examples only retrieved data. The REST web services also have update/create/delete functions. To support web service testing, Firefox has a nice add-on: &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2691"&gt;Poster&lt;/a&gt;. This add-on allows you to POST/PUT XML to a URL. For these examples I again assume that you have Openbravo running locally. I will be creating a new currency, updating its precision and then deleting the currency.&lt;br /&gt;&lt;br /&gt;Here is an example of xml which can be used to create a new Currency:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;ob:Openbravo xmlns:ob="http://www.openbravo.com"&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;Currency&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;active&amp;gt;true&amp;lt;/active&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;iSOCode&amp;gt;OBD&amp;lt;/iSOCode&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;symbol&amp;gt;€&amp;lt;/symbol&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;description&amp;gt;Openbravo Dollars&amp;lt;/description&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;standardPrecision&amp;gt;2&amp;lt;/standardPrecision&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;costingPrecision&amp;gt;4&amp;lt;/costingPrecision&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;pricePrecision&amp;gt;4&amp;lt;/pricePrecision&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;currencySymbolAtTheRight&amp;gt;true&amp;lt;/currencySymbolAtTheRight&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;/Currency&amp;gt;&lt;br /&gt;&amp;lt;/ob:Openbravo&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;You can easily create this xml by retrieving a Currency through a url (for example, the &lt;a href="http://localhost:8080/openbravo/ws/dal/Currency/102" target="_new"&gt;euro&lt;/a&gt;) and then removing the XML parts related to id, client/organization and audit info.&lt;br /&gt;&lt;br /&gt;Click on the Poster icon (right-bottom in Firefox) and set the options as displayed in the image below.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_s9bF0uJ_pxo/SaORgPaJDaI/AAAAAAAAAA4/4QY0t7AHn0Y/s1600-h/REST_1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 298px; height: 320px;" src="http://3.bp.blogspot.com/_s9bF0uJ_pxo/SaORgPaJDaI/AAAAAAAAAA4/4QY0t7AHn0Y/s320/REST_1.png" alt="" id="BLOGGER_PHOTO_ID_5306244769050594722" border="0" /&gt;&lt;/a&gt;Note that the xml (displayed above) is entered in the Content field, the  Action is set to POST and the User Auth. fields contain the login and password. The user must have permissions to create a Currency. The standard Openbravo demo user has these capabilities.&lt;br /&gt;&lt;br /&gt;Then click on the first GO button, you should be seeing the following result:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_s9bF0uJ_pxo/SaOSLIQSIzI/AAAAAAAAABA/E35zX9Vcmjw/s1600-h/REST_2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 302px; height: 320px;" src="http://4.bp.blogspot.com/_s9bF0uJ_pxo/SaOSLIQSIzI/AAAAAAAAABA/E35zX9Vcmjw/s320/REST_2.png" alt="" id="BLOGGER_PHOTO_ID_5306245505864573746" border="0" /&gt;&lt;/a&gt;This xml gives a success message but more importantly it also gives the id back of the newly created object. This allows software, making REST calls, to use this id in further processing. In our case we can use this id to check if the currency was indeed created (note replace the id in the url with the id you received back):&lt;br /&gt;http://localhost:8080/openbravo/ws/dal/Currency/FF8081811FA6E26B011FA6EA2E9C0002&lt;br /&gt;&lt;br /&gt;Now as a next step let's update a field of the new Currency, in this case the precision is changed. The image below shows how this is done. The xml only has the field which needs to be updated and the id of the Currency is present as an xml attribute (to try-this-at-home, replace the id value with the one created in your case).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_s9bF0uJ_pxo/SaOnaVUQcaI/AAAAAAAAABI/5VgPSvM0D5w/s1600-h/REST_3.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 297px;" src="http://3.bp.blogspot.com/_s9bF0uJ_pxo/SaOnaVUQcaI/AAAAAAAAABI/5VgPSvM0D5w/s320/REST_3.png" alt="" id="BLOGGER_PHOTO_ID_5306268856813121954" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;And to clean up let's delete the new currency. This is done with a DELETE action, the url of the action needs to point to the business object which needs to be deleted (in this case the Currency created above).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_s9bF0uJ_pxo/SaOo8DndjBI/AAAAAAAAABQ/yDM9bmUQAjI/s1600-h/REST_4.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 194px;" src="http://3.bp.blogspot.com/_s9bF0uJ_pxo/SaOo8DndjBI/AAAAAAAAABQ/yDM9bmUQAjI/s320/REST_4.png" alt="" id="BLOGGER_PHOTO_ID_5306270535689014290" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The above actions can be performed for all of the 425+ tables in Openbravo. More importantly REST webservices automatically work out-of-the-box also for new tables added by modules.&lt;br /&gt;&lt;br /&gt;The delete action concludes the quick overview of the capabilities of Openbravo REST Webservices. The overview hopefully showed how easy it is to use REST webservices. Software talking to REST webservices need basic xml processing capabilities but that's the only real prerequisite.&lt;br /&gt;&lt;br /&gt;The Openbravo REST framework can be extended with new Webservices. See &lt;a href="http://wiki.openbravo.com/wiki/Projects/Data_Access_Layer/CrudWebServices#Adding_new_Webservices_.28using_a_module.29"&gt;here&lt;/a&gt; for more information. Openbravo REST takes care of security and exception handling. Web services can be added (installed/uninstalled) as part of a module.&lt;br /&gt;&lt;br /&gt;For more information:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://wiki.openbravo.com/wiki/Projects/Data_Access_Layer/CrudWebServices"&gt;REST Webservice Technical Design&lt;/a&gt;&lt;/li&gt;&lt;li&gt;REST test cases can be found in the openbravo development project in the src-test folder and then in the org.openbravo.test.webservice package&lt;/li&gt;&lt;/ul&gt;Here are some other interesting (non-Openbravo) links:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.ics.uci.edu/%7Efielding/pubs/dissertation/top.htm"&gt;Fielding's Dissertation&lt;/a&gt; (Mr. Fielding is the first one to explicitly define the REST concept)&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;Wikipedia on REST&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.xml.com/lpt/a/2004/12/01/restful-web.html"&gt;How to create a REST protocol&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.xfront.com/REST-Web-Services.html"&gt;Building Web Services the REST way&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Some links related to REST versus SOAP, there is a fair amount of articles on the web on this topic: &lt;/p&gt; &lt;ul&gt;&lt;li&gt; &lt;a href="http://searchsoa.techtarget.com/tip/0,289483,sid26_gci1227190,00.html" class="external text" title="http://searchsoa.techtarget.com/tip/0,289483,sid26_gci1227190,00.html" rel="nofollow"&gt;REST versus SOAP - the REST story&lt;/a&gt; &lt;/li&gt;&lt;li&gt; &lt;a href="http://www.networkworld.com/ee/2003/eerest.html" class="external text" title="http://www.networkworld.com/ee/2003/eerest.html" rel="nofollow"&gt;A RESTful approach to Web services&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5606774739693012337-428985801430828461?l=mtopenbravo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mtopenbravo.blogspot.com/feeds/428985801430828461/comments/default' title='Reacties plaatsen'/><link rel='replies' type='text/html' href='http://mtopenbravo.blogspot.com/2009/02/openbravo-250-rest-webservices.html#comment-form' title='0 reacties'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/428985801430828461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/428985801430828461'/><link rel='alternate' type='text/html' href='http://mtopenbravo.blogspot.com/2009/02/openbravo-250-rest-webservices.html' title='Openbravo 2.50: REST Webservices'/><author><name>Martin Taal</name><uri>http://www.blogger.com/profile/09522816133131499716</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://2.bp.blogspot.com/_s9bF0uJ_pxo/SWHZO15HsuI/AAAAAAAAAAM/4DGOFgBvDBc/S220/mtaal_photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_s9bF0uJ_pxo/SaORgPaJDaI/AAAAAAAAAA4/4QY0t7AHn0Y/s72-c/REST_1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5606774739693012337.post-4151549038292661708</id><published>2009-01-08T06:07:00.000-08:00</published><updated>2009-01-16T06:37:49.361-08:00</updated><title type='text'>Openbravo 2.50: Data Access Layer in the overall Openbravo Architecture</title><content type='html'>This post discusses the architecture of the new Data Access Layer and its place in the rest of the current and future envisioned architecture.&lt;br /&gt;&lt;br /&gt;The image below illustrates the different layers of the Openbravo architecture. Part of the architecture is delivered in 2.50 other parts will be delivered in future releases.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_s9bF0uJ_pxo/SWYJKMbZcvI/AAAAAAAAAAo/wPLMGhqIcho/s1600-h/DalOverviewSmaller.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 218px;" src="http://2.bp.blogspot.com/_s9bF0uJ_pxo/SWYJKMbZcvI/AAAAAAAAAAo/wPLMGhqIcho/s320/DalOverviewSmaller.jpg" alt="" id="BLOGGER_PHOTO_ID_5288924883132707570" border="0"&gt;&lt;/a&gt;&lt;br /&gt;The Data Access Layer (DAL) uses the application dictionary as the basis for its operations. The application dictionary defines the tables, columns and data types in Openbravo (for example Business Partner, Sales Order, etc.). The Data Access Layer uses the application dictionary for two purposes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;to generate Java business objects at development time&lt;/li&gt;&lt;li&gt;at runtime to generate a &lt;a href="http://www.hibernate.org/"&gt;Hibernate&lt;/a&gt; mapping to persist the business objects&lt;/li&gt;&lt;/ul&gt;To perform these two steps the DAL reads the application dictionary from the database and builds an in-memory representation. This is called the runtime model. Having the model in-memory makes it possible to use the model in an efficient way for different kinds of tasks (security checking, validation, etc.)&lt;br /&gt;&lt;br /&gt;So at development time Java business objects are &lt;a href="http://www.openarchitectureware.org/"&gt;generated&lt;/a&gt; for each table in the system. The columns of the table corresponds to properties (getters/setters) in the generated Java class. The foreign key columns are present as references to other generated business objects. The business object generation is done as part of the standard Openbravo build steps. The generated classes can be found in the src-gen folder in the openbravo development project.&lt;br /&gt;&lt;br /&gt;At runtime the DAL is responsible for generating the mapping for Hibernate and configuring Hibernate.&lt;br /&gt;The DAL provides an API to store, query and remove business objects from the database. This DAL service layer takes care of validation and security checks. In a future Openbravo release this API will be used to develop the business logic layer. The business logic layer will replace the current stored procedures and triggers. The business service layer will provide an API to the outside world to run business logic within Openbravo.&lt;br /&gt;&lt;br /&gt;Two other interesting components are also present: UI and Web Services. Integrating the DAL into the UI will be done in a future release. In 2.50 we provide a REST webservice layer which provides CRUD operations on all Openbravo business objects. I will discuss the REST Webservice support in the next post.&lt;br /&gt;&lt;br /&gt;At runtime the DAL takes care of transaction handling and providing a context in which all DAL operations run. The transaction handling is done using the &lt;a href="http://www.hibernate.org/43.html"&gt;open-session-in-view&lt;/a&gt; pattern whereby the developer in general does not need to take care of transaction handling explicitly (but he/she can ofcourse when required). The Openbravo context object makes it easy for a developer to retrieve the current user object and other context information.&lt;br /&gt;&lt;br /&gt;The following parts of the new architecture are delivered as part of 2.50:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Runtime Model&lt;/li&gt;&lt;li&gt;Generation of Business Object and Hibernate Mapping&lt;/li&gt;&lt;li&gt;DAL API&lt;/li&gt;&lt;li&gt;REST Webservices&lt;/li&gt;&lt;li&gt;Transaction Handling and User Context&lt;/li&gt;&lt;/ul&gt;The other components will be delivered as part of subsequent releases.&lt;br /&gt;&lt;br /&gt;For more information here are two wiki documents which give some more details:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://wiki.openbravo.com/wiki/Projects/Data_Access_Layer/Functional_Specification"&gt;DAL Functional Spec&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://wiki.openbravo.com/wiki/Projects/Data_Access_Layer/DAL_Developers_Manual"&gt;DAL Developers Guide&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;This hopefully gives a feel for the overall current and future architecture of Openbravo. In the next blog post I will discuss the new REST Webservice functionality in Openbravo 2.50.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5606774739693012337-4151549038292661708?l=mtopenbravo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mtopenbravo.blogspot.com/feeds/4151549038292661708/comments/default' title='Reacties plaatsen'/><link rel='replies' type='text/html' href='http://mtopenbravo.blogspot.com/2009/01/openbravo-250-data-access-layer-in.html#comment-form' title='0 reacties'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/4151549038292661708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/4151549038292661708'/><link rel='alternate' type='text/html' href='http://mtopenbravo.blogspot.com/2009/01/openbravo-250-data-access-layer-in.html' title='Openbravo 2.50: Data Access Layer in the overall Openbravo Architecture'/><author><name>Martin Taal</name><uri>http://www.blogger.com/profile/09522816133131499716</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://2.bp.blogspot.com/_s9bF0uJ_pxo/SWHZO15HsuI/AAAAAAAAAAM/4DGOFgBvDBc/S220/mtaal_photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_s9bF0uJ_pxo/SWYJKMbZcvI/AAAAAAAAAAo/wPLMGhqIcho/s72-c/DalOverviewSmaller.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5606774739693012337.post-7406943235625182776</id><published>2009-01-05T08:43:00.001-08:00</published><updated>2009-01-09T01:15:10.298-08:00</updated><title type='text'>Openbravo 2.50: New Architectural Developments: Data Access Layer and REST Webservices</title><content type='html'>The &lt;a href="http://paolojuvara.blogspot.com/2008/10/openbravo-erp-250-first-step-towards.html"&gt;Openbravo 2.50 release&lt;/a&gt; contains a number of new architectural developments which can be of great interest for Openbravo developers and system integrators.&lt;br /&gt;&lt;br /&gt;The first main development is the &lt;a href="http://en.wikipedia.org/wiki/Data_access_layer"&gt;Data Access Layer&lt;/a&gt; which provides the application developer with an object-oriented view on the Openbravo database. The Data Access Layer is also used to support new XML conversion functionality which allows the application developer to convert business objects from and to XML. The XML conversion logic again forms the basis for export and import of Client data and new &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Web_service"&gt;webservices &lt;/a&gt;functionality provided in Openbravo 2.50.&lt;br /&gt;&lt;br /&gt;I will cover these new developments in a series of posts which will be published the coming weeks.&lt;br /&gt;&lt;br /&gt;In this first post for Openbravo, let me also introduce myself. I am responsible for some of the new architecture developments at Openbravo, both design and development. My background is both in ERP system as well as technical Java coding. Next to Openbravo I am involved in open source development as a committer of the &lt;a href="http://www.eclipse.org/emf"&gt;Eclipse Modeling Framework&lt;/a&gt; project. I am looking forward to work further on extending the Openbravo architecture and hope for extensive feedback from the community on the new developments in the Openbravo 2.50 release.&lt;br /&gt;&lt;br /&gt;The starting point for the blog series will be the new Data Access Layer (DAL). The DAL provides an object-oriented layer over the Openbravo database. It is based on &lt;a href="http://www.hibernate.org/"&gt;Hibernate&lt;/a&gt; using model-driven code generation techniques. The Data Access Layer provides the application developer with the following functionality:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;type safe querying and retrieval of business objects from the database.&lt;/li&gt;&lt;li&gt;a convenient API to update or create new data in the database.&lt;/li&gt;&lt;li&gt;a type safe interface to update information of a business object, increased productivity by making the properties of a business object directly visible through getters and setters (in the development environment).&lt;/li&gt;&lt;li&gt;transaction and context handling.&lt;/li&gt;&lt;li&gt;security and validation checking.&lt;/li&gt;&lt;li&gt;automatically maps new entries in the application dictionary to database tables and columns.&lt;/li&gt;&lt;li&gt;generates Java class business objects (and their associations) on the basis of the Application Dictionary model. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;With the DAL the application developer does not need to type in tedious/type-unsafe sql queries. He/she can make use of the code completion and compile time checking functionality of his/her development environment. The Data Access Layer can also be easily integrated in test driven development approach as it operates independent from servlet containers such as &lt;a href="http://tomcat.apache.org/"&gt;Tomcat&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The Data Access Layer uses an in-memory representation of the application dictionary (the runtime model). This runtime model is used to convert business objects from and to XML. The XML conversion functionality is very usefull for integration scenarios. It is the basis for new functions such as the export and import of Client data and Webservice functionality. The XML Conversion functionality will be discussed in a separate technical post.&lt;br /&gt;&lt;br /&gt;The 2.50 release also provides completely new &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Web_service"&gt;webservice&lt;/a&gt; functionality. The REST webservice offers a common APO to query, retrieve and update all Openbravo business objects (persisted in the database). The REST webservice can be reached using simple (REST) URI's making it easy to use, test and try out. The Openbravo REST framework is easy to extend and allows you to add your own (REST) webservices. I will spend a separate post on REST Webservices and how to create your own WebService.&lt;br /&gt;&lt;br /&gt;This post was just an introduction to give you a feel for what is coming in 2.50. The next posts will dive into more details, starting with an architecture description followed by the standard Hello World DAL example!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5606774739693012337-7406943235625182776?l=mtopenbravo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mtopenbravo.blogspot.com/feeds/7406943235625182776/comments/default' title='Reacties plaatsen'/><link rel='replies' type='text/html' href='http://mtopenbravo.blogspot.com/2009/01/openbravo-250-new-architectural.html#comment-form' title='0 reacties'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/7406943235625182776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5606774739693012337/posts/default/7406943235625182776'/><link rel='alternate' type='text/html' href='http://mtopenbravo.blogspot.com/2009/01/openbravo-250-new-architectural.html' title='Openbravo 2.50: New Architectural Developments: Data Access Layer and REST Webservices'/><author><name>Martin Taal</name><uri>http://www.blogger.com/profile/09522816133131499716</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://2.bp.blogspot.com/_s9bF0uJ_pxo/SWHZO15HsuI/AAAAAAAAAAM/4DGOFgBvDBc/S220/mtaal_photo.jpg'/></author><thr:total>0</thr:total></entry></feed>
