diff --git a/src/main/java/de/metas/ui/web/menu/MenuTree.java b/src/main/java/de/metas/ui/web/menu/MenuTree.java index e3494007e..9889b2bce 100644 --- a/src/main/java/de/metas/ui/web/menu/MenuTree.java +++ b/src/main/java/de/metas/ui/web/menu/MenuTree.java @@ -47,12 +47,14 @@ public final class MenuTree { - public static final MenuTree of(final MenuNode rootNode) + public static final MenuTree of(final long version, final MenuNode rootNode) { - return new MenuTree(rootNode); + return new MenuTree(version, rootNode); } private static final Logger logger = LogManager.getLogger(MenuTree.class); + + private final long version; private final MenuNode rootNode; private final Map nodesById; @@ -60,9 +62,10 @@ public static final MenuTree of(final MenuNode rootNode) private final ListMultimap nodesByTypeAndElementId; private final ListMultimap nodesByMainTableName; - private MenuTree(final MenuNode rootNode) + private MenuTree(final long version, final MenuNode rootNode) { super(); + this.version = version; Preconditions.checkNotNull(rootNode, "rootNode"); this.rootNode = rootNode; @@ -94,8 +97,14 @@ public String toString() { return MoreObjects.toStringHelper(this) .add("rootNode", rootNode) + .add("version", version) .toString(); } + + public long getVersion() + { + return version; + } public MenuNode getRootNode() { diff --git a/src/main/java/de/metas/ui/web/menu/MenuTreeLoader.java b/src/main/java/de/metas/ui/web/menu/MenuTreeLoader.java index a8e535768..59173ec23 100644 --- a/src/main/java/de/metas/ui/web/menu/MenuTreeLoader.java +++ b/src/main/java/de/metas/ui/web/menu/MenuTreeLoader.java @@ -1,7 +1,6 @@ package de.metas.ui.web.menu; import java.util.Enumeration; -import java.util.Properties; import org.adempiere.ad.security.IUserRolePermissions; import org.adempiere.ad.security.IUserRolePermissionsDAO; @@ -13,13 +12,13 @@ import org.compiere.model.MTree; import org.compiere.model.MTreeNode; import org.compiere.model.X_AD_Menu; +import org.compiere.util.Env; import org.slf4j.Logger; -import com.google.common.base.Preconditions; - import de.metas.logging.LogManager; import de.metas.ui.web.menu.MenuNode.MenuNodeType; import de.metas.ui.web.process.ProcessId; +import lombok.NonNull; /* * #%L @@ -43,7 +42,7 @@ * #L% */ -public final class MenuTreeLoader +final class MenuTreeLoader { /* package */static MenuTreeLoader newInstance() { @@ -57,39 +56,33 @@ public final class MenuTreeLoader private static final int DEPTH_Root = 0; private static final int DEPTH_RootChildren = 1; - private Properties _ctx; private UserRolePermissionsKey _userRolePermissionsKey; private IUserRolePermissions _userRolePermissions; // lazy private String _adLanguage; + private long _version = -1; private MenuTreeLoader() { super(); } - public MenuTreeLoader setCtx(final Properties ctx) + public MenuTreeLoader setUserRolePermissionsKey(final UserRolePermissionsKey userRolePermissionsKey) { - _ctx = ctx; + _userRolePermissionsKey = userRolePermissionsKey; return this; } - private Properties getCtx() - { - Preconditions.checkNotNull(_ctx, "ctx"); - return _ctx; - } - - public MenuTreeLoader setUserRolePermissionsKey(final UserRolePermissionsKey userRolePermissionsKey) + @NonNull + private UserRolePermissionsKey getUserRolePermissionsKey() { - _userRolePermissionsKey = userRolePermissionsKey; - return this; + return _userRolePermissionsKey; } private IUserRolePermissions getUserRolePermissions() { if (_userRolePermissions == null) { - final UserRolePermissionsKey userRolePermissionsKey = _userRolePermissionsKey != null ? _userRolePermissionsKey : UserRolePermissionsKey.of(getCtx()); + final UserRolePermissionsKey userRolePermissionsKey = getUserRolePermissionsKey(); _userRolePermissions = userRolePermissionsDAO.retrieveUserRolePermissions(userRolePermissionsKey); } return _userRolePermissions; @@ -109,7 +102,8 @@ public MenuTree load() throw new IllegalStateException("No root menu node available"); // shall not happen } - return MenuTree.of(rootNode); + final long version = getVersion(); + return MenuTree.of(version, rootNode); } private MenuNode createMenuNodeRecursivelly(final MTreeNode nodeModel, final int depth) @@ -237,7 +231,7 @@ private MTreeNode retrieveRootNodeModel() } final MTree mTree = MTree.builder() - .setCtx(getCtx()) + .setCtx(Env.getCtx()) .setTrxName(ITrx.TRXNAME_None) .setAD_Tree_ID(adTreeId) .setEditable(false) @@ -265,8 +259,18 @@ public MenuTreeLoader setAD_Language(String adLanguage) return this; } + @NonNull private String getAD_Language() { return _adLanguage; } + + private long getVersion() + { + if (_version < 0) + { + _version = userRolePermissionsDAO.getCacheVersion(); + } + return _version; + } } diff --git a/src/main/java/de/metas/ui/web/menu/MenuTreeRepository.java b/src/main/java/de/metas/ui/web/menu/MenuTreeRepository.java index 0be3b4daf..f63c0e9ac 100644 --- a/src/main/java/de/metas/ui/web/menu/MenuTreeRepository.java +++ b/src/main/java/de/metas/ui/web/menu/MenuTreeRepository.java @@ -4,9 +4,11 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import org.adempiere.ad.security.IUserRolePermissionsDAO; import org.adempiere.ad.security.UserRolePermissionsKey; import org.adempiere.exceptions.AdempiereException; -import org.compiere.util.Env; +import org.adempiere.util.Services; +import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @@ -15,6 +17,7 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; +import de.metas.logging.LogManager; import de.metas.ui.web.session.UserSession; /* @@ -42,6 +45,8 @@ @Repository public class MenuTreeRepository { + private static final transient Logger logger = LogManager.getLogger(MenuTreeRepository.class); + @Autowired private UserSession userSession; @@ -54,7 +59,6 @@ public class MenuTreeRepository public MenuTree load(final MenuTreeKey key) throws Exception { return MenuTreeLoader.newInstance() - .setCtx(Env.getCtx()) .setUserRolePermissionsKey(key.getUserRolePermissionsKey()) .setAD_Language(key.getAD_Language()) .load(); @@ -73,7 +77,29 @@ public MenuTree getMenuTree(final UserRolePermissionsKey userRolePermissionsKey, try { final MenuTreeKey key = new MenuTreeKey(userRolePermissionsKey, adLanguage); - return menuTrees.get(key); + MenuTree menuTree = menuTrees.get(key); + + // + // If menuTree's version is not the current one, try re-acquiring it. + int retry = 3; + final long currentVersion = Services.get(IUserRolePermissionsDAO.class).getCacheVersion(); + while (menuTree.getVersion() != currentVersion) + { + menuTrees.invalidate(key); + menuTree = menuTrees.get(key); + + retry--; + if (retry <= 0) + { + break; + } + } + if (menuTree.getVersion() != currentVersion) + { + logger.warn("Could not acquire menu tree version {}. Returning what we got... \nmenuTree: {}\nkey={}", currentVersion, menuTree, key); + } + + return menuTree; } catch (final ExecutionException e) {