Add Employee detail provider.

Using Employee detail provider we can show/create/update Employee record. Employee is represented like JPA Entity

public class EmployeeDetailImpl extends OperationalDBDetailImpl {
        private Employee employee;
        /**
         * Creates EmployeeDetailImpl
         * @param viewProviderParams
         * @param dBViewProviderParameter
         */
        public EmployeeDetailImpl(ViewProviderParams viewProviderParams,ViewProviderDBParams dBViewProviderParameter) {
                super(viewProviderParams,dBViewProviderParameter);
        }

        private static String locPath = "ui/details/empDetail";
        
        /**  Employee components group */
        @SuppressWarnings("unused") //for labels
        public static class EmployeeDetailGroup extends AbstractReflexiveDetailCompsGroup{
                private static final long serialVersionUID = 1247188642428845570L;
                private LabelViewProviderComponent firstNameLbl = new LabelViewProviderComponentImpl(new LocKeyImpl(locPath,"firstNameLbl"));
                private LabelViewProviderComponent surNameLbl = new LabelViewProviderComponentImpl(new LocKeyImpl(locPath,"surNameLbl"));
                private LabelViewProviderComponent hireDateLbl = new LabelViewProviderComponentImpl(new LocKeyImpl(locPath,"hireDateLbl"));
                private TextFieldViewProviderComponent firstNameTxt = new TextFieldViewProviderComponentImpl("firstName");
                private TextFieldViewProviderComponent surNameTxt = new TextFieldViewProviderComponentImpl("surName");
                private DateFieldViewProviderComponent hireDateTxt = new DateFieldViewProviderComponentImpl("hireDate");
                
                /**
                 * Reads employee
                 * @param employee
                 */
                public void readEmployee(Employee employee){
                    firstNameTxt.setValue(employee.getFirstName());
                    surNameTxt.setValue(employee.getSurName());
                    hireDateTxt.setValue(employee.getHireDate());
                }
                
                /**
                 * Updates employee
                 * @param employee
                 */
                public void updateEmployee(Employee employee){
                        employee.setFirstName(firstNameTxt.getValue());
                        employee.setSurName(surNameTxt.getValue());
                        employee.setHireDate(hireDateTxt.getValue());
                }
        }
        
        private static class EmployeeDetailCompsDef extends AbstractReflexiveDetailCompsDef{
                private static final long serialVersionUID = 1686884731467995419L;
                
                private class Groups extends AbstractReflexiveDetailCompsDef.Groups{
                        private static final long serialVersionUID = 4211123167894108681L;
                        private EmployeeDetailGroup employeeGroup = new EmployeeDetailGroup();
                        private DepartmentDetailGroup departmentDetailGroup = new DepartmentDetailGroup(){
                                private static final long serialVersionUID = 0L;
                                @Override
                                protected void localizeComponent(LocalizationService localizationService,SettingsApplContext context, ViewProviderComponent comp) {
                                        localizeComponentWithTitlePrefix(localizationService, context, comp);
                                }
                        };
                        private OkCancelButtonsGroup buttonsGroup = new OkCancelButtonsGroup();
                }
                private Groups groups = new Groups();
                
                
                private EmployeeDetailCompsDef(){
                }
        }

        @Override
        protected String getLocPath() {
                return locPath;
        }

        @Override
        protected ViewProviderComponentContainer setupInitRootViewProviderComponentContainer() {
                EmployeeDetailCompsDef def = (EmployeeDetailCompsDef) ((DetailViewProviderInfo)viewProviderInfo).getDetailCompsDef();
                ViewProviderComponentContainer main = new ViewProviderComponentContainerImpl(ViewProviderConstants.MAIN_CONTAINER_ID,new ContainerGridLayoutImpl(2));
                def.groups.employeeGroup.addToGridContainer(main);
                def.groups.departmentDetailGroup.addToGridContainer(main);
                main.addComponent(new LabelViewProviderComponentImpl("empty",""));
                main.addComponent(def.groups.buttonsGroup.getGridContainer());
                return main;
        }
        
        @SuppressWarnings("unchecked")
        @Override
        protected DetailCompsDef createDetailCompsDef() {
                EmployeeDetailCompsDef empDef = new EmployeeDetailCompsDef();
                setupOkCancelButtons(empDef.groups.buttonsGroup);
                return empDef;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected DetailCompsDef readDataFromDB(DetailCompsDef def) throws ViewProviderException {
                EmployeeDetailCompsDef empDef = (EmployeeDetailCompsDef)def;
                CommandExecutorBS bs = businessServiceCreator.createRootService(CommandExecutorBS.class,session);
                try{
                        CommandExecutionResult<Employee> executeRequiresNew = bs.executeRequiresNew(new ReadCommand(callerContext.getLastCaller().getInitData(ViewProviderConstants.ID),empDef),
                                                                                                                                                                                        EmptyCommandExecutionEnv.getInstance(),
                                                                                                                                                                                        EmptyCommandEvent.getInstance());
                        employee = executeRequiresNew.get();
                        if(ViewProviderOperation.UPDATE.equals(operation)){
                                DetailViewUtils.setEditableToCompsGroup(empDef.groups.departmentDetailGroup,false);
                        }
                }
                catch(Exception e){
                        throw new ViewProviderException(getViewProviderID().getDef(),"Error reading data",e);
                }
                finally{
                        bs.close();
                }
                return def;
        }
        
        @Override
        protected DetailCompsDef setupInsertDef(DetailCompsDef def) {
                EmployeeDetailCompsDef empDef = (EmployeeDetailCompsDef)def;
                empDef.groups.departmentDetailGroup.nameTxt.setEditable(false);
                empDef.groups.employeeGroup.hireDateTxt.setValue(new Date());
                Object departmentId = null;
                if(callerContext != null && !callerContext.getCallers().isEmpty()){
                        departmentId = callerContext.getLastCaller().getInitData(Department.DEPARTMENT_ID_KEY);
                        if(departmentId == null ) {
                                if(callerContext.getLastCaller().getPrev() != null){
                                        departmentId = callerContext.getLastCaller().getPrev().getInitData(Department.DEPARTMENT_ID_KEY);
                                }
                        }
                        if(departmentId != null){
                                empDef.groups.departmentDetailGroup.codeTxt.setEditable(false);
                                DepartmentService depService = businessServiceCreator.createRootService(DepartmentService.class, session);
                                Department department = depService.findById(departmentId);
                                empDef.groups.departmentDetailGroup.readDepartment(department);
                        }
                }
                return def;
        }

        
        private static class ReadCommand extends AbstractCommand<Employee>{
                private static final long serialVersionUID = 1781615000344310393L;
                private Object id;
                private EmployeeDetailCompsDef empDef;
                private ReadCommand(Object id,EmployeeDetailCompsDef empDef) {
                        super();
                        this.id = id;
                        this.empDef = empDef;
                }
                @Override
                public Employee execute(ClientCommandExecutor executor,CommandExecutionEnv env, CommandEvent event) throws Exception {
                        CommandExecutorBS bs = (CommandExecutorBS) executor;
                        EmployeeService employeeService = bs.createChildService(EmployeeService.class);
                    Employee employee = employeeService.findById(id);
                    empDef.groups.employeeGroup.readEmployee(employee);
                    empDef.groups.departmentDetailGroup.readDepartment(employee.getDepartment());
                        return employee;
                }
        }
        
        private static class InsertCommand extends AbstractCommand<Employee>{
                private static final long serialVersionUID = 1781615000344310393L;
                private EmployeeDetailCompsDef empDef;
                private InsertCommand(EmployeeDetailCompsDef empDef) {
                        super();
                        this.empDef = empDef;
                }
                @Override
                public Employee execute(ClientCommandExecutor executor,CommandExecutionEnv env, CommandEvent event) throws Exception {
                        CommandExecutorBS bs = (CommandExecutorBS) executor;
                        DepartmentService ds = bs.createChildService(DepartmentService.class);
                        Department department = ds.findByCode(empDef.groups.departmentDetailGroup.codeTxt.getValue());
                        EmployeeService employeeService = bs.createChildService(EmployeeService.class);
                    Employee employee = new Employee();
                    employee.setId(IdHelper.nextId(employee.getClass()));
                    empDef.groups.employeeGroup.updateEmployee(employee);
                    employee.setDepartment(department);
                    employeeService.persist(employee);
                        return employee;
                }
        }


        @Override
        protected Command doInsert(DetailCompsDef def) throws ViewProviderException {
                EmployeeDetailCompsDef empDef = (EmployeeDetailCompsDef)def;
                CommandExecutorBS bs = businessServiceCreator.createRootService(CommandExecutorBS.class,session);
                try{
                        CommandExecutionResult<Employee> executeRequiresNew = bs.executeRequiresNew(new InsertCommand(empDef),EmptyCommandExecutionEnv.getInstance(),EmptyCommandEvent.getInstance());
                        employee = executeRequiresNew.get();
                }
                catch(Exception e){
                        throw new ViewProviderException(getViewProviderID().getDef(),"Error inserting employee",e);
                }
                return doAfterSucInsert(employee.getId());
        }

        @Override
        protected Command doUpdate(DetailCompsDef def) throws ViewProviderException{
                EmployeeDetailCompsDef empDef = (EmployeeDetailCompsDef)def;
                EmployeeDetailGroup employeeDetailGroup = empDef.groups.employeeGroup;
                employeeDetailGroup.updateEmployee(employee);
                EmployeeService employeeService = businessServiceCreator.createRootService(EmployeeService.class,session);
                employeeService.merge(employee);
                return doAfterSucUpdate(employee.getId());
        }       
}