我使用DynamicMenuContent
/**
* Presenter that displays menu item if, and only if the user has the specified role.
*/
public class RoleMenuPresenter
extends JMenuItem
implements DynamicMenuContent {
private static final JComponent[] EMPTY = new JComponent[0];
private final String roleName;
private final AuthenticationDelegate delegate = (AuthenticationDelegate) SpringSingleton
.getBean("authenticationDelegate");
private final JComponent[] components = {this};
private final JComponent[] emptyComponents = EMPTY;
//~ Constructors ===================================================================================================
/**
* Constructs this presenter.
*
* @param a action to execute
* @param roleName the rolename
*/
public RoleMenuPresenter(Action a, String roleName) {
super(a);
this.roleName = roleName;
}
//~ Methods ========================================================================================================
@Override
public JComponent[] getMenuPresenters() {
if (delegate.getStatusBean().hasRole(roleName)) {
return components;
}
return emptyComponents;
}
@Override
public JComponent[] synchMenuPresenters(JComponent[] jComponents) {
return getMenuPresenters();
}
public String getRoleName() {
return roleName;
}
public interface Provider
extends Presenter.Menu {
@Override
RoleMenuPresenter getMenuPresenter();
}
}
安全Action
实施RoleMenuPresenter.Provider
。菜单项按预期隐藏。但是,如果隐藏了菜单的所有项目,则会出现问题,仍然会显示菜单。例如:
如果隐藏了A,B和C,则交易仍然可见。我的问题是如何自动隐藏交易?谢谢。
答案 0 :(得分:0)
我终于成功了。 JavaScript
用于计算空文件夹路径。 MenuFolderUtil
用于预热菜单。 ReheatMenus
是文件系统提供程序,用于在内存DynamicLayerContent
文件夹中提供。 *_hidden
是主要条目。
MenuVisibilityUtil
final class MenuFolderUtil {
static Set<String> findEmptyFolder() {
Set<String> folderPaths = new LinkedHashSet<>();
FileObject file = FileUtil.getConfigFile("Menu");
Enumeration<? extends FileObject> folderEnumerations = file.getFolders(
true);
while (folderEnumerations.hasMoreElements()) {
FileObject element = folderEnumerations.nextElement();
folderPaths.add(element.getPath());
}
Enumeration<? extends FileObject> childrenEnum = file.getChildren(true);
while (childrenEnum.hasMoreElements()) {
FileObject element = childrenEnum.nextElement();
if (element.isFolder()) {
continue;
}
FileObject parent = element.getParent();
String parentPath = parent.getPath();
if (!folderPaths.contains(parentPath)) {
continue;
}
Action action = FileUtil.getConfigObject(
element.getPath(),
Action.class);
if (action instanceof Presenter.Menu) {
JMenuItem presenter = ((Presenter.Menu) action).getMenuPresenter();
if (presenter instanceof DynamicMenuContent) {
treatDynamicMenuContent(
(DynamicMenuContent) presenter,
folderPaths, buildParentPaths(element));
} else {
folderPaths.removeAll(buildParentPaths(element));
}
} else if (action instanceof DynamicMenuContent) {
treatDynamicMenuContent(
(DynamicMenuContent) action,
folderPaths,
buildParentPaths(element));
} else if (action != null) {
folderPaths.removeAll(buildParentPaths(element));
}
}
return folderPaths;
}
private static void treatDynamicMenuContent(DynamicMenuContent presenter,
Set<String> folderPaths, Set<String> c) {
JComponent[] presenters = presenter.getMenuPresenters();
if (presenters != null && presenters.length > 0) {
folderPaths.removeAll(c);
}
}
private static Set<String> buildParentPaths(FileObject fo) {
Set<String> paths = new LinkedHashSet<>();
for (FileObject parent = fo.getParent();
parent != null; parent = parent.getParent()) {
paths.add(parent.getPath());
}
return paths;
}
}
/**
* Adapted from {@code org.netbeans.core.ui.warmup.MenuWarmUpTask}.
*/
class ReheatMenus
implements Runnable {
static void launch() {
EventQueue.invokeLater(new ReheatMenus());
}
private ReheatMenus() {}
private static final RequestProcessor RP = new RequestProcessor(ReheatMenus.class);
private MenuBar bar;
private Component[] comps;
@Override
public void run() {
if (EventQueue.isDispatchThread()) {
if (bar == null) {
Frame main = WindowManager.getDefault().getMainWindow();
assert main != null;
if (main instanceof JFrame) {
JMenuBar menuBar = ((JFrame) main).getJMenuBar();
if (menuBar instanceof MenuBar) {
bar = (MenuBar) menuBar;
RP.post(this);
}
}
} else {
comps = bar.getComponents();
RP.post(this);
}
} else if (comps != null) {
walkMenu(comps);
} else {
bar.waitFinished();
EventQueue.invokeLater(this);
}
}
private void walkMenu(Component[] items) {
for (Component item : items) {
if (!(item instanceof JMenu)) {
continue;
}
try {
Class<?> cls = item.getClass();
//noinspection JavaReflectionMemberAccess
Method m = cls.getDeclaredMethod("doInitialize");
m.setAccessible(true);
m.invoke(item);
walkMenu(((JMenu) item).getMenuComponents());
} catch (Exception x) {
// most likely a NoSuchMethodException on a dynamic submenu
}
}
}
}
/**
* File system which add system hidden folders.
*
* @author Thomas Edwin Santosa
*/
@ServiceProvider(service = FileSystem.class)
public class DynamicLayerContent
extends MultiFileSystem {
private static DynamicLayerContent INSTANCE;
public DynamicLayerContent() {
// will be created on startup, exactly once
INSTANCE = this;
setPropagateMasks(true); // permit *_hidden masks to be used
}
static void clear() {
INSTANCE.setDelegates();
}
static void setHidden(Set<String> paths)
throws IOException {
FileSystem fileSystem = FileUtil.createMemoryFileSystem();
for (String path : paths) {
String pathHidden = path + "_hidden";
String[] pathSplits = pathHidden.split("/");
FileObject fo = fileSystem.getRoot();
for (String folder : pathSplits) {
fo = FileUtil.createFolder(fo, folder);
}
}
INSTANCE.setDelegates(fileSystem);
}
}
要使用此功能,请在插件中创建一个安装程序并调用/**
* Utility for menu security.
*
* @author Thomas Edwin Santosa
*/
final class MenuVisibilityUtil {
private static final Logger log = LoggerFactory.getLogger(MenuVisibilityUtil.class);
private MenuVisibilityUtil() {
}
static void refresh() {
Runnable run = new Runnable() {
public void run() {
Set<String> hiddenPaths = new HashSet<>();
Frame main = WindowManager.getDefault().getMainWindow();
assert main != null;
if (main instanceof JFrame) {
JFrame frame = (JFrame) main;
JMenuBar menuBar = frame.getJMenuBar();
frame.setJMenuBar(null);
DynamicLayerContent.clear();
try {
DynamicLayerContent.setHidden(MenuFolderUtil.findEmptyFolder());
} catch (IOException e) {
log.error("cannot delete menu {}", hiddenPaths, e);
}
frame.setJMenuBar(menuBar);
ReheatMenus.launch();
}
}
};
if (EventQueue.isDispatchThread()) {
run.run();
} else {
EventQueue.invokeLater(run);
}
}
}
如果有任何用户切换,您可能需要再次呼叫MenuVisibilityUtil.refresh();
。