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.portal.kernel.model;
016    
017    import com.liferay.portal.kernel.util.CharPool;
018    import com.liferay.portal.kernel.util.GetterUtil;
019    import com.liferay.portal.kernel.util.StringBundler;
020    import com.liferay.portal.kernel.util.StringPool;
021    import com.liferay.portal.kernel.util.StringUtil;
022    import com.liferay.portal.kernel.util.Validator;
023    
024    import java.security.InvalidParameterException;
025    
026    /**
027     * @author Brian Wing Shun Chan
028     * @author Jorge Ferrer
029     */
030    public class PortletInstance {
031    
032            public static final int PORTLET_INSTANCE_KEY_MAX_LENGTH =
033                    255 - PortletInstance._INSTANCE_SEPARATOR.length() +
034                            PortletInstance._USER_SEPARATOR.length() + 39;
035    
036            public static PortletInstance fromPortletInstanceKey(
037                    String portletInstanceKey) {
038    
039                    return new PortletInstance(
040                            _getPortletName(portletInstanceKey), _getUserId(portletInstanceKey),
041                            _getInstanceId(portletInstanceKey));
042            }
043    
044            public static PortletInstance fromPortletNameAndUserIdAndInstanceId(
045                    String portletName, String userIdAndInstanceId) {
046    
047                    UserIdAndInstanceIdEncoder userIdAndInstanceIdEncoder =
048                            _buildUserIdAndInstanceIdEncoder(userIdAndInstanceId);
049    
050                    return new PortletInstance(
051                            portletName, userIdAndInstanceIdEncoder.getUserId(),
052                            userIdAndInstanceIdEncoder.getInstanceId());
053            }
054    
055            public PortletInstance(String portletName) {
056                    this(portletName, StringUtil.randomString(12));
057            }
058    
059            public PortletInstance(String portletName, long userId) {
060                    this(portletName, userId, null);
061            }
062    
063            public PortletInstance(String portletName, long userId, String instanceId) {
064                    _validatePortletName(portletName);
065    
066                    _portletName = portletName;
067                    _userId = userId;
068                    _instanceId = instanceId;
069            }
070    
071            public PortletInstance(String portletName, String instanceId) {
072                    this(portletName, 0, instanceId);
073            }
074    
075            public String getInstanceId() {
076                    return _instanceId;
077            }
078    
079            public String getPortletInstanceKey() {
080                    StringBundler sb = new StringBundler(5);
081    
082                    sb.append(_portletName);
083    
084                    if (_userId > 0) {
085                            sb.append(_USER_SEPARATOR);
086                            sb.append(_userId);
087                    }
088    
089                    if (Validator.isNotNull(_instanceId)) {
090                            sb.append(_INSTANCE_SEPARATOR);
091                            sb.append(_instanceId);
092                    }
093    
094                    return sb.toString();
095            }
096    
097            public String getPortletName() {
098                    return _portletName;
099            }
100    
101            public long getUserId() {
102                    return _userId;
103            }
104    
105            public String getUserIdAndInstanceId() {
106                    UserIdAndInstanceIdEncoder userIdAndInstanceIdEncoder =
107                            new UserIdAndInstanceIdEncoder(_userId, _instanceId);
108    
109                    return userIdAndInstanceIdEncoder.encode();
110            }
111    
112            public boolean hasIdenticalPortletName(PortletInstance portletInstance) {
113                    return hasIdenticalPortletName(portletInstance.getPortletName());
114            }
115    
116            public boolean hasIdenticalPortletName(String portletName) {
117                    return _portletName.equals(portletName);
118            }
119    
120            public boolean hasInstanceId() {
121                    return Validator.isNotNull(_instanceId);
122            }
123    
124            public boolean hasUserId() {
125                    if (_userId > 0) {
126                            return true;
127                    }
128    
129                    return false;
130            }
131    
132            @Override
133            public String toString() {
134                    return getPortletInstanceKey();
135            }
136    
137            private static UserIdAndInstanceIdEncoder _buildUserIdAndInstanceIdEncoder(
138                    String userIdAndInstanceId) {
139    
140                    if (userIdAndInstanceId == null) {
141                            throw new InvalidParameterException(
142                                    "User ID and instance ID are null");
143                    }
144    
145                    if (userIdAndInstanceId.isEmpty()) {
146                            return new UserIdAndInstanceIdEncoder(0, null);
147                    }
148    
149                    int slashCount = StringUtil.count(userIdAndInstanceId, CharPool.SLASH);
150    
151                    if (slashCount > 0) {
152                            throw new InvalidParameterException(
153                                    "User ID and instance ID contain slashes");
154                    }
155    
156                    int underlineCount = StringUtil.count(
157                            userIdAndInstanceId, CharPool.UNDERLINE);
158    
159                    if (underlineCount > 1) {
160                            throw new InvalidParameterException(
161                                    "User ID and instance ID has more than one underscore");
162                    }
163    
164                    if (underlineCount == 1) {
165                            int index = userIdAndInstanceId.indexOf(CharPool.UNDERLINE);
166    
167                            long userId = GetterUtil.getLong(
168                                    userIdAndInstanceId.substring(0, index), -1);
169    
170                            if (userId == -1) {
171                                    throw new InvalidParameterException("User ID is not a number");
172                            }
173    
174                            String instanceId = null;
175    
176                            if (index < (userIdAndInstanceId.length() - 1)) {
177                                    instanceId = userIdAndInstanceId.substring(index + 1);
178                            }
179    
180                            return new UserIdAndInstanceIdEncoder(userId, instanceId);
181                    }
182    
183                    return new UserIdAndInstanceIdEncoder(0, userIdAndInstanceId);
184            }
185    
186            private static String _getInstanceId(String portletInstanceKey) {
187                    int index = portletInstanceKey.indexOf(_INSTANCE_SEPARATOR);
188    
189                    if (index == -1) {
190                            return null;
191                    }
192    
193                    return portletInstanceKey.substring(
194                            index + _INSTANCE_SEPARATOR.length());
195            }
196    
197            private static String _getPortletName(String portletInstanceKey) {
198                    int x = portletInstanceKey.indexOf(_USER_SEPARATOR);
199                    int y = portletInstanceKey.indexOf(_INSTANCE_SEPARATOR);
200    
201                    if ((x == -1) && (y == -1)) {
202                            return portletInstanceKey;
203                    }
204                    else if (x != -1) {
205                            return portletInstanceKey.substring(0, x);
206                    }
207    
208                    return portletInstanceKey.substring(0, y);
209            }
210    
211            private static long _getUserId(String portletInstanceKey) {
212                    int x = portletInstanceKey.indexOf(_USER_SEPARATOR);
213                    int y = portletInstanceKey.indexOf(_INSTANCE_SEPARATOR);
214    
215                    if (x == -1) {
216                            return 0;
217                    }
218    
219                    if (y != -1) {
220                            return GetterUtil.getLong(
221                                    portletInstanceKey.substring(x + _USER_SEPARATOR.length(), y));
222                    }
223    
224                    return GetterUtil.getLong(
225                            portletInstanceKey.substring(x + _USER_SEPARATOR.length()));
226            }
227    
228            private void _validatePortletName(String portletName) {
229                    for (String keyword : _PORTLET_NAME_KEYWORDS) {
230                            if (!portletName.contains(keyword)) {
231                                    continue;
232                            }
233    
234                            throw new InvalidParameterException(
235                                    "The portletName '" + portletName +
236                                            "' must not contain the keyword " + keyword);
237                    }
238            }
239    
240            private static final String _INSTANCE_SEPARATOR = "_INSTANCE_";
241    
242            private static final String _USER_SEPARATOR = "_USER_";
243    
244            private final String[] _PORTLET_NAME_KEYWORDS =
245                    {_INSTANCE_SEPARATOR, _USER_SEPARATOR};
246    
247            private final String _instanceId;
248            private final String _portletName;
249            private final long _userId;
250    
251            private static final class UserIdAndInstanceIdEncoder {
252    
253                    public UserIdAndInstanceIdEncoder(long userId, String instanceId) {
254                            _userId = userId;
255                            _instanceId = instanceId;
256                    }
257    
258                    public String encode() {
259                            if ((_userId <= 0) && Validator.isBlank(_instanceId)) {
260                                    return null;
261                            }
262    
263                            StringBundler sb = new StringBundler(3);
264    
265                            if (_userId > 0) {
266                                    sb.append(_userId);
267                                    sb.append(StringPool.UNDERLINE);
268                            }
269    
270                            if (_instanceId != null) {
271                                    sb.append(_instanceId);
272                            }
273    
274                            return sb.toString();
275                    }
276    
277                    public String getInstanceId() {
278                            return _instanceId;
279                    }
280    
281                    public long getUserId() {
282                            return _userId;
283                    }
284    
285                    @Override
286                    public String toString() {
287                            return encode();
288                    }
289    
290                    private String _instanceId;
291                    private long _userId;
292    
293            }
294    
295    }