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 LocKey locPrefix = new LocKeyImpl("detail/empDetail","empDetail");
        
        @Override
        protected LocKey getLocPrefix() {
                return locPrefix;
        }


        /**  Employee components group */
        @SuppressWarnings("unused") //for labels
        public static class EmployeeDetailGroup extends AbstractReflexiveCompsGroup{
                private static final long serialVersionUID = 1247188642428845570L;
                private LabelViewProviderComponent firstNameLbl = new LabelViewProviderComponentImpl(locPrefix.createChildKey("firstNameLbl"));
                private LabelViewProviderComponent surNameLbl = new LabelViewProviderComponentImpl(locPrefix.createChildKey("surNameLbl"));
                private LabelViewProviderComponent hireDateLbl = new LabelViewProviderComponentImpl(locPrefix.createChildKey("hireDateLbl"));
                private LabelViewProviderComponent workPositionLbl = new LabelViewProviderComponentImpl(locPrefix.createChildKey("workPositionLbl")); 
                private TextFieldViewProviderComponent firstNameTxt = new TextFieldViewProviderComponentImpl("firstName");
                private TextFieldViewProviderComponent surNameTxt = new TextFieldViewProviderComponentImpl("surName");
                private DateFieldViewProviderComponent hireDateTxt = new DateFieldViewProviderComponentImpl("hireDate");
                private AbstractViewProviderComponent workPositionFld;
                
                private EmployeeDetailGroup(ViewProviderOperation operation){
                        if(ViewProviderOperation.READ.equals(operation)){
                                workPositionFld = new TextFieldViewProviderComponentImpl("workPosition");
                        }
                        else{
                                workPositionFld = new ComboBoxViewProviderComponentImpl<WorkPosition>("workPosition");
                        }
                }
                /**
                 * Reads employee
                 * @param employee
                 */
                @SuppressWarnings("unchecked")
                public void readEmployee(Employee employee){
                    firstNameTxt.setValue(employee.getFirstName());
                    surNameTxt.setValue(employee.getSurName());
                    hireDateTxt.setValue(employee.getHireDate());
                    if(workPositionFld instanceof TextFieldViewProviderComponent){
                        workPositionFld.setValue(employee.getWorkPosition().toString());
                    }
                    else{
                        workPositionFld.setValue(employee.getWorkPosition());
                    }
                }
                /**
                 * Updates employee
                 * @param employee
                 */
                public void updateEmployee(Employee employee){
                        employee.setFirstName(firstNameTxt.getValue());
                        employee.setSurName(surNameTxt.getValue());
                        employee.setHireDate(hireDateTxt.getValue());
                        employee.setWorkPosition((WorkPosition) workPositionFld.getValue());
                }
        }
        
        /** Small Employee detail group */
        @SuppressWarnings("unused") //for labels
        public static class EmployeeSmallPrefixDetailGroup extends AbstractReflexiveCompsGroup{
                private static final long serialVersionUID = 1247188642428845570L;
                private LocPair<StringLocValue> title = new LocPairImpl<StringLocValue>(locPrefix.createChildKey("employee"));
                /** First Name label */
                public LabelViewProviderComponent firstNameLbl = new LabelViewProviderComponentImpl(locPrefix.createChildKey("firstNameLbl"));
                /** Surname label */
                public LabelViewProviderComponent surNameLbl = new LabelViewProviderComponentImpl(locPrefix.createChildKey("surNameLbl"));
                /** First name text */
                public TextFieldViewProviderComponent firstNameTxt = new TextFieldViewProviderComponentImpl("firstName");
                /** Surname txt */
                public TextFieldViewProviderComponent surNameTxt = new TextFieldViewProviderComponentImpl("surName");
                
                @Override
                protected void localizeComponent(LocalizationService localizationService,SettingsApplContext context, ViewProviderComponent comp) {
                        localizeComponentWithTitlePrefix(localizationService, context, comp);
                }
                
                
                /**
                 * Reads employee
                 * @param employee
                 */
                public void readEmployee(Employee employee){
                    firstNameTxt.setValue(employee.getFirstName());
                    surNameTxt.setValue(employee.getSurName());
                }
                /**
                 * Updates employee
                 * @param employee
                 */
                public void updateEmployee(Employee employee){
                        employee.setFirstName(firstNameTxt.getValue());
                        employee.setSurName(surNameTxt.getValue());
                }
        }
        
        
        private static class EmployeeDetailCompsDef extends AbstractReflexiveCompsDef{
                private static final long serialVersionUID = 1686884731467995419L;
                private class Groups extends AbstractReflexiveCompsDef.Groups{
                        private static final long serialVersionUID = 4211123167894108681L;
                        private EmployeeDetailGroup employeeGroup;
                        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;
                        private Groups(ViewProviderOperation operation){
                                employeeGroup = new EmployeeDetailGroup(operation);
                        }
                }
                private Groups groups;
                private EmployeeDetailCompsDef(ViewProviderOperation operation){
                        groups = new Groups(operation);
                }
        }

        @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);
                if(def.groups.buttonsGroup != null){
                        main.addComponent(new LabelViewProviderComponentImpl("empty",""));
                        main.addComponent(def.groups.buttonsGroup.getGridContainer());
                }
                return main;
        }
        
        @Override
        protected CompsDef createDetailCompsDef() {
                EmployeeDetailCompsDef empDef = new EmployeeDetailCompsDef(operation);
                empDef.groups.buttonsGroup = createOkCancelButtonsGroup();
                setupOkCancelButtons(empDef.groups.buttonsGroup);
                return empDef;
        }
        
        

        @Override
        protected void registerFetches(CompsDef def) {
                if(!ViewProviderOperation.INSERT.equals(operation)){
                        return;
                }
                EmployeeDetailCompsDef empDef = (EmployeeDetailCompsDef)def;
                ListViewProviderOpenInfo fetchOpenInfo = ListViewProviderOpenInfoDUImpl.newFrameOpenInfo(new ViewProviderDef(ViewProviderKind.ListViewProvider,EmpViewProvidersBindings.DEP_LIST));
                FetchDefImpl fetchDef = new FetchDefImpl("departmentFetch",fetchOpenInfo);
                fetchDef.addMapping(empDef.groups.departmentDetailGroup.codeTxt.getId(),ListViewUtils.getColumnId(DepartmentGroup.ID, DepartmentGroup.Columns.CODE.name));
                fetchDef.addMapping(empDef.groups.departmentDetailGroup.nameTxt.getId(),ListViewUtils.getColumnId(DepartmentGroup.ID, DepartmentGroup.Columns.NAME.name));
                registerFetch(fetchDef);
                empDef.groups.departmentDetailGroup.codeTxt.setFetchId(fetchDef.getFetchId());
        }

        @Override
        protected CompsDef readDataFromDB(CompsDef def) throws ViewProviderException {
                EmployeeDetailCompsDef empDef = (EmployeeDetailCompsDef)def;
                CommandExecutorBS bs = businessServiceCreator.createRootService(CommandExecutorBS.class,session);
                try{
                        CommandExecutionResult<Employee> executeRequiresNew = bs.executeRequiresNew(new ReadCommand(callerContext.getLastCaller().getCurrentDataValue(ViewProviderConstants.ID),empDef),
                                                                                                                                                                                        EmptyCommandExecutionEnv.getInstance(),
                                                                                                                                                                                        EmptyCommandEvent.getInstance());
                        employee = executeRequiresNew.get();
                        if(ViewProviderOperation.UPDATE.equals(operation)){
                                CompsDefUtils.setEditableToCompsGroup(empDef.groups.departmentDetailGroup,false);
                        }
                }
                catch(Exception e){
                        throw new ViewProviderException(getViewProviderID().getDef(),"Error reading data",e);
                }
                finally{
                        bs.close();
                }
                return def;
        }
        
        @SuppressWarnings("unchecked")
        @Override
        protected CompsDef setupInsertDef(CompsDef 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().getCurrentDataValue(Department.DEPARTMENT_ID_KEY);
                        if(departmentId == null ) {
                                if(callerContext.getLastCaller().getPrev() != null){
                                        departmentId = callerContext.getLastCaller().getPrev().getCurrentDataValue(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.readEntity(department);
                        }
                }
                WorkPositionService workPosService = businessServiceCreator.createRootService(WorkPositionService.class, session);
                ComboBoxViewProviderComponent workPosField = (ComboBoxViewProviderComponent) empDef.groups.employeeGroup.workPositionFld;
                workPosField.setValues(workPosService.findAllPositions());
                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;
                }
                @SuppressWarnings("unchecked")
                @Override
                public Employee execute(CommandExecutor executor,CommandExecutionEnv env, CommandEvent event) throws Exception {
                        CommandExecutorBS bs = (CommandExecutorBS) executor;
                        EmployeeService employeeService = bs.createChildService(EmployeeService.class);
                    Employee employee = employeeService.findById(id);
                        WorkPositionService workPosService = bs.createChildService(WorkPositionService.class);
                        if(empDef.groups.employeeGroup.workPositionFld instanceof ComboBoxViewProviderComponent){
                                ComboBoxViewProviderComponent workPosField = (ComboBoxViewProviderComponent) empDef.groups.employeeGroup.workPositionFld;
                                workPosField.setValues(workPosService.findAllPositions());
                        }
                    
                    empDef.groups.employeeGroup.readEmployee(employee);
                    empDef.groups.departmentDetailGroup.readEntity(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(CommandExecutor 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(CompsDef 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(CompsDef 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());
        }

        @Override
        protected Long getCurrentData() {
                return employee != null ? employee.getId() : null;
        }       
        
        
}