ch.inofix.referencemanager.service.impl.ReferenceLocalServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for ch.inofix.referencemanager.service.impl.ReferenceLocalServiceImpl.java

Source

/**
 * Copyright (c) 2016-present Inofix GmbH, Luzern. 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 ch.inofix.referencemanager.service.impl;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.jbibtex.BibTeXEntry;
import org.jbibtex.Key;
import org.jbibtex.StringValue;
import org.jbibtex.StringValue.Style;
import org.jbibtex.Value;

import com.liferay.asset.kernel.model.AssetEntry;
import com.liferay.asset.kernel.model.AssetLinkConstants;
import com.liferay.portal.kernel.backgroundtask.BackgroundTask;
import com.liferay.portal.kernel.backgroundtask.BackgroundTaskManager;
import com.liferay.portal.kernel.exception.LocaleException;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
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.ResourceConstants;
import com.liferay.portal.kernel.model.SystemEventConstants;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.search.Field;
import com.liferay.portal.kernel.search.Hits;
import com.liferay.portal.kernel.search.Indexable;
import com.liferay.portal.kernel.search.IndexableType;
import com.liferay.portal.kernel.search.Indexer;
import com.liferay.portal.kernel.search.IndexerRegistryUtil;
import com.liferay.portal.kernel.search.QueryConfig;
import com.liferay.portal.kernel.search.SearchContext;
import com.liferay.portal.kernel.search.Sort;
import com.liferay.portal.kernel.service.GroupLocalServiceUtil;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.systemevent.SystemEvent;
import com.liferay.portal.kernel.util.ContentTypes;
import com.liferay.portal.kernel.util.FileUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.HtmlUtil;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import com.liferay.portal.spring.extender.service.ServiceReference;

import ch.inofix.referencemanager.backgroundtask.ReferenceImportBackgroundTaskExecutor;
import ch.inofix.referencemanager.model.BibRefRelation;
import ch.inofix.referencemanager.model.Bibliography;
import ch.inofix.referencemanager.model.Reference;
import ch.inofix.referencemanager.service.base.ReferenceLocalServiceBaseImpl;
import ch.inofix.referencemanager.service.util.BibTeXUtil;
import ch.inofix.referencemanager.service.util.ReferenceImporter;
import ch.inofix.referencemanager.social.ReferenceActivityKeys;

/**
 * The implementation of the reference local service.
 *
 * <p>
 * All custom service methods should be put in this class. Whenever methods are
 * added, rerun ServiceBuilder to copy their definitions into the
 * {@link ch.inofix.referencemanager.service.ReferenceLocalService} interface.
 *
 * <p>
 * This is a local service. Methods of this service will not have security
 * checks based on the propagated JAAS credentials because this service can only
 * be accessed from within the same VM.
 * </p>
 *
 * @author Brian Wing Shun Chan
 * @author Christian Berndt
 * @created 2016-03-28 17:08
 * @modified 2017-10-30 15:08
 * @version 1.1.3
 * @see ReferenceLocalServiceBaseImpl
 * @see ch.inofix.referencemanager.service.ReferenceLocalServiceUtil
 */
public class ReferenceLocalServiceImpl extends ReferenceLocalServiceBaseImpl {
    /*
     * NOTE FOR DEVELOPERS:
     * 
     * Never reference this class directly. Always use {@link
     * ch.inofix.referencemanager.service.ReferenceLocalServiceUtil} to access
     * the reference local service.
     */

    @Indexable(type = IndexableType.REINDEX)
    @Override
    public Reference addReference(long userId, String bibTeX, long[] bibliographyIds, ServiceContext serviceContext)
            throws PortalException {

        // Reference

        User user = userPersistence.findByPrimaryKey(userId);

        long groupId = serviceContext.getScopeGroupId();

        long companyId = user.getCompanyId();

        long referenceId = counterLocalService.increment();

        Reference reference = referencePersistence.create(referenceId);

        reference.setUuid(serviceContext.getUuid());
        reference.setGroupId(groupId);
        reference.setCompanyId(companyId);
        reference.setUserId(user.getUserId());
        reference.setUserName(user.getFullName());
        reference.setExpandoBridgeAttributes(serviceContext);

        BibTeXEntry bibTeXEntry = BibTeXUtil.getBibTeXEntry(bibTeX);
        if (bibTeXEntry != null) {
            Key key = new Key("bibshare-id");
            Value value = new StringValue(String.valueOf(referenceId), Style.QUOTED);
            bibTeXEntry.addField(key, value);
        } else {
            // TODO: raise an error and report to the user that something is
            // wrong with the bibtex-src.
        }

        bibTeX = BibTeXUtil.format(bibTeXEntry);

        reference.setBibTeX(bibTeX);

        referencePersistence.update(reference);

        // Match user and group references against common references

        long defaultGroupId = GetterUtil.getLong(PropsUtil.get("default.group.id"));

        if (reference.getGroupId() != defaultGroupId) {

            match(reference);

        }

        // BibRefRelation

        for (long bibliographyId : bibliographyIds) {

            Bibliography bibliography = bibliographyLocalService.getBibliography(bibliographyId);

            long bibRefRelationId = counterLocalService.increment();
            BibRefRelation bibRefRelation = bibRefRelationPersistence.create(bibRefRelationId);

            bibRefRelation.setGroupId(bibliography.getGroupId());
            bibRefRelation.setCompanyId(bibliography.getCompanyId());
            bibRefRelation.setUserId(bibliography.getUserId());
            bibRefRelation.setUserName(bibliography.getUserName());

            bibRefRelation.setBibliographyId(bibliography.getBibliographyId());
            bibRefRelation.setReferenceId(referenceId);

            bibRefRelationPersistence.update(bibRefRelation);

        }

        // Resources

        resourceLocalService.addModelResources(reference, serviceContext);

        // Asset

        updateAsset(userId, reference, serviceContext.getAssetCategoryIds(), serviceContext.getAssetTagNames(),
                serviceContext.getAssetLinkEntryIds(), serviceContext.getAssetPriority());

        // Social

        JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();

        extraDataJSONObject.put("title", reference.getCitation());

        socialActivityLocalService.addActivity(userId, groupId, Reference.class.getName(), referenceId,
                ReferenceActivityKeys.ADD_REFERENCE, extraDataJSONObject.toString(), 0);

        return reference;

    }

    @Override
    public Reference addReference(long userId, String bibTeX, ServiceContext serviceContext)
            throws PortalException {

        return addReference(userId, bibTeX, new long[0], serviceContext);

    }

    @Override
    public void deleteReferences(long groupId) throws PortalException {
        for (Reference reference : referencePersistence.findByGroupId(groupId)) {
            referenceLocalService.deleteReference(reference);
        }
    }

    @Indexable(type = IndexableType.DELETE)
    @Override
    @SystemEvent(type = SystemEventConstants.TYPE_DELETE)
    public Reference deleteReference(Reference reference) throws PortalException {

        // Reference

        referencePersistence.remove(reference);

        // Resources

        resourceLocalService.deleteResource(reference.getCompanyId(), Reference.class.getName(),
                ResourceConstants.SCOPE_INDIVIDUAL, reference.getReferenceId());

        // Subscriptions

        subscriptionLocalService.deleteSubscriptions(reference.getCompanyId(), Reference.class.getName(),
                reference.getReferenceId());

        // Asset

        assetEntryLocalService.deleteEntry(Reference.class.getName(), reference.getReferenceId());

        // Comment

        // TODO
        // deleteDiscussion(reference);

        // Expando

        expandoRowLocalService.deleteRows(reference.getReferenceId());

        // Ratings

        ratingsStatsLocalService.deleteStats(Reference.class.getName(), reference.getReferenceId());

        // Trash

        trashEntryLocalService.deleteEntry(Reference.class.getName(), reference.getReferenceId());

        // Workflow

        // TODO: do we need workflow support?
        // workflowInstanceLinkLocalService.deleteWorkflowInstanceLinks(
        // reference.getCompanyId(), reference.getGroupId(),
        // Reference.class.getName(), reference.getReferenceId());

        return reference;
    }

    @Override
    public Reference deleteReference(long referenceId) throws PortalException {
        Reference reference = referencePersistence.findByPrimaryKey(referenceId);

        bibRefRelationLocalService.deleteByReferenceId(referenceId);

        refRefRelationLocalService.deleteByReferenceId(referenceId);

        return referenceLocalService.deleteReference(reference);
    }

    public List<Reference> getGroupReferences(long groupId) throws PortalException, SystemException {

        return referencePersistence.findByGroupId(groupId);
    }

    @Override
    public Reference getReference(long referenceId) throws PortalException {
        return referencePersistence.findByPrimaryKey(referenceId);
    }

    /**
     * Imports the references from the file.
     *
     * @param userId
     *            the primary key of the user
     * @param groupId
     *            the primary key of the group
     * @param privateLayout
     *            whether the layout is private to the group
     * @param parameterMap
     *            the mapping of parameters indicating which information will be
     *            imported.
     * @param file
     *            the file with the data
     * @param serviceContext
     * @since 1.0.2
     * @throws PortalException
     *             if a group or user with the primary key could not be found,
     *             or if some other portal exception occurred
     * @throws SystemException
     *             if a system exception occurred
     * @see com.liferay.portal.lar.LayoutImporter
     */
    public void importReferences(long userId, long groupId, boolean privateLayout,
            Map<String, String[]> parameterMap, File file, ServiceContext serviceContext)
            throws PortalException, SystemException {

        try {
            ReferenceImporter referenceImporter = new ReferenceImporter();

            referenceImporter.importReferences(userId, groupId, privateLayout, parameterMap, file, serviceContext);

        } catch (PortalException pe) {
            Throwable cause = pe.getCause();

            if (cause instanceof LocaleException) {
                throw (PortalException) cause;
            }

            _log.error(pe);

            throw pe;
        } catch (SystemException se) {

            _log.error(se);

            throw se;
        } catch (Exception e) {

            _log.error(e);

            throw new SystemException(e);
        }
    }

    /**
     * Imports the references from the input stream.
     *
     * @param userId
     *            the primary key of the user
     * @param groupId
     *            the primary key of the group
     * @param privateLayout
     *            whether the layout is private to the group
     * @param parameterMap
     *            the mapping of parameters indicating which information will be
     *            imported.
     * @param inputStream
     *            the input stream
     * @param serviceContext
     * @since 1.0.2
     * @throws PortalException
     *             if a group or user with the primary key could not be found,
     *             or if some other portal exception occurred
     * @throws SystemException
     *             if a system exception occurred
     */
    public void importReferences(long userId, long groupId, boolean privateLayout,
            Map<String, String[]> parameterMap, InputStream inputStream, ServiceContext serviceContext)
            throws PortalException, SystemException {

        File file = null;

        try {
            file = FileUtil.createTempFile("bib");

            FileUtil.write(file, inputStream);

            importReferences(userId, groupId, privateLayout, parameterMap, file, serviceContext);

        } catch (IOException ioe) {

            _log.error(ioe);

            throw new SystemException(ioe);
        } finally {
            FileUtil.delete(file);
        }
    }

    /**
     * 
     * @param userId
     * @param taskName
     * @param groupId
     * @param privateLayout
     * @param parameterMap
     * @param file
     * @param serviceContext
     * @since 1.0.8
     * @return
     * @throws PortalException
     */
    public long importReferencesInBackground(long userId, String taskName, long groupId, boolean privateLayout,
            Map<String, String[]> parameterMap, File file, ServiceContext serviceContext) throws PortalException {

        Map<String, Serializable> taskContextMap = new HashMap<String, Serializable>();
        taskContextMap.put("userId", userId);
        taskContextMap.put("groupId", groupId);
        taskContextMap.put("parameterMap", (Serializable) parameterMap);
        taskContextMap.put("privateLayout", privateLayout);
        taskContextMap.put("serviceContext", serviceContext);

        BackgroundTask backgroundTask = backgroundTaskmanager.addBackgroundTask(userId, groupId, taskName,
                ReferenceImportBackgroundTaskExecutor.class.getName(), taskContextMap, serviceContext);

        backgroundTask.addAttachment(userId, file.getName(), file);

        return backgroundTask.getBackgroundTaskId();

    }

    public void match(Reference reference) throws PortalException {

        _log.info("match");

        long defaultGroupId = GetterUtil.getLong(PropsUtil.get("default.group.id"));

        Hits hits = search(reference.getUserId(), defaultGroupId, -1, null, reference.getTitle(), null,
                WorkflowConstants.STATUS_ANY, null, false, 0, 20, null);

        _log.info("hits.getLength() = " + hits.getLength());

        if (hits.getLength() == 0) {

            // not yet in the pool of common references

            _log.info("not yet in the global references ");

            // TODO: strip the private fields from the reference
            String bibTeX = reference.getBibTeX();

            ServiceContext serviceContext = new ServiceContext();
            serviceContext.setScopeGroupId(defaultGroupId);

            Reference globalReference = addReference(reference.getUserId(), bibTeX, serviceContext);

            refRefRelationLocalService.addRefRefRelation(reference.getUserId(), globalReference.getReferenceId(),
                    reference.getReferenceId(), new ServiceContext());
        }
    }

    @Indexable(type = IndexableType.REINDEX)
    public Reference reIndexReference(long referenceId) throws PortalException {
        return getReference(referenceId);
    }

    @Override
    public Hits search(long userId, long groupId, long bibliographyId, String keywords, int start, int end,
            Sort sort) throws PortalException {

        if (sort == null) {
            sort = new Sort(Field.MODIFIED_DATE, true);
        }

        String author = null;
        String title = null;
        String year = null;

        boolean andOperator = false;

        if (Validator.isNotNull(keywords)) {

            author = keywords;
            title = keywords;
            year = keywords;

        } else {
            andOperator = true;
        }

        return search(userId, groupId, bibliographyId, author, title, year, WorkflowConstants.STATUS_ANY, null,
                andOperator, start, end, sort);

    }

    @Override
    public Hits search(long userId, long groupId, long bibliographyId, String author, String title, String year,
            int status, LinkedHashMap<String, Object> params, boolean andSearch, int start, int end, Sort sort)
            throws PortalException {

        if (sort == null) {
            sort = new Sort(Field.MODIFIED_DATE, true);
        }

        Indexer<Reference> indexer = IndexerRegistryUtil.getIndexer(Reference.class.getName());

        SearchContext searchContext = buildSearchContext(userId, groupId, bibliographyId, author, title, year,
                status, params, andSearch, start, end, sort);

        return indexer.search(searchContext);
    }

    @Override
    public void subscribe(long userId, long groupId) throws PortalException {
        subscriptionLocalService.addSubscription(userId, groupId, Reference.class.getName(), groupId);
    }

    @Override
    public void unsubscribe(long userId, long groupId) throws PortalException {
        subscriptionLocalService.deleteSubscription(userId, Reference.class.getName(), groupId);
    }

    public void updateAsset(long userId, Reference reference, long[] assetCategoryIds, String[] assetTagNames,
            long[] assetLinkEntryIds, Double priority) throws PortalException {

        boolean visible = false;

        Date publishDate = null;

        if (reference.isApproved()) {
            visible = true;

            publishDate = reference.getCreateDate();
        }

        String summary = HtmlUtil.extractText(StringUtil.shorten(reference.getCitation(), 500));

        AssetEntry assetEntry = assetEntryLocalService.updateEntry(userId, reference.getGroupId(),
                reference.getCreateDate(), reference.getModifiedDate(), Reference.class.getName(),
                reference.getReferenceId(), reference.getUuid(), 0, assetCategoryIds, assetTagNames, true, visible,
                null, null, publishDate, null, ContentTypes.TEXT_HTML, reference.getTitle(),
                reference.getCitation(), summary, null, null, 0, 0, priority);

        assetLinkLocalService.updateLinks(userId, assetEntry.getEntryId(), assetLinkEntryIds,
                AssetLinkConstants.TYPE_RELATED);
    }

    public Reference updateReference(long referenceId, long userId, String bibTeX, ServiceContext serviceContext)
            throws PortalException {

        return updateReference(referenceId, userId, bibTeX, new long[0], serviceContext);
    }

    @Indexable(type = IndexableType.REINDEX)
    public Reference updateReference(long referenceId, long userId, String bibTeX, long[] bibliographyIds,
            ServiceContext serviceContext) throws PortalException {

        // Reference

        User user = userPersistence.findByPrimaryKey(userId);

        Reference reference = referencePersistence.findByPrimaryKey(referenceId);
        long groupId = serviceContext.getScopeGroupId();
        long companyId = user.getCompanyId();

        reference.setUuid(serviceContext.getUuid());
        reference.setGroupId(groupId);
        reference.setCompanyId(companyId);
        reference.setUserId(user.getUserId());
        reference.setUserName(user.getFullName());
        reference.setExpandoBridgeAttributes(serviceContext);

        BibTeXEntry bibTeXEntry = BibTeXUtil.getBibTeXEntry(bibTeX);
        if (bibTeXEntry != null) {
            Key key = new Key("bibshare-last-modified");
            Value value = new StringValue(String.valueOf(new Date().getTime()), Style.QUOTED);
            bibTeXEntry.addField(key, value);
        } else {
            // TODO: raise an error and report to the user that something is
            // wrong with the bibtex-src.
        }

        bibTeX = BibTeXUtil.format(bibTeXEntry);

        reference.setBibTeX(bibTeX);

        reference = referencePersistence.update(reference);

        // Match user and group references against common references

        long defaultGroupId = GetterUtil.getLong(PropsUtil.get("default.group.id"));

        if (reference.getGroupId() != defaultGroupId) {
            match(reference);
        }

        // BibRefRelation

        for (long bibliographyId : bibliographyIds) {

            Bibliography bibliography = bibliographyLocalService.getBibliography(bibliographyId);

            long bibRefRelationId = counterLocalService.increment();
            BibRefRelation bibRefRelation = bibRefRelationPersistence.create(bibRefRelationId);

            bibRefRelation.setGroupId(bibliography.getGroupId());
            bibRefRelation.setCompanyId(bibliography.getCompanyId());
            bibRefRelation.setUserId(bibliography.getUserId());
            bibRefRelation.setUserName(bibliography.getUserName());

            bibRefRelation.setBibliographyId(bibliography.getBibliographyId());
            bibRefRelation.setReferenceId(referenceId);

            bibRefRelationPersistence.update(bibRefRelation);

        }

        // Resources

        resourceLocalService.addModelResources(reference, serviceContext);

        // Asset

        updateAsset(userId, reference, serviceContext.getAssetCategoryIds(), serviceContext.getAssetTagNames(),
                serviceContext.getAssetLinkEntryIds(), serviceContext.getAssetPriority());

        // Social

        JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();

        extraDataJSONObject.put("title", reference.getCitation());

        socialActivityLocalService.addActivity(userId, groupId, Reference.class.getName(), referenceId,
                ReferenceActivityKeys.UPDATE_REFERENCE, extraDataJSONObject.toString(), 0);

        return reference;

    }

    protected SearchContext buildSearchContext(long userId, long groupId, long bibliographyId, String author,
            String title, String year, int status, LinkedHashMap<String, Object> params, boolean andSearch,
            int start, int end, Sort sort) throws PortalException {

        SearchContext searchContext = new SearchContext();

        searchContext.setAttribute(Field.STATUS, status);

        if (Validator.isNotNull(author)) {
            searchContext.setAttribute("author", author);
        }

        if (bibliographyId > 0) {
            searchContext.setAttribute("bibliographyId", bibliographyId);
        }

        if (Validator.isNotNull(title)) {
            searchContext.setAttribute("title", title);
        }

        if (Validator.isNotNull(year)) {
            searchContext.setAttribute("year", year);
        }

        searchContext.setAttribute("paginationType", "more");

        Group group = GroupLocalServiceUtil.getGroup(groupId);

        searchContext.setCompanyId(group.getCompanyId());

        searchContext.setEnd(end);
        if (groupId > 0) {
            searchContext.setGroupIds(new long[] { groupId });
        }
        searchContext.setSorts(sort);
        searchContext.setStart(start);
        searchContext.setUserId(userId);

        searchContext.setAndSearch(andSearch);

        if (params != null) {

            String keywords = (String) params.remove("keywords");

            if (Validator.isNotNull(keywords)) {
                searchContext.setKeywords(keywords);
            }
        }

        QueryConfig queryConfig = new QueryConfig();

        queryConfig.setHighlightEnabled(false);
        queryConfig.setScoreEnabled(false);

        searchContext.setQueryConfig(queryConfig);

        if (sort != null) {
            searchContext.setSorts(sort);
        }

        searchContext.setStart(start);

        return searchContext;
    }

    @ServiceReference(type = BackgroundTaskManager.class)
    protected BackgroundTaskManager backgroundTaskmanager;

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

}