/* * Copyright 2015 Bekwam, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.bekwam.examples.javafx.accesscontrol; import javafx.application.Platform; import javafx.fxml.FXML; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.util.StringConverter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; /** * @author carl_000 */ public class MainViewController { private Logger log = LoggerFactory.getLogger(MainViewController.class); @FXML MenuItem miA; @FXML MenuItem miB; @FXML MenuItem miC; @FXML Button tbA; @FXML Button tbB; @FXML Button tbC; @FXML Button btnA; @FXML Button btnB; @FXML Button btnC; @FXML ChoiceBox<UserSecurity> cbUser; enum AccessType { HIDE, DISABLE, SHOW } enum CommandType {A, B, C} enum NodePropertiesKeyType { commandType } @FXML public void initialize() { miA.getProperties().put(NodePropertiesKeyType.commandType, CommandType.A ); tbA.getProperties().put(NodePropertiesKeyType.commandType, CommandType.A ); btnA.getProperties().put(NodePropertiesKeyType.commandType, CommandType.A ); miB.getProperties().put(NodePropertiesKeyType.commandType, CommandType.B ); tbB.getProperties().put(NodePropertiesKeyType.commandType, CommandType.B ); btnB.getProperties().put(NodePropertiesKeyType.commandType, CommandType.B ); miC.getProperties().put(NodePropertiesKeyType.commandType, CommandType.C ); tbC.getProperties().put(NodePropertiesKeyType.commandType, CommandType.C); btnC.getProperties().put(NodePropertiesKeyType.commandType, CommandType.C); Map<CommandType, AccessType> access1 = new LinkedHashMap<>(); access1.put(CommandType.A, AccessType.HIDE); access1.put(CommandType.B, AccessType.HIDE); access1.put(CommandType.C, AccessType.HIDE); UserSecurity s1 = new UserSecurity("Carl (No Access)", access1 ); Map<CommandType, AccessType> access2 = new LinkedHashMap<>(); access2.put( CommandType.A, AccessType.SHOW ); access2.put( CommandType.B, AccessType.HIDE ); access2.put( CommandType.C, AccessType.DISABLE ); UserSecurity s2 = new UserSecurity("Ralph (Some Access)", access2 ); Map<CommandType, AccessType> access3 = new LinkedHashMap<>(); access3.put( CommandType.A, AccessType.SHOW ); access3.put(CommandType.B, AccessType.SHOW); access3.put(CommandType.C, AccessType.SHOW); UserSecurity s3 = new UserSecurity("Jim (All Access)", access3 ); cbUser.setConverter(new StringConverter<UserSecurity>() { @Override public String toString(UserSecurity object) { return object.getName(); } @Override public UserSecurity fromString(String string) { if (string == null) return null; if (string.equalsIgnoreCase("Carl (No Access)")) { return s1; } if (string.equalsIgnoreCase("Ralph (Some Access)")) { return s2; } if (string.equalsIgnoreCase("Jim (All Access)")) { return s3; } return null; } }); cbUser.getItems().addAll(s1, s2, s3); cbUser.getSelectionModel().select(s1); cbUser.getSelectionModel().selectedItemProperty().addListener( (ov, oldV,newV) -> applySecurity(cbUser.getScene()) ); } /** * Must be called after @FXML initialize() b/c Scene won't be available */ public void init() { applySecurity(cbUser.getScene()); } class UserSecurity { private final String name; private final Map<CommandType, AccessType> access; public UserSecurity(String name, Map<CommandType, AccessType> access) { this.name = name; this.access = access; } public String getName() { return name; } public AccessType getAccess(CommandType command) { Objects.requireNonNull(access); AccessType a = access.get( command ); Objects.requireNonNull(a); return a; } } private void applySecurity(Scene s) { if( log.isDebugEnabled() ) { log.debug("[APPLY]"); } applySecurity(s, cbUser.getSelectionModel().getSelectedItem(), s.getRoot()); } private void applySecurity(Scene s, UserSecurity security, Node n) { if( n == null ) return; if( n.getProperties().containsKey(NodePropertiesKeyType.commandType) ) { // // This is a Node that should have security applied // CommandType command = (CommandType) n.getProperties().get(NodePropertiesKeyType.commandType ); AccessType access = security.getAccess(command); if( log.isDebugEnabled() ) { log.debug("[APPLY] command={}, access={}", command, access); } switch( security.getAccess(command) ) { case SHOW: n.setVisible(true); n.setDisable(false); n.setManaged(true); break; case HIDE: n.setVisible(false); n.setDisable(true); n.setManaged(false); break; case DISABLE: n.setVisible(true); n.setDisable(true); n.setManaged(true); break; } } // // Menus and MenuItems are not Nodes // if( n instanceof MenuBar ) { MenuBar mb = (MenuBar)n; for( Menu toplevel : mb.getMenus() ) { applySecurity( s, security, toplevel ); } } if( n instanceof Parent) { Parent p = (Parent)n; for( Node childNode : p.getChildrenUnmodifiable() ) { applySecurity( s, security, childNode ); } p.layout(); } } private void applySecurity(Scene s, UserSecurity security, MenuItem mi) { if( mi == null ) return; if( mi.getProperties().containsKey(NodePropertiesKeyType.commandType) ) { // // This is a Node that should have security applied // CommandType command = (CommandType) mi.getProperties().get(NodePropertiesKeyType.commandType ); AccessType access = security.getAccess(command); if( log.isDebugEnabled() ) { log.debug("[APPLY] command={}, access={}", command, access); } switch( security.getAccess(command) ) { case SHOW: mi.setVisible(true); mi.setDisable(false); break; case HIDE: mi.setVisible(false); mi.setDisable(true); break; case DISABLE: mi.setVisible(true); mi.setDisable(true); break; } } if( mi instanceof Menu ) { Menu m = (Menu)mi; for( MenuItem childMI : m.getItems() ) { applySecurity( s, security, childMI ); } } } @FXML public void close() { Platform.exit(); } }