Table of Contents
Preface
Chapter 1: Getting Started with OFBiz
Chapter 2: Working with OFBiz
Chapter 3: Screen Widgets
Chapter 4: Form Widgets
Chapter 5: Other View Element Types in Screen Widgets
Chapter 6: The Controller
Chapter 7: Entities, View Entities, and Extended Entities
Chapter 8: Accessing the Entities and View Entities
Chapter 9: The Events
Chapter 10: The Service Engine
Chapter 11: Permissions and the Service Engine
Chapter 12: Minilang
Chapter 13: Tying Up the Loose Ends
Chapter 14: Tips and Techniques
Appendix A: Simple Method User's Guide
Index
- Chapter 1: Getting Started with OFBiz
- Getting the OFBiz Code
- Downloading and Installing SVN
- Downloading TortoiseSVN
- Using SVN to Get OFBiz
- Our OFBiz Workspace—First Look
- Installing the Java Development Kit (JDK)
- Downloading JDK 5.0
- Installing JDK 5.0
- Downloading OFBiz Ready to Launch
- Setting Up an Eclipse Project
- Using Derby—the OFBiz Stock Database
- Compiling OFBiz and Loading the Data
- Verifying the Installation Process
- The Compilation Portion
- The Data Loading Portion
- Some Pre-Ignition Processes we won't do Twice
- Backing Up the Derby Data Files
- Running OFBiz
- Allocating Memory for OFBiz
- Starting OFBiz and Verifying the Start-Up Process
- Seeing the Logs in Real Time
- Possible Problems with Start-Up
- Allocating Memory for OFBiz
- Switching Off OFBiz
- Our First Tour of OFBiz
- Accessing OFBiz
- Exploring the Webapp "ecommerce"
- Let's Buy Something
- Exploring the Webapp "order"
- Receiving Payment
- Fulfilling the Order
- Invoice Automatically Generated with Payment Applied
- End-to-End Tour Completed
- Summary
- Chapter 2: Working with OFBiz
- Adding Our First Field
- Changing the Data
- Editing the Entity Definition
- Updating the Database
- Changing the Looks
- Editing the User-Interface
- Checking Our Changes
- Changing the Flow
- Rewiring the "Save" (Update Postal Address) Button
- Creating the New Widget Screen
- Creating the FTL File
- More to the Flow
- Some Changes Possible with Engines Running
- Changing the Data
- Resetting Our Play Area Quickly
- Skipping Some Pre-Ignition Processes
- Restoring Derby Data Files
- Removing the Web Server (Catalina) Work Files
- Updating the Database with Our Data Entity Changes
- Showing Off Our Spanking New OFBiz Installation
- Tripping Up Our Plan
- Storing a Save-Point to Dramatically Ease Testing
- Archiving Derby Data Files and Web Server Work Files
- Restoring a Save-Point
- Restoring the Derby Data Files
- Restoring the Web Server Work Files
- Computer, Run Scenario A from Last Save-Point
- Skipping Some Pre-Ignition Processes
- The Structure of OFBiz in General
- Components in OFBiz
- Referencing Components in OFBiz
- Creating Our Own OFBiz Component
- Creating the Component
- Using Our Component
- Cleaning Up Our Mess in the "party" Component
- Converting the BeanShell to a Java Event
- Clean Extension Strategies Employed
- Checking that Our Move was Successful
- A Bit More Mess Remains
- Webapps in OFBiz
- Creating Our First Webapp
- Webapp URIs in this Book
- Testing Our First Webapp
- The Model-View-Controller Architectural Pattern
- The MVC in Plain English
- The Model in OFBiz
- The View in OFBiz
- The Controller in OFBiz
- Other Files in an OFBiz Component
- The MVC in Plain English
- Summary
- Adding Our First Field
- Chapter 3: Screen Widgets
- Equipping Our Webapp with a Screen Widget View Handler
- Using the Screen Widget View Handler
- Files and Locations
- Creating Our First Screen Widget
- Defining a Screen Widget
- Informing the Control Servlet about the Screen Widget
- Referencing Screen Widgets
- Uniform Pattern of Flow in OFBiz
- Seeing Our First Screen Widget
- The Anatomy of the <section> Element
- Our First Conditional Screen Widget
- Element Order in the controller.xml
- Inform the Control Servlet about the Screen Widget
- If-Then-Else Structure
- The <if-condition> Element
- The Then—<actions> and <widgets> Elements
- The Else—<fail-widgets> Element
- The Minimum <section>
- Sending Parameters with Requests
- Seeing Our Conditional Screen Widget
- Screen Widget Context and Variables
- Utility Objects in Context
- Nested Sections for Nested Conditions
- Organizing a Large Screen into Smaller Screens
- The Global Context Revisited
- Outer Contexts Visible to Nested Ones
- Screen Widget's Integration with FreeMarker
- Cleaning Up in the "party" Component
- Commenting Changes to the Core Code
- Screen Widgets as Templates
- A Candidate for Templating
- Creating the Header
- Creating the Footer
- Using Our Header and Footer
- Seeing Our First Well-Formed XHTML Document
- Using Decorator Screen Widgets for Templating
- Creating a XHTML Decorator Screen
- Using the XHTML Decorator Screen
- Seeing Our First Decorator in Action
- Multiple Content Slots
- Creating the First Half of the Header
- Creating the Second Half of the Header
- Adding a Content Slot to a Decorator
- Using Our Multi-Slot Decorator
- Seeing Our First Multi-Slot Decorator
- Nesting Decorators
- Top-Down Approach (delegation)
- The Bottom-Up Approach (Vertical Stack)
- Using Both Approaches
- A Candidate for Templating
- Summary
- Chapter 4: Form Widgets
- Files and Locations
- Creating Our First Form Widget
- Creating the Containing Screen Widget
- Referencing Form Widgets
- Create the Form Widget
- Seeing Our First Form
- Understanding the Form Attributes
- Minimum Requirements to Use Form Widgets
- Including the Minimal Requirements
- Form Processing via Request Event
- Java Events
- Submitting and Processing Our First Form
- The "list" Type Form Widget
- Creating the Containing Screen
- Adding Form Processing Code
- Publishing the Form
- Seeing Our First "list" Type Form
- The "multi" Type Form Widget
- Creating the Containing Screen
- Loading Data for the Form
- Publishing the Form
- Creating the Form-Processing Logic
- Seeing Our First "multi" Type Form
- Alternative Targets in Two-Target Forms
- Creating the Form
- Creating the Containing Screen
- Publishing the Two-Target Form
- Seeing Our First Two-Target Form
- Row-Level Actions
- Creating the Form
- Creating the Containing Screen
- Publishing the Form
- Seeing the Form in Action
- Summary
- Chapter 5: Other View Element Types in Screen Widgets
- Menu Widgets
- Creating Our First Menu Widget
- Including Our Menu Widget in Our Screen Widgets
- Understanding the Menu Item Attributes
- Including the Menu Widget via a Decorator Screen Widget
- Add Screen Widget "ConditionalScreen" to the Menu
- Sub-Menus and Conditional-Menu Items
- Pre-processing Actions for Menu Widgets
- FreeMarker
- As Decorator Templates
- Displaying Dynamically Created List Variables
- Iterating Through the List
- Bringing it All Together
- The User-Interface Labels
- Adding the appheader
- Summary
- Menu Widgets
- Chapter 6: The Controller
- How OFBiz Hears Our Requests—The Control Servlet
- Defining a Control Servlet for a Webapp
- Using the Control Servlet
- Funnelling All Requests to the Single Control Servlet
- Defining Needed Utility Objects for the Control Servlet
- GenericDelegator Object
- The GenericDispatcher Object
- Some Background on Servlets
- Programming a Control Servlet
- Logging into Our Learning Application
- Specifying Handlers
- Request Maps
- Knocking on the Right Doors
- Security—Before Answering the Door
- The https Attribute
- The auth Attribute
- The direct-request Attribute
- Event—Determining a Response
- Java Events
- Response—Defining Various Responses
- View Maps
- Summary
- How OFBiz Hears Our Requests—The Control Servlet
- Chapter 7: Entities, View Entities, and Extended Entities
- Entities
- The Structure of the Data Model
- Referencing Fields of an Entity
- OFBiz Uses Relational Database Management Systems
- Curious Trivia about the Relational Model
- Entity Engine Concepts
- Datasources
- Entity Delegators
- Entity Groups
- Defining Our First Entity
- Assigning Our Entity to an Entity Group
- Loading Our Entity into the Entity Engine
- Seeing Our First Entity
- Using Our First Entity
- Creating a Drop-Down
- Populating the Drop-Down
- Expiring a Value
- Un-Expiring a Value
- Anatomy of an <entity> Element
- The <field> Element
- The <prim-key> Element
- The <relation> Element
- The <index> Element
- Relation Types
- One-to-One Relations
- One-to-Many Relations
- One-to-One Relations with No Foreign Keys
- View Entities
- Anatomy of a <view-entity>
- The <member-entity> Element
- The <alias> and <alias-all> Elements
- The <view-link> Element
- The <relation> Element
- Applying Functions on Fields
- Counting the Number of Records
- Counting Distinct Records
- Arithmetic Aggregate Functions
- Uppercase and Lowercase Functions
- Grouping for Summary Views
- Complex Aliases
- Nested <complex-alias> Elements
- Anatomy of a <view-entity>
- Extending Entities
- Summary
- Entities
- Chapter 8: Accessing the Entities and View Entities
- Setting-Up Our Playground
- The Script Processor
- The Generic Screen
- Creating the Screen Widget
- Creating the Form Widget
- Creating the FreeMarker File
- Publishing Our Generic Screen
- Testing Our Playground
- GenericValue Objects
- Creating a Database Record
- Why a Map is Used?
- Updating Database Records
- Deleting Database Records
- Retrieving Database Records
- Find Records by Conditions
- Conditions
- Comparison Operators (EntityComparisonOperator)
- Condition Lists
- Condition Joiners (EntityJoinOperator)
- Tools for Common Styles of Conditions
- Conditions Joined by AND
- Conditions Joined by OR
- Counting the Number of Records Retrieved
- OFBiz Date Condition
- Getting Related Records
- One-to-One Relations
- One-to-Many Relations
- Utilities for Post-Query processing
- Post-Query Ordering
- Post-Query Filtering by Conditions
- Post-Query Filtering by Date
- Other Post-Query Filtering Methods
- Find Records by Conditions
- Using the Entity Engine Cache
- Dynamic View Entities
- Left Outer Joins with the Dynamic View Entity
- Performing the Lookup
- EntityFindOptions
- Paginating Using the EntityListIterator
- Paginating through Party Records: A Working Example
- Functions and Dynamic View Entities
- Summary
- Setting-Up Our Playground
- Chapter 9: The Events
- Java Events
- Security and Access Control
- User Logins are like Access Cards
- Security Groups are like Access Levels
- Security Permissions are like Individual Secured Areas
- Security Permissions are Contained within Security Groups
- User Logins are Assigned Security Groups
- Dealing with Security in Java
- Sending Feedback to the End-User
- Conventions for Message Placeholders
- Testing the Conventions
- Handling Parameters
- Accessing Localized Messages
- Parameterizing Messages
- Catering for Multiple Languages
- Security and Access Control
- Working with the Database
- Summary
- Java Events
- Chapter 10: The Service Engine
- Defining a Service
- Creating the Java Code for the Service
- Testing Our First Service
- Service Parameters
- Input Parameters (IN)
- Output Parameters (OUT)
- Two Way Parameters (INOUT)
- Special Unchecked Parameters
- Optional and Compulsory Parameters
- The DispatchContext
- Service Security and Access Control
- Calling Services from Java Code
- Implementing Interfaces
- Overriding Implemented Attributes
- Synchronous and Asynchronous Services.
- Using the Job Scheduler
- Quickly Running a Service
- Naming a Service and the Service Reference
- Event Condition Actions (ECA)
- Service Event Condition Actions (SECAs)
- Entity Event Condition Actions (EECAs)
- Summary
- Chapter 11: Permissions and the Service Engine
- Simple Permissions
- Two-Part Permissions and Special "_ADMIN" Permissions
- Role Checks
- Combining Multiple Checks
- Nested Checks
- Complex Permissions
- Setting-Up Our Playground
- Creating the Request and View Maps
- Creating the Screen and Form Widgets
- Creating the Entity PlanetReview
- Defining Services that Require Complex Permission
- Implementing Services that Require Complex Permission
- Defining Permission Services
- Implementing Permission Services
- Playing with Complex Permissions
- Complex Permissions and Simple Permissions cannot be combined
- Setting-Up Our Playground
- Summary
- Chapter 12: Minilang
- What is Minilang?
- Tools to Code XML
- Defining a Simple Service
- Defining the Simple Service
- Writing the Simple Method
- Simple Events
- Validating and Converting Fields
- Validating a Simple Event Example
- Checking Security in Minilang
- Invoking from Minilang
- Calling Services from Minilang
- Calling Simple Methods
- Calling Java Methods
- Calling BeanShell
- Minilang in Screen Widgets
- Summary
- What is Minilang?
- Chapter 13: Tying Up the Loose Ends
- The OFBiz Look and Feel
- Changing the Customer Facing Site
- Changing the Back Office Screens
- The Header
- The Applications Bar (appbar)
- The Central Area
- The Footer
- Using FreeMarker
- OFBiz Transform Tags
- <@ofbizUrl>
- <@ofbizContentUrl>
- <@ofbizCurrency>
- Calling Java from FreeMarker
- OFBiz Transform Tags
- OFBiz Utilities
- UtilMisc
- UtilValidate
- UtilDateTime
- Debug
- The OFBiz Look and Feel
- Outputting Different Formats
- Outputting a PDF
- Summary
- Chapter 14: Tips and Techniques
- Debugging Techniques
- Logging
- console.log
- ofbiz.log
- Configuring the Logs
- Viewing the Logs through Webtools
- Writing Information to the Logs
- Logging Minilang
- Logging
- Debugging Java Code
- Passing in the VM Parameters
- Configuring the Remote Debugger
- Debugging Techniques
- Managing a Project Using Subversion
- Preparing the Repository and Creating the Project
- Step 1: Checking Out the Latest OFBiz Code
- Step 2: Making a Copy
- Step 3: Importing Our Copy
- Step 4: Branching ofbiz\current to Create the Trunk
- Getting the Latest Features and Bug Fixes
- Step 5: Updating OFBiz Current
- Step 6: Merging Changes between Revisions of OFBiz Current into Our Project
- Preparing the Repository and Creating the Project
- Apache HTTP Server and OFBiz using mod_proxy_ajp
- Installing the Apache HTTP Server
- What is mod_proxy_ajp?
- Configuring Apache HTTP Server to Use mod_proxy_ajp
- Configuring OFBiz to Use the AJP Connector
- Getting the Secure Pages to Work
- Configuring SSL in Apache
- Creating a Self-Signed SSL Certificate
- Going into Production
- Development Tips
- Summary
- Appendix A: Simple Method User's Guide
- <simple-methods>
- <simple-method>
- Call Operations
- <call-map-processor>
- <call-service> / <call-service-asynch>
- <set-service-fields>
- Handling the Results of Service Calls
- <results-to-map>
- <result-to-field>
- <result-to-request>
- <result-to-result>
- <call-bsh>
- <call-simple-method>
- <call-object-method>
- <call-class-method>
- Service Operations
- <field-to-result>
- Event Operations
- <session-to-field>
- Environment Operations
- <set>
- <clear-field>
- <first-from-list>
- Miscellaneous Entity Operations
- <sequenced-id-to-env>
- <make-next-seq-id>
- Entity Find Operations
- <entity-one>
- <entity-and>
- <entity-condition>
- Sub-Elements
- <condition-list>
- <having-condition-list>
- <select-fields>
- <order-by>
- <entity-condition> complete example:
- <entity-count>
- <get-related-one>
- <get-related>
- <order-value-list>
- <filter-list-by-and>
- <filter-list-by-date>
- Entity Value Operations
- <make-value>
- <clone-value>
- <create-value>
- <store-value>
- <refresh-value>
- <remove-value>
- <remove-related>
- <remove-by-and>
- <set-pk-fields> / <set-nonpk-fields>
- <store-list>
- Control Operations
- <iterate>
- <iterate-map>
- <check-errors>
- <add-error>
- <return>
- If Conditions
- <if-validate-method>
- <if-instance-of>
- <if-compare>
- <if-compare-field>
- Conditions:
- Other Operations
- <log>
- <now-timestamp-to-env>
- <now-date-to-env>
- <set-current-user-login>
- <calculate>