jorgediazest.indexchecker.model.IndexCheckerModelQuery.java Source code

Java tutorial

Introduction

Here is the source code for jorgediazest.indexchecker.model.IndexCheckerModelQuery.java

Source

/**
 * Copyright (c) 2015-present Jorge Daz All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */

package jorgediazest.indexchecker.model;

import com.liferay.portal.kernel.dao.orm.Criterion;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.language.LanguageUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.Group;
import com.liferay.portal.kernel.model.Layout;
import com.liferay.portal.kernel.model.ResourceAction;
import com.liferay.portal.kernel.model.ResourceBlock;
import com.liferay.portal.kernel.model.ResourceBlockPermission;
import com.liferay.portal.kernel.model.ResourceConstants;
import com.liferay.portal.kernel.model.ResourcePermission;
import com.liferay.portal.kernel.model.Role;
import com.liferay.portal.kernel.model.RoleConstants;
import com.liferay.portal.kernel.search.BooleanClauseOccur;
import com.liferay.portal.kernel.search.BooleanQuery;
import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
import com.liferay.portal.kernel.search.Document;
import com.liferay.portal.kernel.search.Field;
import com.liferay.portal.kernel.search.Indexer;
import com.liferay.portal.kernel.search.IndexerRegistryUtil;
import com.liferay.portal.kernel.search.ParseException;
import com.liferay.portal.kernel.search.SearchContext;
import com.liferay.portal.kernel.search.SearchException;
import com.liferay.portal.kernel.security.permission.ActionKeys;
import com.liferay.portal.kernel.service.ResourceActionLocalServiceUtil;
import com.liferay.portal.kernel.service.ResourceBlockLocalServiceUtil;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.LocalizationUtil;
import com.liferay.portal.kernel.util.PortalUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Validator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import jorgediazest.indexchecker.index.IndexSearchUtil;

import jorgediazest.util.data.Data;
import jorgediazest.util.model.Model;
import jorgediazest.util.modelquery.ModelQuery;
import jorgediazest.util.modelquery.ModelQueryImpl;

public class IndexCheckerModelQuery extends ModelQueryImpl {

    public void addPermissionsClassNameGroupIdFields(Map<Long, Data> groupMap, Data data) throws SystemException {

        String className = getPermissionsClassName(data);
        long classPK = getPermissionsClassPK(data);

        if (Validator.isNull(classPK) || Validator.isNull(className) || (classPK <= 0)) {

            return;
        }

        Indexer indexer = IndexerRegistryUtil.getIndexer(className);

        if (!indexer.isPermissionAware()) {
            return;
        }

        long groupId = data.get("groupId", 0L);

        Data group = groupMap.get(groupId);

        if (group != null) {
            long layoutClassNameId = PortalUtil.getClassNameId(Layout.class);

            if (group.get("classNameId", -1L) == layoutClassNameId) {
                groupId = group.get("parentGroupId", groupId);
            }

            data.set("permissionsGroupId", groupId);
        }

        data.set("permissionsClassName", className);
        data.set("permissionsClassPK", classPK);
    }

    public void delete(Data value) throws SearchException {
        Object uid = value.get("uid");

        if (uid == null) {
            return;
        }

        getModel().getIndexerNullSafe().delete(value.getCompanyId(), uid.toString());
    }

    public Map<Data, String> deleteAndCheck(Collection<Data> dataCollection) {

        Map<Data, String> errors = new HashMap<Data, String>();

        if (_log.isDebugEnabled()) {
            _log.debug("Deleting " + dataCollection.size() + " objects of type " + getModel().getClassName());
        }

        int i = 0;

        for (Data data : dataCollection) {
            /* Delete object from index */
            try {
                this.delete(data);

                if (_log.isDebugEnabled()) {
                    _log.debug("Deleting " + (i++) + " uid: " + data.get("uid"));
                }
            } catch (SearchException e) {
                errors.put(data, e.getClass() + " - " + e.getMessage());

                if (_log.isDebugEnabled()) {
                    _log.debug(e.getClass() + " - " + e.getMessage(), e);
                }
            }

            /* Reindex object, perhaps we deleted it by error */
            try {
                this.reindex(data);
            } catch (Exception e) {
            }
        }

        return errors;
    }

    public void fillDataObject(Data data, String[] attributes, Document doc) {
        data.set("uid", doc.getUID());

        Locale[] locales = LanguageUtil.getAvailableLocales().toArray(new Locale[0]);
        Locale siteLocale = LocaleUtil.getSiteDefault();

        for (String attribute : attributes) {
            String attrDoc = IndexSearchUtil.getAttributeForDocument(getModel(), attribute);

            List<Map<Locale, String>> listValueMap = null;

            Class<?> typeClass = data.getAttributeTypeClass(attribute);

            if (typeClass.equals(String.class) || typeClass.equals(Object.class)) {

                listValueMap = IndexSearchUtil.getLocalizedMap(locales, doc, attrDoc);
            }

            if ((listValueMap != null) && !listValueMap.isEmpty()) {
                String[] xml = new String[listValueMap.size()];

                int pos = 0;

                for (Map<Locale, String> valueMap : listValueMap) {
                    xml[pos++] = LocalizationUtil.updateLocalization(valueMap, "", "data",
                            LocaleUtil.toLanguageId(siteLocale));
                }

                data.set(attribute, xml);
            } else if (doc.hasField(attrDoc)) {
                data.set(attribute, doc.getField(attrDoc).getValues());
            }
        }
    }

    public Map<Long, Data> getData(String[] attributesModel, String[] attributesRelated, Criterion filter)
            throws Exception {

        Map<Long, Data> dataMap = super.getData(attributesModel, attributesRelated, filter);

        addPermissionFields(dataMap);

        return dataMap;
    }

    public Set<Data> getIndexData(Set<Model> relatedModels, String[] attributes, SearchContext searchContext,
            BooleanQuery contextQuery) throws SearchException {

        int size = Math.max((int) getModel().count() * 2, 50000);

        Document[] docs = IndexSearchUtil.executeSearch(searchContext, contextQuery, size, 50000);

        Set<Data> indexData = new HashSet<Data>();

        if (docs != null) {
            for (int i = 0; i < docs.length; i++) {
                Data data = new Data(getModel(), this.dataComparator);

                data.addModelTableInfo(relatedModels);

                fillDataObject(data, attributes, docs[i]);

                indexData.add(data);
            }
        }

        return indexData;
    }

    public BooleanQuery getIndexQuery(List<Long> groupIds, SearchContext searchContext) throws ParseException {

        BooleanQuery query = BooleanQueryFactoryUtil.create(searchContext);
        query.addRequiredTerm(Field.ENTRY_CLASS_NAME, getModel().getClassName());

        if (getModel().hasAttribute("groupId") && (groupIds != null)) {
            BooleanQuery groupQuery = BooleanQueryFactoryUtil.create(searchContext);

            for (Long groupId : groupIds) {
                groupQuery.addTerm(Field.SCOPE_GROUP_ID, groupId);
            }

            query.add(groupQuery, BooleanClauseOccur.MUST);
        }

        return query;
    }

    public BooleanQuery getIndexQuery(long groupId, SearchContext searchContext) throws ParseException {

        List<Long> groupIds = null;

        if (groupId != 0) {
            groupIds = new ArrayList<Long>();

            groupIds.add(groupId);
        }

        return getIndexQuery(groupIds, searchContext);
    }

    public BooleanQuery getIndexQuery(SearchContext searchContext) throws ParseException {

        return getIndexQuery(null, searchContext);
    }

    public SearchContext getIndexSearchContext(long companyId) {
        SearchContext searchContext = new SearchContext();
        searchContext.setCompanyId(companyId);
        searchContext.setEntryClassNames(new String[] { getModel().getClassName() });
        return searchContext;
    }

    public boolean hasActionId(long actionIds, String name, String actionId) throws PortalException {

        Long bitwiseValue = getActionIdBitwiseValue(name, actionId);

        if (Validator.isNull(bitwiseValue)) {
            return false;
        }

        if ((actionIds & bitwiseValue) == bitwiseValue) {
            return true;
        } else {
            return false;
        }
    }

    public Map<Data, String> reindex(Collection<Data> dataCollection) {

        Map<Data, String> errors = new HashMap<Data, String>();

        if (_log.isDebugEnabled()) {
            _log.debug("Reindexing " + dataCollection.size() + " objects of type " + getModel().getClassName());
        }

        int i = 0;

        for (Data data : dataCollection) {
            try {
                this.reindex(data);

                if (_log.isDebugEnabled()) {
                    _log.debug("Reindexing " + (i++) + " pk: " + data.getPrimaryKey());
                }
            } catch (SearchException e) {
                errors.put(data, e.getClass() + " - " + e.getMessage());

                if (_log.isDebugEnabled()) {
                    _log.debug(e.getClass() + " - " + e.getMessage(), e);
                }
            }
        }

        return errors;
    }

    public void reindex(Data value) throws SearchException {
        getModel().getIndexerNullSafe().reindex(getModel().getClassName(), value.getPrimaryKey());
    }

    protected void addPermissionFields(Map<Long, Data> dataMap) throws Exception, PortalException, SystemException {

        ModelQuery groupQuery = mqFactory.getModelQueryObject(Group.class);

        Map<Long, Data> groupMap = groupQuery.getDataWithCache("pk,classNameId,parentGroupId".split(","));

        for (Data data : dataMap.values()) {
            addPermissionsClassNameGroupIdFields(groupMap, data);
        }

        addRelatedModelData(dataMap, ResourcePermission.class.getName(),
                " =primKey,roleId,actionIds,scope".split(","), "permissionsClassPK=primKey".split(","), false,
                true);

        addRelatedModelData(dataMap, ResourceBlock.class.getName(), " =groupId, =name,resourceBlockId".split(","),
                "permissionsGroupId=groupId,permissionsClassName=name".split(","), false, false);

        addRelatedModelData(dataMap, ResourceBlockPermission.class.getName(),
                " =resourceBlockId,roleId,actionIds".split(","), "resourceBlockId".split(","), false, true);

        ModelQuery roleQuery = mqFactory.getModelQueryObject(Role.class);

        Map<Long, Data> roleMap = roleQuery.getDataWithCache("pk,type".split(","));

        for (Data data : dataMap.values()) {
            addRolesFieldsToData(roleMap, data);
        }
    }

    protected void addRolesFieldsToData(Map<Long, Data> roleMap, Data data) throws PortalException {

        String className = data.get("permissionsClassName", StringPool.BLANK);

        String permissionsField = ResourceBlockPermission.class.getName();

        if (ResourceBlockLocalServiceUtil.isSupported(className)) {
            permissionsField = ResourceBlockPermission.class.getName();
        } else {
            permissionsField = ResourcePermission.class.getName();
        }

        addRolesFieldsToData(roleMap, className, data, permissionsField);
    }

    @SuppressWarnings("unchecked")
    protected void addRolesFieldsToData(Map<Long, Data> roleMap, String className, Data data,
            String permissionsField) throws PortalException {

        Object aux = data.get(permissionsField);

        Set<List<Object>> resourcePermissions = null;

        if (aux instanceof List) {
            resourcePermissions = new HashSet<List<Object>>();
            resourcePermissions.add((List<Object>) aux);
        } else if (aux instanceof Set) {
            resourcePermissions = (Set<List<Object>>) aux;
        }

        if (resourcePermissions == null) {
            return;
        }

        Set<String> roleIds = new HashSet<String>();
        Set<String> groupRoleIds = new HashSet<String>();

        for (List<Object> resourcePermission : resourcePermissions) {
            long roleId = (Long) resourcePermission.get(0);
            long actionIds = (Long) resourcePermission.get(1);

            if (resourcePermission.size() > 2) {
                int scope = (Integer) resourcePermission.get(2);

                if (scope != ResourceConstants.SCOPE_INDIVIDUAL) {
                    continue;
                }
            }

            if (hasActionId(actionIds, className, ActionKeys.VIEW)) {
                Data role = roleMap.get(roleId);

                if (role == null) {
                    continue;
                }

                long groupId = data.get("permissionsGroupId", 0L);

                int type = role.get("type", -1);

                if ((type == RoleConstants.TYPE_ORGANIZATION) || (type == RoleConstants.TYPE_SITE)) {

                    groupRoleIds.add(groupId + StringPool.DASH + roleId);
                } else {
                    roleIds.add(Long.toString(roleId));
                }
            }
        }

        data.set("roleId", roleIds);
        data.set("groupRoleId", groupRoleIds);
    }

    protected long getActionIdBitwiseValue(String name, String actionId) throws PortalException {

        String key = name + "_" + actionId;

        Long bitwiseValue = cacheActionIdBitwiseValue.get(key);

        if (bitwiseValue == null) {
            ResourceAction resourceAction = ResourceActionLocalServiceUtil.fetchResourceAction(name, actionId);

            if (resourceAction == null) {
                bitwiseValue = 0L;
            } else {
                bitwiseValue = resourceAction.getBitwiseValue();
            }

            cacheActionIdBitwiseValue.put(key, bitwiseValue);
        }

        return bitwiseValue;
    }

    protected String getPermissionsClassName(Data data) {
        return data.getEntryClassName();
    }

    protected long getPermissionsClassPK(Data data) {
        if (data.getModel().isResourcedModel()) {
            return data.getResourcePrimKey();
        }

        return data.getPrimaryKey();
    }

    protected Map<String, Long> cacheActionIdBitwiseValue = new HashMap<String, Long>();

    private static Log _log = LogFactoryUtil.getLog(IndexCheckerModelQuery.class);

}