MainServlet中,当处理完全局启动事件,比如插件自动部署目录的设定之后,就开始初始化Resource Action,其代码如下:
- if (_log.isDebugEnabled()) {
- _log.debug("Initialize resource actions");
- }
- try {
- initResourceActions(portlets);
- }
- ..
它调用了initResourceActions方法,我们看它做了什么事情:
首先,它对PERMISSIONS_USER_CHECK_ALGORITHM的设定必须是6以上,否则就返回:
- if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM < 6) {
- if (_log.isWarnEnabled()) {
- StringBundler sb = new StringBundler(8);
- sb.append("Liferay is configured to use permission algorithm ");
- sb.append(PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM);
- sb.append(". Versions after 6.1 will only support algorithm ");
- sb.append("6 and above. Please sign in as an administrator, ");
- ...
- _log.warn(sb.toString());
- }
- return;
- }
这个设定在portal.properties文件中,Liferay 6 默认的设置为6:
- #
- # Set the algorithm used to check permissions for a user. This is useful so
- # that you can optimize the search for different databases. See
- # com.liferay.portal.service.impl.PermissionLocalServiceImpl.
- #
- # Algorithms 1 through 4 are essentially the same but make calls in different
- # orders depending on how the database is optimized and how the portal
- # permissions are used. Algorithm 5 moves to a completely role based
- # permissions check for better performance. Permissions by users are no
- # longer supported, yet it uses the same table structure as algorithms 1-4.
- #
- # Algorithm 6 is the current algorithm for Liferay 6 and above. It supports
- # role based permissions like algorithm 5, but does so by using only one
- # table and bitwise operations. This makes it perform far better than the
- # other algorithms.
- #
- #permissions.user.check.algorithm=1
- #permissions.user.check.algorithm=2
- #permissions.user.check.algorithm=3
- #permissions.user.check.algorithm=4
- #permissions.user.check.algorithm=5
- permissions.user.check.algorithm=6
然后,它对参数中的每个portlet进行迭代,找出ResourceActions进行处理:
- while (itr.hasNext()) {
- Portlet portlet = itr.next();
- List<String> portletActions =
- ResourceActionsUtil.getPortletResourceActions(portlet);
- ResourceActionLocalServiceUtil.checkResourceActions(
- portlet.getPortletId(), portletActions);
- List<String> modelNames =
- ResourceActionsUtil.getPortletModelResources(
- portlet.getPortletId());
- for (String modelName : modelNames) {
- List<String> modelActions =
- ResourceActionsUtil.getModelResourceActions(modelName);
- ResourceActionLocalServiceUtil.checkResourceActions(
- modelName, modelActions);
- }
- }
我们逐行分析。
分析04-05行:
在第04行,它调用ResourceActionsUtil的getPortletResourceActions方法来获取和某个portlet相关联的portletActions列表:
- public static List<String> getPortletResourceActions(Portlet portlet) {
- return getResourceActions().getPortletResourceActions(portlet);
- }
它会去委托ResourceActionImpl的getPortletResourceActions方法:
- public List<String> getPortletResourceActions(Portlet portlet) {
- List<String> actions = ListUtil.copy(
- getPortletResourceActions(portlet.getPortletId()));
- synchronized (this) {
- checkPortletActions(portlet, actions);
- setActions(
- _portletResourceActions, portlet.getPortletId(), actions);
- }
- return actions;
- }
从第3行又可以看出,它是从portlet得到其id然后传递给重载的另一个方法:
- public List<String> getPortletResourceActions(String name) {
- name = PortletConstants.getRootPortletId(name);
- List<String> actions = getActions(_portletResourceActions, name);
- if (!actions.isEmpty()) {
- return actions;
- }
- synchronized (this) {
- actions = getPortletMimeTypeActions(name);
- if (!name.equals(PortletKeys.PORTAL)) {
- checkPortletActions(name, actions);
- }
- List<String> groupDefaultActions =
- _portletResourceGroupDefaultActions.get(name);
- if (groupDefaultActions == null) {
- groupDefaultActions = new UniqueList<String>();
- checkPortletGroupDefaultActions(groupDefaultActions);
- _portletResourceGroupDefaultActions.put(
- name, new UnmodifiableList<String>(groupDefaultActions));
- }
- List<String> guestDefaultActions =
- _portletResourceGuestDefaultActions.get(name);
- if (guestDefaultActions == null) {
- guestDefaultActions = new UniqueList<String>();
- checkPortletGuestDefaultActions(guestDefaultActions);
- _portletResourceGuestDefaultActions.put(
- name, new UnmodifiableList<String>(guestDefaultActions));
- }
- List<String> layoutManagerActions =
- _portletResourceLayoutManagerActions.get(name);
- if (layoutManagerActions == null) {
- layoutManagerActions = new UniqueList<String>();
- checkPortletLayoutManagerActions(layoutManagerActions);
- _portletResourceLayoutManagerActions.put(
- name, new UnmodifiableList<String>(layoutManagerActions));
- }
- actions = setActions(_portletResourceActions, name, actions);
- }
- return actions;
- }
这里跟进每一步都会很复杂,我们一步一步来,第11行可以根据portlet的name来获得portlet的mode ,并且根据mode的设定来得到它的action,是edit还是edit_guest.第17-27行去检查group的默认action,吧group的默认action设置为view.29-39行去检查guest的默认action,把guest的默认action设置为view.第41-51行去检查layoutManager的action,它会为每个layoutManager都添加4种action(CONFIGURATION,PERMISSIONS,PERFERENCES和VIEW)
所以概括来说,04行就是检查并且获取每个portlet的action设置,包括自身action,group action,guest action,layout manager action.
分析07-08行:
07行中,它会调用ResourceActionLocalServiceUtil的checkResourceActions方法:
- public static void checkResourceActions(java.lang.String name,
- java.util.List<java.lang.String> actionIds)
- throws com.liferay.portal.kernel.exception.SystemException {
- getService().checkResourceActions(name, actionIds);
- }
它最终实际会委托ResourceActionLocalServiceImpl的checkResourceActions方法:
- public void checkResourceActions(
- String name, List<String> actionIds, boolean addDefaultActions)
- throws SystemException {
- if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM != 6) {
- return;
- }
- List<ResourceAction> resourceActions =
- resourceActionPersistence.findByName(name);
- resourceActions = ListUtil.copy(resourceActions);
- checkResourceActions(
- name, actionIds, resourceActions, addDefaultActions);
- }
从这里可以看出,它第05-06行先确保user permission check被设置为6,然后它在09-10行中从数据库中取得与portlet名字对应的resource actions列表,最后来检查数据库中的resource actions是否和先前从04-05步的相一致。
分析第10-20行:
它从portlet分离出对应的portlet mode的所有action,然后在继续刚才的分析,这里就不一一详细分析了。
所以,初始化resource action之后,系统就对每个portle有哪些action十分清楚了。