Logic Component

The logic component provides data for the UI component and executes actions that are triggered by UI events.

Each Tile has its own controller, represented by the MAFTileController interface, to accomplish these tasks. Data for tiles can come directly from the data component, or from a local or global tile context. Tile contexts objects hold temporary references to the Business Objects and UI, or to logic component related parameters. You can group and reference Business Objects by MAFBinding objects, which contain the information needed to retrieve Business Objects from the back-end.

MAFParameters that are set in MAFTileContext or MAFGlobalContext objects can hold any objects as a parameter value, including MAFBusinessObjects. An example of this is when you pass the selected Business Object while you navigate from a list screen to a detail screen.

To browse the contents of tile and global context objects, get a copy of them from a MAFTileController, however, these copies cannot be modified. To change the tile and global context, use the setContextParameter() or setGlobalParameter() setter methods of the controller objects.

MAFTileControllers keep the proper states of the Tile and Global Context, and ensure the proper timing of data retrieval and action execution. As screen tiles can be nest, tile controllers must also cooperate with their parent controller.

The framework provides ways to interact with MAFTileControllers, to decorate them or to override them. To use or modify tile controllers, each application must register its own MAFApplicationTileControllerCreator object during the creation of MAFCore. This creator object is notified each time a TileController is to be created. At this point, you can:
  • Let the framework create the TileController.
  • Replace the TileController with your own implementation.
  • Decorate the created TileController with additional or modified functionality.

MAFTileController provides two methods for action execution: performActions() and performAction(). Timing the execution of a set of actions is complex, because of the different execution methods (long-running and instant actions), and because you can override the behavior of any single action.

The performActions() method handles action execution, ensuring that actions in the execution chain wait for previous actions to finish, even if they run in the background. The performActions() method uses the performAction() method as a call-back to execute a single action. If you do not need a different execution mechanism, in a decorator class you can decorate only the performAction() method, not the threading.

However, a decorated object is unaware of the decorator object, so it cannot invoke the performAction() method of the decorator controller. To avoid implementing a complex action execution mechanism, MAFExtensibility provides a predefined action execution class, the MAFDefaultActionExecutor class:
	// MAFCore is the main object to deal with MAF Extensibility
	// MAFCore should be built before MAF Extensibility features can be used
        MAFCoreBuilder mafCoreBuilder = new MAFCoreBuilder(this, false);

        //Registering application Tile Controller Creator
        mafCoreBuilder.setApplicationTileControllerCreator(new MyControllerCreator());
        
	…

	private class MyControllerCreator implements MAFApplicationTileControllerCreator {

		@Override
		public boolean beforeCreateTileController(String tileId,
				MAFTileContext mafTileContext,
				MAFGenericBOManager mafBoManager, MAFGlobalContext globalContext) {
			//Let the framework to do the controller creation
			return false;
		}

		@Override
		public MAFTileController createTileController(String tileId,
				MAFTileContext mafTileContext,
				MAFGenericBOManager mafBoManager, MAFGlobalContext globalContext) {
			//Will be never invoked as beforeCreateTileController return false always 
			return null;
		}

		@Override
		public MAFTileController afterCreateTileController(
				MAFTileController tileController, String tileId,
				MAFTileContext mafTileContext,
				MAFGenericBOManager mafBoManager, MAFGlobalContext globalContext) {
			//Return a new Decorator object
			return new MyController(tileController);
		}

	}
	
	private class MyController implements MAFTileController {
		
		private MAFTileController decoratedController;
		
		//Create a new actionExecutor that can handle the default action execution taking care of the proper timing and synchronization 
		private MAFActionExecutor actionExecutor = new MAFDefaultActionExecutor(this);
		
		public MyController(MAFTileController decoratedController) {
			this.decoratedController = decoratedController;
		}

		@Override
		public MAFDataResult getData(List<MAFBinding> bindings,
				boolean reloadData, boolean updateContext,
				MAFDataProgressListener listener) {
			//use the default bahviour
			return decoratedController.getData(bindings, reloadData, updateContext, listener);
		}

		
		@Override
		public MAFPerformResult performActions(MAFActivityState activityState,
				List<MAFAction> actions, String eventId,
				String sourceElementId, Object sourceElement, MAFTile tile,
				MAFPerformProgressListener listener) {
			//use the actionExecutor to handle the default action execution taking care of the proper timing and synchronization
			//Note: we can not use the decorated controller's same method here as it is not aware of this class so it would not be ablte to call back 
			//the getActionInfo() and the performAction() method of this object
			return actionExecutor.performActions(activityState, actions, eventId, sourceElementId, sourceElement, tile, listener);
		}

		@Override
		public MAFActionInfo getActionInfo(MAFAction action,
				MAFActivityState activityState, String eventId,
				String sourceElementId, Object sourceElement, MAFTile tile) {
			if ("MyActionId".equals(action.getId())) {
				//set our action as an instant action that should not be delegated to the parent controller
				return new MAFActionInfo(false, false);
			}
			return decoratedController.getActionInfo(action, activityState, eventId, sourceElementId, sourceElement, tile);
		}

		@Override
		public void performAction(MAFAction action,
				MAFActivityState activityState, String eventId,
				String sourceElementId, Object sourceElement, MAFTile tile) {
			//If the current action is our action, execute it...
			if ("MyActionId".equals(action.getId())) {
			}
			//... otherwise let the decorated controller to do its job 
			decoratedController.performAction(action, activityState, eventId, sourceElementId, sourceElement, tile);
		}

		…
		
	}