Difference between revisions of "Java Wrapper for OFBiz Services"
m |
m (→Changes from 1.4 preview 2) |
||
Line 83: | Line 83: | ||
String partyId = (String) mapValue.get(ExampleService.Out.partyId.getName()); | String partyId = (String) mapValue.get(ExampleService.Out.partyId.getName()); | ||
− | == Changes | + | == Changes in 1.4 preview 3 == |
− | Note that from opentaps 1.4 preview 3 and later, the | + | Note that from opentaps 1.4 preview 3 and later, the java package has been changed from <tt>org.opentaps.domain.base.services</tt> to <tt>org.opentaps.base.services</tt>. |
Latest revision as of 06:17, 2 December 2009
Starting with opentaps 1.4 (after preview 2), opentaps will provide Java objects as wrappers for services defined with the ofbiz service engine, including both ofbiz and legacy opentaps services. These "service wrapper POJOs" are automatically generated along with the base entity classes using ant make-base-entities.
These service wrappers can be used instead of raw Maps to set or get the service parameters in a type-safe way. The POJOs are in org.opentaps.base.services package and named after the original service definition (converted to a valid java class name.) For example: createInventoryItem is CreateInventoryItemService, opentaps.runMrp is OpentapsRunMrpService.
The main benefit is that each parameter is guaranteed to exist and be of the correct type by the compiler. This makes code maintenance much easier if the service definitions are changed. In addition, an IDE such as Eclipse can help discover the service parameters via autocompletion. If a service is defined multiple time the wrapper class reflects the actual service definition as seen by the service engine.
Contents
Calling a service
For example if there is a service named example with inputs: a String partyId and a BigDecimal amount, and output partyId:
ExampleService service = new ExampleService(); service.setInPartytId("somePartyId"); service.setInAmount(new BigDecimal("40.0"));
// if the service requires authentication you can either use a User instance service.setUser(someUser); // note that this is not setInUser since "user" is not really a defined IN parameter of the service // or a GenericValue userLogin instance service.setInUserLogin(someUserLogin);
// calling the service requires an Infrastructure instance service.runSync(infrastructure); // or it is also possible to specify that a new transaction is not necessary service.runSyncNoNewTransaction(infrastructure);
// getting the service results parameters and status if (service.isSuccess()) { String exampleOutput = service.getOutPartyId(); } else if (service.isError()) { // getting the service error message Debug.logError(service.getErrorMessage(), MODULE); }
Calling a service from inside a POJO service can be done using the runSync helper method provided by the Service class:
ExampleService service = new ExampleService(); service.setInPartytId("somePartyId"); service.setInAmount(new BigDecimal("40.0")); // this helper method will auto set the current User and Infrastructure // and also avoids creating a new transaction // on service error, a ServiceException is thrown so there is no need to test for // the status in most cases runSync(service); // at this point the service must have succeeded String exampleOutput = service.getOutPartyId();
Using the wrapper inside its service definition
The wrappers can also be used inside the service definition method to read the inputs. Following the same example as above:
public static Map<String, Object> exampleServiceImplementation(DispatchContext dctx, Map<String, Object> context) { ExampleService service = ExampleService.fromInput(context); String partyId = service.getInPartyId(); BigDecimal amount = service.getInAmount(); // internal parameters are also available Locale locale = service.getInLocale(); TimeZone timezone = service.getInTimeZone(); // the user is available both as a GenericValue and a User instance GenericValue userLogin = service.getInUserLogin(); User user = service.getUser(); // note that this is not getInUser since "user" is not really a defined IN parameter of the service ... String resultPartyId = "resultPartyId"; // the actual service implementation ... // then out parameter can be set in the same wrapper instance service.putAllOutput(ServiceUtil.returnSuccess()); // all the methods from ServiceUtil or UtilMessage normally used // to build the output map can be used here, for success / error or failure service.setOutPartyId(resultPartyId); return service.outputMap(); }
Static fields
In addition to the accessors to get or set the inputs or outputs parameters, each wrapper defines an In and Out static enum. Following the example from above, you may also refer to the service parameters like this:
Map<String, Object> input = UtilMisc.toMap( ExampleService.In.partyId.getName(), "somePartyId", ExampleService.In.amount.getName(), new BigDecimal("40.0"), ExampleService.In.userLogin.getName(), someUserLogin); Map<String, Object> output = dispatcher.runSync(ExampleService.NAME, input); String partyId = (String) mapValue.get(ExampleService.Out.partyId.getName());
Changes in 1.4 preview 3
Note that from opentaps 1.4 preview 3 and later, the java package has been changed from org.opentaps.domain.base.services to org.opentaps.base.services.