001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.asset.service.impl;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.util.ArrayUtil;
021    import com.liferay.portal.model.User;
022    import com.liferay.portlet.asset.NoSuchLinkException;
023    import com.liferay.portlet.asset.model.AssetEntry;
024    import com.liferay.portlet.asset.model.AssetLink;
025    import com.liferay.portlet.asset.model.AssetLinkConstants;
026    import com.liferay.portlet.asset.service.base.AssetLinkLocalServiceBaseImpl;
027    
028    import java.util.ArrayList;
029    import java.util.Collections;
030    import java.util.Date;
031    import java.util.List;
032    
033    /**
034     * This class implements the methods needed to handle AssetLinks, the entity
035     * that relates different assets in the portal.
036     *
037     * The basic information stored for every link includes both assets entry IDs,
038     * the userId, the link type and the link's weight.
039     *
040     * @author Brian Wing Shun Chan
041     * @author Juan Fern??ndez
042     */
043    public class AssetLinkLocalServiceImpl extends AssetLinkLocalServiceBaseImpl {
044    
045            /**
046             * Adds a new asset link.
047             *
048             * @param  userId the primary key of the link's creator
049             * @param  entryId1 the primary key of the first asset entry
050             * @param  entryId2 the primary key of the second asset entry
051             * @param  type the link type. Acceptable values include {@link
052             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_RELATED}
053             *         which is a bidirectional relationship and {@link
054             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_CHILD}
055             *         which is a unidirectional relationship. For more information see
056             *         {@link com.liferay.portlet.asset.model.AssetLinkConstants}
057             * @param  weight the weight of the relationship, allowing precedence
058             *         ordering of links
059             * @return the asset link
060             * @throws PortalException if the user could not be found
061             */
062            @Override
063            public AssetLink addLink(
064                            long userId, long entryId1, long entryId2, int type, int weight)
065                    throws PortalException {
066    
067                    User user = userPersistence.findByPrimaryKey(userId);
068                    Date now = new Date();
069    
070                    long linkId = counterLocalService.increment();
071    
072                    AssetLink link = assetLinkPersistence.create(linkId);
073    
074                    link.setCompanyId(user.getCompanyId());
075                    link.setUserId(user.getUserId());
076                    link.setUserName(user.getFullName());
077                    link.setCreateDate(now);
078                    link.setEntryId1(entryId1);
079                    link.setEntryId2(entryId2);
080                    link.setType(type);
081                    link.setWeight(weight);
082    
083                    assetLinkPersistence.update(link);
084    
085                    if (AssetLinkConstants.isTypeBi(type)) {
086                            long linkId2 = counterLocalService.increment();
087    
088                            AssetLink link2 = assetLinkPersistence.create(linkId2);
089    
090                            link2.setCompanyId(user.getCompanyId());
091                            link2.setUserId(user.getUserId());
092                            link2.setUserName(user.getFullName());
093                            link2.setCreateDate(now);
094                            link2.setEntryId1(entryId2);
095                            link2.setEntryId2(entryId1);
096                            link2.setType(type);
097                            link2.setWeight(weight);
098    
099                            assetLinkPersistence.update(link2);
100                    }
101    
102                    return link;
103            }
104    
105            /**
106             * Deletes the asset link.
107             *
108             * @param link the asset link
109             */
110            @Override
111            public void deleteLink(AssetLink link) {
112                    if (AssetLinkConstants.isTypeBi(link.getType())) {
113                            try {
114                                    assetLinkPersistence.removeByE_E_T(
115                                            link.getEntryId2(), link.getEntryId1(), link.getType());
116                            }
117                            catch (NoSuchLinkException nsle) {
118                                    if (_log.isWarnEnabled()) {
119                                            _log.warn("Unable to delete asset link", nsle);
120                                    }
121                            }
122                    }
123    
124                    assetLinkPersistence.remove(link);
125            }
126    
127            /**
128             * Deletes the asset link.
129             *
130             * @param  linkId the primary key of the asset link
131             * @throws PortalException if the asset link could not be found
132             */
133            @Override
134            public void deleteLink(long linkId) throws PortalException {
135                    AssetLink link = assetLinkPersistence.findByPrimaryKey(linkId);
136    
137                    deleteLink(link);
138            }
139    
140            /**
141             * Deletes all links associated with the asset entry.
142             *
143             * @param entryId the primary key of the asset entry
144             */
145            @Override
146            public void deleteLinks(long entryId) {
147                    for (AssetLink link : assetLinkPersistence.findByE1(entryId)) {
148                            deleteLink(link);
149                    }
150    
151                    for (AssetLink link : assetLinkPersistence.findByE2(entryId)) {
152                            deleteLink(link);
153                    }
154            }
155    
156            /**
157             * Delete all links that associate the two asset entries.
158             *
159             * @param entryId1 the primary key of the first asset entry
160             * @param entryId2 the primary key of the second asset entry
161             */
162            @Override
163            public void deleteLinks(long entryId1, long entryId2) {
164                    List<AssetLink> links = assetLinkPersistence.findByE_E(
165                            entryId1, entryId2);
166    
167                    for (AssetLink link : links) {
168                            deleteLink(link);
169                    }
170            }
171    
172            /**
173             * Returns all the asset links whose first entry ID is the given entry ID.
174             *
175             * @param  entryId the primary key of the asset entry
176             * @return the asset links whose first entry ID is the given entry ID
177             */
178            @Override
179            public List<AssetLink> getDirectLinks(long entryId) {
180                    List<AssetLink> assetLinks = assetLinkPersistence.findByE1(entryId);
181    
182                    if (!assetLinks.isEmpty()) {
183                            List<AssetLink> filteredAssetLinks = new ArrayList<>(
184                                    assetLinks.size());
185    
186                            for (AssetLink assetLink : assetLinks) {
187                                    AssetEntry assetEntry = assetEntryPersistence.fetchByPrimaryKey(
188                                            assetLink.getEntryId2());
189    
190                                    if ((assetEntry != null) && assetEntry.isVisible()) {
191                                            filteredAssetLinks.add(assetLink);
192                                    }
193                            }
194    
195                            assetLinks = Collections.unmodifiableList(filteredAssetLinks);
196                    }
197    
198                    return assetLinks;
199            }
200    
201            /**
202             * Returns all the asset links of the given link type whose first entry ID
203             * is the given entry ID.
204             *
205             * @param  entryId the primary key of the asset entry
206             * @param  typeId the link type. Acceptable values include {@link
207             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_RELATED}
208             *         which is a bidirectional relationship and {@link
209             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_CHILD}
210             *         which is a unidirectional relationship. For more information see
211             *         {@link com.liferay.portlet.asset.model.AssetLinkConstants}
212             * @return the asset links of the given link type whose first entry ID is
213             *         the given entry ID
214             */
215            @Override
216            public List<AssetLink> getDirectLinks(long entryId, int typeId) {
217                    List<AssetLink> assetLinks = assetLinkPersistence.findByE1_T(
218                            entryId, typeId);
219    
220                    if (!assetLinks.isEmpty()) {
221                            List<AssetLink> filteredAssetLinks = new ArrayList<>(
222                                    assetLinks.size());
223    
224                            for (AssetLink assetLink : assetLinks) {
225                                    AssetEntry assetEntry = assetEntryPersistence.fetchByPrimaryKey(
226                                            assetLink.getEntryId2());
227    
228                                    if ((assetEntry != null) && assetEntry.isVisible()) {
229                                            filteredAssetLinks.add(assetLink);
230                                    }
231                            }
232    
233                            assetLinks = Collections.unmodifiableList(filteredAssetLinks);
234                    }
235    
236                    return assetLinks;
237            }
238    
239            /**
240             * Returns all the asset links whose first or second entry ID is the given
241             * entry ID.
242             *
243             * @param  entryId the primary key of the asset entry
244             * @return the asset links whose first or second entry ID is the given entry
245             *         ID
246             */
247            @Override
248            public List<AssetLink> getLinks(long entryId) {
249                    List<AssetLink> e1Links = assetLinkPersistence.findByE1(entryId);
250                    List<AssetLink> e2Links = assetLinkPersistence.findByE2(entryId);
251    
252                    List<AssetLink> links = new ArrayList<>(
253                            e1Links.size() + e2Links.size());
254    
255                    links.addAll(e1Links);
256                    links.addAll(e2Links);
257    
258                    return links;
259            }
260    
261            /**
262             * Returns all the asset links of the given link type whose first or second
263             * entry ID is the given entry ID.
264             *
265             * @param  entryId the primary key of the asset entry
266             * @param  typeId the link type. Acceptable values include {@link
267             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_RELATED}
268             *         which is a bidirectional relationship and {@link
269             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_CHILD}
270             *         which is a unidirectional relationship. For more information see
271             *         {@link com.liferay.portlet.asset.model.AssetLinkConstants}
272             * @return the asset links of the given link type whose first or second
273             *         entry ID is the given entry ID
274             */
275            @Override
276            public List<AssetLink> getLinks(long entryId, int typeId) {
277                    List<AssetLink> e1Links = assetLinkPersistence.findByE1_T(
278                            entryId, typeId);
279                    List<AssetLink> e2Links = assetLinkPersistence.findByE2_T(
280                            entryId, typeId);
281    
282                    List<AssetLink> links = new ArrayList<>(
283                            e1Links.size() + e2Links.size());
284    
285                    links.addAll(e1Links);
286                    links.addAll(e2Links);
287    
288                    return links;
289            }
290    
291            /**
292             * Returns all the asset links of the given link type whose second entry ID
293             * is the given entry ID.
294             *
295             * @param  entryId the primary key of the asset entry
296             * @param  typeId the link type. Acceptable values include {@link
297             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_RELATED}
298             *         which is a bidirectional relationship and {@link
299             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_CHILD}
300             *         which is a unidirectional relationship. For more information see
301             *         {@link com.liferay.portlet.asset.model.AssetLinkConstants}
302             * @return the asset links of the given link type whose second entry ID is
303             *         the given entry ID
304             */
305            @Override
306            public List<AssetLink> getReverseLinks(long entryId, int typeId) {
307                    return assetLinkPersistence.findByE2_T(entryId, typeId);
308            }
309    
310            @Override
311            public AssetLink updateLink(
312                            long userId, long entryId1, long entryId2, int typeId, int weight)
313                    throws PortalException {
314    
315                    AssetLink assetLink = assetLinkPersistence.fetchByE_E_T(
316                            entryId1, entryId2, typeId);
317    
318                    if (assetLink == null) {
319                            return addLink(userId, entryId1, entryId2, typeId, weight);
320                    }
321    
322                    assetLink.setWeight(weight);
323    
324                    assetLinkPersistence.update(assetLink);
325    
326                    return assetLink;
327            }
328    
329            /**
330             * Updates all links of the asset entry, replacing them with links
331             * associating the asset entry with the asset entries of the given link
332             * entry IDs.
333             *
334             * <p>
335             * If no link exists with a given link entry ID, a new link is created
336             * associating the current asset entry with the asset entry of that link
337             * entry ID. An existing link is deleted if either of its entry IDs is not
338             * contained in the given link entry IDs.
339             * </p>
340             *
341             * @param  userId the primary key of the user updating the links
342             * @param  entryId the primary key of the asset entry to be managed
343             * @param  linkEntryIds the primary keys of the asset entries to be linked
344             *         with the asset entry to be managed
345             * @param  typeId the type of the asset links to be created. Acceptable
346             *         values include {@link
347             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_RELATED}
348             *         which is a bidirectional relationship and {@link
349             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_CHILD}
350             *         which is a unidirectional relationship. For more information see
351             *         {@link com.liferay.portlet.asset.model.AssetLinkConstants}
352             * @throws PortalException if the user could not be found
353             */
354            @Override
355            public void updateLinks(
356                            long userId, long entryId, long[] linkEntryIds, int typeId)
357                    throws PortalException {
358    
359                    if (linkEntryIds == null) {
360                            return;
361                    }
362    
363                    List<AssetLink> links = getLinks(entryId, typeId);
364    
365                    for (AssetLink link : links) {
366                            if (((link.getEntryId1() == entryId) &&
367                                     !ArrayUtil.contains(linkEntryIds, link.getEntryId2())) ||
368                                    ((link.getEntryId2() == entryId) &&
369                                     !ArrayUtil.contains(linkEntryIds, link.getEntryId1()))) {
370    
371                                    deleteLink(link);
372                            }
373                    }
374    
375                    for (long assetLinkEntryId : linkEntryIds) {
376                            if (assetLinkEntryId != entryId) {
377                                    AssetLink link = assetLinkPersistence.fetchByE_E_T(
378                                            entryId, assetLinkEntryId, typeId);
379    
380                                    if (link == null) {
381                                            addLink(userId, entryId, assetLinkEntryId, typeId, 0);
382                                    }
383                            }
384                    }
385            }
386    
387            private static final Log _log = LogFactoryUtil.getLog(
388                    AssetLinkLocalServiceImpl.class);
389    
390    }