001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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.exception.SystemException;
019    import com.liferay.portal.kernel.util.ArrayUtil;
020    import com.liferay.portal.model.User;
021    import com.liferay.portlet.asset.NoSuchLinkException;
022    import com.liferay.portlet.asset.model.AssetEntry;
023    import com.liferay.portlet.asset.model.AssetLink;
024    import com.liferay.portlet.asset.model.AssetLinkConstants;
025    import com.liferay.portlet.asset.service.base.AssetLinkLocalServiceBaseImpl;
026    
027    import java.util.ArrayList;
028    import java.util.Collections;
029    import java.util.Date;
030    import java.util.List;
031    
032    /**
033     * This class implements the methods needed to handle AssetLinks, the entity
034     * that relates different assets in the portal.
035     *
036     * The basic information stored for every link includes both assets entry IDs,
037     * the userId, the link type and the link's weight.
038     *
039     * @author Brian Wing Shun Chan
040     * @author Juan Fern??ndez
041     */
042    public class AssetLinkLocalServiceImpl extends AssetLinkLocalServiceBaseImpl {
043    
044            /**
045             * Adds a new asset link.
046             *
047             * @param  userId the primary key of the link's creator
048             * @param  entryId1 the primary key of the first asset entry
049             * @param  entryId2 the primary key of the second asset entry
050             * @param  type the link type. Acceptable values include {@link
051             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_RELATED}
052             *         which is a bidirectional relationship and {@link
053             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_CHILD}
054             *         which is a unidirectional relationship. For more information see
055             *         {@link com.liferay.portlet.asset.model.AssetLinkConstants}
056             * @param  weight the weight of the relationship, allowing precedence
057             *         ordering of links
058             * @return the asset link
059             * @throws PortalException if the user could not be found
060             * @throws SystemException if a system exception occurred
061             */
062            @Override
063            public AssetLink addLink(
064                            long userId, long entryId1, long entryId2, int type, int weight)
065                    throws PortalException, SystemException {
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             * @throws SystemException if a system exception occurred
110             */
111            @Override
112            public void deleteLink(AssetLink link) throws SystemException {
113                    if (AssetLinkConstants.isTypeBi(link.getType())) {
114                            try {
115                                    assetLinkPersistence.removeByE_E_T(
116                                            link.getEntryId2(), link.getEntryId1(), link.getType());
117                            }
118                            catch (NoSuchLinkException nsle) {
119                            }
120                    }
121    
122                    assetLinkPersistence.remove(link);
123            }
124    
125            /**
126             * Deletes the asset link.
127             *
128             * @param  linkId the primary key of the asset link
129             * @throws PortalException if the asset link could not be found
130             * @throws SystemException if a system exception occurred
131             */
132            @Override
133            public void deleteLink(long linkId)
134                    throws PortalException, SystemException {
135    
136                    AssetLink link = assetLinkPersistence.findByPrimaryKey(linkId);
137    
138                    deleteLink(link);
139            }
140    
141            /**
142             * Deletes all links associated with the asset entry.
143             *
144             * @param  entryId the primary key of the asset entry
145             * @throws SystemException if a system exception occurred
146             */
147            @Override
148            public void deleteLinks(long entryId) throws SystemException {
149                    for (AssetLink link : assetLinkPersistence.findByE1(entryId)) {
150                            deleteLink(link);
151                    }
152    
153                    for (AssetLink link : assetLinkPersistence.findByE2(entryId)) {
154                            deleteLink(link);
155                    }
156            }
157    
158            /**
159             * Delete all links that associate the two asset entries.
160             *
161             * @param  entryId1 the primary key of the first asset entry
162             * @param  entryId2 the primary key of the second asset entry
163             * @throws SystemException if a system exception occurred
164             */
165            @Override
166            public void deleteLinks(long entryId1, long entryId2)
167                    throws SystemException {
168    
169                    List<AssetLink> links = assetLinkPersistence.findByE_E(
170                            entryId1, entryId2);
171    
172                    for (AssetLink link : links) {
173                            deleteLink(link);
174                    }
175            }
176    
177            /**
178             * Returns all the asset links whose first entry ID is the given entry ID.
179             *
180             * @param  entryId the primary key of the asset entry
181             * @return the asset links whose first entry ID is the given entry ID
182             * @throws SystemException if a system exception occurred
183             */
184            @Override
185            public List<AssetLink> getDirectLinks(long entryId) throws SystemException {
186                    return getDirectLinks(entryId, true);
187            }
188    
189            @Override
190            public List<AssetLink> getDirectLinks(
191                            long entryId, boolean excludeInvisibleLinks)
192                    throws SystemException {
193    
194                    List<AssetLink> assetLinks = assetLinkPersistence.findByE1(entryId);
195    
196                    return filterAssetLinks(assetLinks, excludeInvisibleLinks);
197            }
198    
199            /**
200             * Returns all the asset links of the given link type whose first entry ID
201             * is the given entry ID.
202             *
203             * @param  entryId the primary key of the asset entry
204             * @param  typeId the link type. Acceptable values include {@link
205             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_RELATED}
206             *         which is a bidirectional relationship and {@link
207             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_CHILD}
208             *         which is a unidirectional relationship. For more information see
209             *         {@link com.liferay.portlet.asset.model.AssetLinkConstants}
210             * @return the asset links of the given link type whose first entry ID is
211             *         the given entry ID
212             * @throws SystemException if a system exception occurred
213             */
214            @Override
215            public List<AssetLink> getDirectLinks(long entryId, int typeId)
216                    throws SystemException {
217    
218                    return getDirectLinks(entryId, typeId, true);
219            }
220    
221            @Override
222            public List<AssetLink> getDirectLinks(
223                            long entryId, int typeId, boolean excludeInvisibleLinks)
224                    throws SystemException {
225    
226                    List<AssetLink> assetLinks = assetLinkPersistence.findByE1_T(
227                            entryId, typeId);
228    
229                    return filterAssetLinks(assetLinks, excludeInvisibleLinks);
230            }
231    
232            /**
233             * Returns all the asset links whose first or second entry ID is the given
234             * entry ID.
235             *
236             * @param  entryId the primary key of the asset entry
237             * @return the asset links whose first or second entry ID is the given entry
238             *         ID
239             * @throws SystemException if a system exception occurred
240             */
241            @Override
242            public List<AssetLink> getLinks(long entryId) throws SystemException {
243                    List<AssetLink> e1Links = assetLinkPersistence.findByE1(entryId);
244                    List<AssetLink> e2Links = assetLinkPersistence.findByE2(entryId);
245    
246                    List<AssetLink> links = new ArrayList<AssetLink>(
247                            e1Links.size() + e2Links.size());
248    
249                    links.addAll(e1Links);
250                    links.addAll(e2Links);
251    
252                    return links;
253            }
254    
255            /**
256             * Returns all the asset links of the given link type whose first or second
257             * entry ID is the given entry ID.
258             *
259             * @param  entryId the primary key of the asset entry
260             * @param  typeId the link type. Acceptable values include {@link
261             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_RELATED}
262             *         which is a bidirectional relationship and {@link
263             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_CHILD}
264             *         which is a unidirectional relationship. For more information see
265             *         {@link com.liferay.portlet.asset.model.AssetLinkConstants}
266             * @return the asset links of the given link type whose first or second
267             *         entry ID is the given entry ID
268             * @throws SystemException if a system exception occurred
269             */
270            @Override
271            public List<AssetLink> getLinks(long entryId, int typeId)
272                    throws SystemException {
273    
274                    List<AssetLink> e1Links = assetLinkPersistence.findByE1_T(
275                            entryId, typeId);
276                    List<AssetLink> e2Links = assetLinkPersistence.findByE2_T(
277                            entryId, typeId);
278    
279                    List<AssetLink> links = new ArrayList<AssetLink>(
280                            e1Links.size() + e2Links.size());
281    
282                    links.addAll(e1Links);
283                    links.addAll(e2Links);
284    
285                    return links;
286            }
287    
288            /**
289             * Returns all the asset links of the given link type whose second entry ID
290             * is the given entry ID.
291             *
292             * @param  entryId the primary key of the asset entry
293             * @param  typeId the link type. Acceptable values include {@link
294             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_RELATED}
295             *         which is a bidirectional relationship and {@link
296             *         com.liferay.portlet.asset.model.AssetLinkConstants#TYPE_CHILD}
297             *         which is a unidirectional relationship. For more information see
298             *         {@link com.liferay.portlet.asset.model.AssetLinkConstants}
299             * @return the asset links of the given link type whose second entry ID is
300             *         the given entry ID
301             * @throws SystemException if a system exception occurred
302             */
303            @Override
304            public List<AssetLink> getReverseLinks(long entryId, int typeId)
305                    throws SystemException {
306    
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, SystemException {
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             * @throws SystemException if a system exception occurred
354             */
355            @Override
356            public void updateLinks(
357                            long userId, long entryId, long[] linkEntryIds, int typeId)
358                    throws PortalException, SystemException {
359    
360                    if (linkEntryIds == null) {
361                            return;
362                    }
363    
364                    List<AssetLink> links = getLinks(entryId, typeId);
365    
366                    for (AssetLink link : links) {
367                            if (((link.getEntryId1() == entryId) &&
368                                     !ArrayUtil.contains(linkEntryIds, link.getEntryId2())) ||
369                                    ((link.getEntryId2() == entryId) &&
370                                     !ArrayUtil.contains(linkEntryIds, link.getEntryId1()))) {
371    
372                                    deleteLink(link);
373                            }
374                    }
375    
376                    for (long assetLinkEntryId : linkEntryIds) {
377                            if (assetLinkEntryId != entryId) {
378                                    AssetLink link = assetLinkPersistence.fetchByE_E_T(
379                                            entryId, assetLinkEntryId, typeId);
380    
381                                    if (link == null) {
382                                            addLink(userId, entryId, assetLinkEntryId, typeId, 0);
383                                    }
384                            }
385                    }
386            }
387    
388            protected List<AssetLink> filterAssetLinks(
389                            List<AssetLink> assetLinks, boolean excludeInvisibleLinks)
390                    throws SystemException {
391    
392                    if (assetLinks.isEmpty() || !excludeInvisibleLinks) {
393                            return assetLinks;
394                    }
395    
396                    List<AssetLink> filteredAssetLinks = new ArrayList<AssetLink>(
397                            assetLinks.size());
398    
399                    for (AssetLink assetLink : assetLinks) {
400                            AssetEntry assetEntry = assetEntryPersistence.fetchByPrimaryKey(
401                                    assetLink.getEntryId2());
402    
403                            if ((assetEntry != null) && assetEntry.isVisible()) {
404                                    filteredAssetLinks.add(assetLink);
405                            }
406                    }
407    
408                    assetLinks = Collections.unmodifiableList(filteredAssetLinks);
409    
410                    return assetLinks;
411            }
412    
413    }