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.messageboards.model.impl;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portlet.messageboards.model.MBMessage;
020    import com.liferay.portlet.messageboards.model.MBTreeWalker;
021    import com.liferay.portlet.messageboards.service.MBMessageLocalService;
022    import com.liferay.portlet.messageboards.util.comparator.MessageThreadComparator;
023    
024    import java.util.ArrayList;
025    import java.util.Comparator;
026    import java.util.HashMap;
027    import java.util.List;
028    import java.util.Map;
029    
030    /**
031     * @author Brian Wing Shun Chan
032     */
033    public class MBTreeWalkerImpl implements MBTreeWalker {
034    
035            public MBTreeWalkerImpl(
036                    long threadId, int status, MBMessageLocalService messageLocalService,
037                    Comparator<MBMessage> comparator) {
038    
039                    _messageIdsMap = new HashMap<>();
040    
041                    List<MBMessage> messages = null;
042                    MBMessage rootMessage = null;
043    
044                    try {
045                            messages = messageLocalService.getThreadMessages(
046                                    threadId, status, comparator);
047    
048                            for (int i = 0; i < messages.size(); i++) {
049                                    MBMessage curMessage = messages.get(i);
050    
051                                    if (curMessage.isRoot()) {
052                                            rootMessage = curMessage;
053                                    }
054    
055                                    long parentMessageId = curMessage.getParentMessageId();
056    
057                                    if (!curMessage.isRoot() &&
058                                            !_messageIdsMap.containsKey(parentMessageId)) {
059    
060                                            _messageIdsMap.put(parentMessageId, i);
061                                    }
062                            }
063                    }
064                    catch (Exception e) {
065                            _log.error(e);
066                    }
067    
068                    _messages = messages;
069                    _rootMessage = rootMessage;
070            }
071    
072            /**
073             * @deprecated As of 7.0.0, replaced by {@link #MBTreeWalkerImpl(long, int,
074             *             MBMessageLocalService, Comparator)}
075             */
076            @Deprecated
077            public MBTreeWalkerImpl(
078                    MBMessage message, int status,
079                    MBMessageLocalService messageLocalService) {
080    
081                    this(
082                            message.getThreadId(), status, messageLocalService,
083                            new MessageThreadComparator());
084            }
085    
086            @Override
087            public List<MBMessage> getChildren(MBMessage message) {
088                    List<MBMessage> children = new ArrayList<>();
089    
090                    int[] range = getChildrenRange(message);
091    
092                    for (int i = range[0]; i < range[1]; i++) {
093                            children.add(_messages.get(i));
094                    }
095    
096                    return children;
097            }
098    
099            @Override
100            public int[] getChildrenRange(MBMessage message) {
101                    long messageId = message.getMessageId();
102    
103                    Integer pos = _messageIdsMap.get(messageId);
104    
105                    if (pos == null) {
106                            return new int[] {0, 0};
107                    }
108    
109                    int[] range = new int[2];
110                    range[0] = pos.intValue();
111    
112                    for (int i = range[0]; i < _messages.size(); i++) {
113                            MBMessage curMessage = _messages.get(i);
114    
115                            if (curMessage.getParentMessageId() == messageId) {
116                                    range[1] = i + 1;
117                            }
118                            else {
119                                    break;
120                            }
121                    }
122    
123                    return range;
124            }
125    
126            @Override
127            public List<MBMessage> getMessages() {
128                    return _messages;
129            }
130    
131            @Override
132            public MBMessage getRoot() {
133                    return _rootMessage;
134            }
135    
136            @Override
137            public boolean isLeaf(MBMessage message) {
138                    Long messageIdObj = Long.valueOf(message.getMessageId());
139    
140                    if (_messageIdsMap.containsKey(messageIdObj)) {
141                            return false;
142                    }
143                    else {
144                            return true;
145                    }
146            }
147    
148            @Override
149            public boolean isOdd() {
150                    _odd = !_odd;
151    
152                    return _odd;
153            }
154    
155            private static final Log _log = LogFactoryUtil.getLog(
156                    MBTreeWalkerImpl.class);
157    
158            private final Map<Long, Integer> _messageIdsMap;
159            private final List<MBMessage> _messages;
160            private boolean _odd;
161            private final MBMessage _rootMessage;
162    
163    }