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;
016    
017    import com.liferay.portal.kernel.cache.PortalCache;
018    import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
019    import com.liferay.portal.kernel.cache.key.CacheKeyGenerator;
020    import com.liferay.portal.kernel.cache.key.CacheKeyGeneratorUtil;
021    import com.liferay.portal.kernel.exception.PortalException;
022    import com.liferay.portal.kernel.exception.SystemException;
023    import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
024    import com.liferay.portal.kernel.log.Log;
025    import com.liferay.portal.kernel.log.LogFactoryUtil;
026    import com.liferay.portal.kernel.portlet.LiferayPortletMode;
027    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
028    import com.liferay.portal.kernel.util.GetterUtil;
029    import com.liferay.portal.kernel.util.JavaConstants;
030    import com.liferay.portal.kernel.util.ParamUtil;
031    import com.liferay.portal.kernel.util.StringPool;
032    import com.liferay.portal.kernel.util.Validator;
033    import com.liferay.portal.kernel.util.WebKeys;
034    import com.liferay.portal.model.Group;
035    import com.liferay.portal.model.Layout;
036    import com.liferay.portal.model.LayoutConstants;
037    import com.liferay.portal.model.LayoutTypePortlet;
038    import com.liferay.portal.model.Portlet;
039    import com.liferay.portal.model.PortletConstants;
040    import com.liferay.portal.model.PortletPreferencesIds;
041    import com.liferay.portal.security.auth.PrincipalException;
042    import com.liferay.portal.security.permission.ActionKeys;
043    import com.liferay.portal.security.permission.PermissionChecker;
044    import com.liferay.portal.security.permission.PermissionThreadLocal;
045    import com.liferay.portal.service.GroupLocalServiceUtil;
046    import com.liferay.portal.service.PortalPreferencesLocalServiceUtil;
047    import com.liferay.portal.service.PortletLocalServiceUtil;
048    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
049    import com.liferay.portal.service.UserLocalServiceUtil;
050    import com.liferay.portal.service.permission.LayoutPermissionUtil;
051    import com.liferay.portal.service.permission.PortletPermissionUtil;
052    import com.liferay.portal.theme.ThemeDisplay;
053    import com.liferay.portal.util.PortalUtil;
054    import com.liferay.portal.util.PortletKeys;
055    import com.liferay.portal.util.PropsValues;
056    import com.liferay.portal.xml.StAXReaderUtil;
057    import com.liferay.portlet.portletconfiguration.util.ConfigurationPortletRequest;
058    
059    import java.util.ArrayList;
060    import java.util.Collections;
061    import java.util.HashMap;
062    import java.util.List;
063    import java.util.Map;
064    
065    import javax.portlet.PortletPreferences;
066    import javax.portlet.PortletRequest;
067    import javax.portlet.PreferencesValidator;
068    import javax.portlet.filter.PortletRequestWrapper;
069    
070    import javax.servlet.http.HttpServletRequest;
071    import javax.servlet.http.HttpSession;
072    
073    import javax.xml.stream.XMLEventReader;
074    import javax.xml.stream.XMLInputFactory;
075    import javax.xml.stream.XMLStreamException;
076    import javax.xml.stream.events.EndElement;
077    import javax.xml.stream.events.StartElement;
078    import javax.xml.stream.events.XMLEvent;
079    
080    /**
081     * @author Brian Wing Shun Chan
082     * @author Alexander Chow
083     * @author Minhchau Dang
084     * @author Raymond Aug??
085     */
086    @DoPrivileged
087    public class PortletPreferencesFactoryImpl
088            implements PortletPreferencesFactory {
089    
090            public static Map<String, Preference> createPreferencesMap(String xml) {
091                    XMLEventReader xmlEventReader = null;
092    
093                    Map<String, Preference> preferencesMap = new HashMap<>();
094    
095                    try {
096                            XMLInputFactory xmlInputFactory =
097                                    StAXReaderUtil.getXMLInputFactory();
098    
099                            xmlEventReader = xmlInputFactory.createXMLEventReader(
100                                    new UnsyncStringReader(xml));
101    
102                            while (xmlEventReader.hasNext()) {
103                                    XMLEvent xmlEvent = xmlEventReader.nextEvent();
104    
105                                    if (xmlEvent.isStartElement()) {
106                                            StartElement startElement = xmlEvent.asStartElement();
107    
108                                            String elementName = startElement.getName().getLocalPart();
109    
110                                            if (elementName.equals("preference")) {
111                                                    Preference preference = readPreference(xmlEventReader);
112    
113                                                    preferencesMap.put(preference.getName(), preference);
114                                            }
115                                    }
116                            }
117                    }
118                    catch (XMLStreamException xse) {
119                            throw new SystemException(xse);
120                    }
121                    finally {
122                            if (xmlEventReader != null) {
123                                    try {
124                                            xmlEventReader.close();
125                                    }
126                                    catch (XMLStreamException xse) {
127                                            if (_log.isDebugEnabled()) {
128                                                    _log.debug(xse, xse);
129                                            }
130                                    }
131                            }
132                    }
133    
134                    return preferencesMap;
135            }
136    
137            @Override
138            public void checkControlPanelPortletPreferences(
139                            ThemeDisplay themeDisplay, Portlet portlet)
140                    throws PortalException {
141    
142                    Layout layout = themeDisplay.getLayout();
143    
144                    Group group = layout.getGroup();
145    
146                    if (!group.isControlPanel()) {
147                            return;
148                    }
149    
150                    String portletId = portlet.getPortletId();
151    
152                    boolean hasControlPanelAccessPermission =
153                            PortletPermissionUtil.hasControlPanelAccessPermission(
154                                    themeDisplay.getPermissionChecker(),
155                                    themeDisplay.getScopeGroupId(), portletId);
156    
157                    if (!hasControlPanelAccessPermission) {
158                            return;
159                    }
160    
161                    PortletPreferences portletSetup = getStrictLayoutPortletSetup(
162                            layout, portletId);
163    
164                    if (portletSetup instanceof StrictPortletPreferencesImpl) {
165                            getLayoutPortletSetup(layout, portletId);
166                    }
167    
168                    if (portlet.isInstanceable()) {
169                            return;
170                    }
171    
172                    PortletPreferencesIds portletPreferencesIds = getPortletPreferencesIds(
173                            themeDisplay.getScopeGroupId(), themeDisplay.getUserId(), layout,
174                            portletId, false);
175    
176                    PortletPreferencesLocalServiceUtil.getPreferences(
177                            portletPreferencesIds);
178            }
179    
180            @Override
181            public PortletPreferences fromDefaultXML(String xml) {
182                    Map<String, Preference> preferencesMap = toPreferencesMap(xml);
183    
184                    return new PortletPreferencesImpl(xml, preferencesMap);
185            }
186    
187            @Override
188            public PortalPreferencesImpl fromXML(
189                    long ownerId, int ownerType, String xml) {
190    
191                    Map<String, Preference> preferencesMap = toPreferencesMap(xml);
192    
193                    return new PortalPreferencesImpl(
194                            ownerId, ownerType, xml, preferencesMap, false);
195            }
196    
197            @Override
198            public PortletPreferencesImpl fromXML(
199                    long companyId, long ownerId, int ownerType, long plid,
200                    String portletId, String xml) {
201    
202                    Map<String, Preference> preferencesMap = toPreferencesMap(xml);
203    
204                    return new PortletPreferencesImpl(
205                            companyId, ownerId, ownerType, plid, portletId, xml,
206                            preferencesMap);
207            }
208    
209            /**
210             * @deprecated As of 6.2.0, replaced by {@link #fromXML(long, int, String)}
211             */
212            @Deprecated
213            @Override
214            public PortalPreferences fromXML(
215                    long companyId, long ownerId, int ownerType, String xml) {
216    
217                    return fromXML(ownerId, ownerType, xml);
218            }
219    
220            @Override
221            public PortletPreferences getExistingPortletSetup(
222                            Layout layout, String portletId)
223                    throws PortalException {
224    
225                    if (Validator.isNull(portletId)) {
226                            return null;
227                    }
228    
229                    PortletPreferences portletPreferences = getStrictPortletSetup(
230                            layout, portletId);
231    
232                    if (portletPreferences instanceof StrictPortletPreferencesImpl) {
233                            throw new PrincipalException();
234                    }
235    
236                    return portletPreferences;
237            }
238    
239            @Override
240            public PortletPreferences getExistingPortletSetup(
241                            PortletRequest portletRequest)
242                    throws PortalException {
243    
244                    String portletResource = ParamUtil.getString(
245                            portletRequest, "portletResource");
246    
247                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
248                            WebKeys.THEME_DISPLAY);
249    
250                    return getExistingPortletSetup(
251                            themeDisplay.getLayout(), portletResource);
252            }
253    
254            @Override
255            public PortletPreferences getLayoutPortletSetup(
256                    Layout layout, String portletId) {
257    
258                    return getLayoutPortletSetup(layout, portletId, null);
259            }
260    
261            @Override
262            public PortletPreferences getLayoutPortletSetup(
263                    Layout layout, String portletId, String defaultPreferences) {
264    
265                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
266                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
267    
268                    if (PortletConstants.hasUserId(portletId)) {
269                            ownerId = PortletConstants.getUserId(portletId);
270                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
271                    }
272    
273                    return getLayoutPortletSetup(
274                            layout.getCompanyId(), ownerId, ownerType, layout.getPlid(),
275                            portletId, defaultPreferences);
276            }
277    
278            @Override
279            public PortletPreferences getLayoutPortletSetup(
280                    long companyId, long ownerId, int ownerType, long plid,
281                    String portletId, String defaultPreferences) {
282    
283                    return PortletPreferencesLocalServiceUtil.getPreferences(
284                            companyId, ownerId, ownerType, plid, portletId, defaultPreferences);
285            }
286    
287            @Override
288            public PortalPreferences getPortalPreferences(HttpServletRequest request) {
289                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
290                            WebKeys.THEME_DISPLAY);
291    
292                    return getPortalPreferences(
293                            request.getSession(), themeDisplay.getUserId(),
294                            themeDisplay.isSignedIn());
295            }
296    
297            @Override
298            public PortalPreferences getPortalPreferences(
299                    HttpSession session, long userId, boolean signedIn) {
300    
301                    long ownerId = userId;
302                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
303    
304                    PortalPreferences portalPreferences = null;
305    
306                    if (signedIn) {
307                            PortalPreferencesWrapper portalPreferencesWrapper =
308                                    PortalPreferencesWrapperCacheUtil.get(ownerId, ownerType);
309    
310                            if (portalPreferencesWrapper == null) {
311                                    portalPreferencesWrapper =
312                                            (PortalPreferencesWrapper)
313                                                    PortalPreferencesLocalServiceUtil.getPreferences(
314                                                            ownerId, ownerType);
315    
316                                    portalPreferences =
317                                            portalPreferencesWrapper.getPortalPreferencesImpl();
318                            }
319                            else {
320                                    PortalPreferencesImpl portalPreferencesImpl =
321                                            portalPreferencesWrapper.getPortalPreferencesImpl();
322    
323                                    portalPreferences = portalPreferencesImpl.clone();
324                            }
325                    }
326                    else {
327                            if (session != null) {
328                                    portalPreferences = (PortalPreferences)session.getAttribute(
329                                            WebKeys.PORTAL_PREFERENCES);
330                            }
331    
332                            if (portalPreferences == null) {
333                                    PortalPreferencesWrapper portalPreferencesWrapper =
334                                            PortalPreferencesWrapperCacheUtil.get(ownerId, ownerType);
335    
336                                    if (portalPreferencesWrapper == null) {
337                                            portalPreferencesWrapper =
338                                                    (PortalPreferencesWrapper)
339                                                            PortalPreferencesLocalServiceUtil.getPreferences(
340                                                                    ownerId, ownerType);
341    
342                                            portalPreferences =
343                                                    portalPreferencesWrapper.getPortalPreferencesImpl();
344                                    }
345                                    else {
346                                            PortalPreferencesImpl portalPreferencesImpl =
347                                                    portalPreferencesWrapper.getPortalPreferencesImpl();
348    
349                                            portalPreferences = portalPreferencesImpl.clone();
350                                    }
351    
352                                    if (session != null) {
353                                            session.setAttribute(
354                                                    WebKeys.PORTAL_PREFERENCES, portalPreferences);
355                                    }
356                            }
357                    }
358    
359                    portalPreferences.setSignedIn(signedIn);
360                    portalPreferences.setUserId(userId);
361    
362                    return portalPreferences;
363            }
364    
365            /**
366             * @deprecated As of 6.2.0, replaced by {@link
367             *             #getPortalPreferences(HttpSession, long, boolean)}
368             */
369            @Deprecated
370            @Override
371            public PortalPreferences getPortalPreferences(
372                    HttpSession session, long companyId, long userId, boolean signedIn) {
373    
374                    return getPortalPreferences(session, userId, signedIn);
375            }
376    
377            @Override
378            public PortalPreferences getPortalPreferences(
379                    long userId, boolean signedIn) {
380    
381                    return getPortalPreferences(null, userId, signedIn);
382            }
383    
384            /**
385             * @deprecated As of 6.2.0, replaced by {@link #getPortalPreferences(long,
386             *             boolean)}
387             */
388            @Deprecated
389            @Override
390            public PortalPreferences getPortalPreferences(
391                    long companyId, long userId, boolean signedIn) {
392    
393                    return getPortalPreferences(userId, signedIn);
394            }
395    
396            @Override
397            public PortalPreferences getPortalPreferences(
398                    PortletRequest portletRequest) {
399    
400                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
401                            portletRequest);
402    
403                    return getPortalPreferences(request);
404            }
405    
406            @Override
407            public PortletPreferences getPortletPreferences(
408                            HttpServletRequest request, String portletId)
409                    throws PortalException {
410    
411                    PortletPreferencesIds portletPreferencesIds = getPortletPreferencesIds(
412                            request, portletId);
413    
414                    return PortletPreferencesLocalServiceUtil.getPreferences(
415                            portletPreferencesIds);
416            }
417    
418            @Override
419            public PortletPreferencesIds getPortletPreferencesIds(
420                            HttpServletRequest request, Layout layout, String portletId)
421                    throws PortalException {
422    
423                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
424                            WebKeys.THEME_DISPLAY);
425    
426                    long siteGroupId = themeDisplay.getSiteGroupId();
427                    long userId = PortalUtil.getUserId(request);
428                    LayoutTypePortlet layoutTypePortlet =
429                            themeDisplay.getLayoutTypePortlet();
430    
431                    boolean modeEditGuest = false;
432    
433                    String portletMode = ParamUtil.getString(request, "p_p_mode");
434    
435                    if (portletMode.equals(LiferayPortletMode.EDIT_GUEST.toString()) ||
436                            ((layoutTypePortlet != null) &&
437                             layoutTypePortlet.hasModeEditGuestPortletId(portletId))) {
438    
439                            modeEditGuest = true;
440                    }
441    
442                    return getPortletPreferencesIds(
443                            siteGroupId, userId, layout, portletId, modeEditGuest);
444            }
445    
446            @Override
447            public PortletPreferencesIds getPortletPreferencesIds(
448                            HttpServletRequest request, String portletId)
449                    throws PortalException {
450    
451                    Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
452    
453                    return getPortletPreferencesIds(request, layout, portletId);
454            }
455    
456            @Override
457            public PortletPreferencesIds getPortletPreferencesIds(
458                            long siteGroupId, long userId, Layout layout, String portletId,
459                            boolean modeEditGuest)
460                    throws PortalException {
461    
462                    PermissionChecker permissionChecker =
463                            PermissionThreadLocal.getPermissionChecker();
464    
465                    String originalPortletId = portletId;
466    
467                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
468                            layout.getCompanyId(), portletId);
469    
470                    long ownerId = 0;
471                    int ownerType = 0;
472                    long plid = 0;
473    
474                    if (modeEditGuest) {
475                            boolean hasUpdateLayoutPermission = LayoutPermissionUtil.contains(
476                                    permissionChecker, layout, ActionKeys.UPDATE);
477    
478                            if (!layout.isPrivateLayout() && hasUpdateLayoutPermission) {
479                            }
480                            else {
481    
482                                    // Only users with the correct permissions can update guest
483                                    // preferences
484    
485                                    throw new PrincipalException.MustHavePermission(
486                                            permissionChecker, Layout.class.getName(),
487                                            layout.getLayoutId(), ActionKeys.UPDATE);
488                            }
489                    }
490    
491                    if (PortletConstants.hasUserId(originalPortletId) &&
492                            (PortletConstants.getUserId(originalPortletId) == userId)) {
493    
494                            ownerId = userId;
495                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
496                            plid = layout.getPlid();
497                    }
498                    else if (portlet.isPreferencesCompanyWide()) {
499                            ownerId = layout.getCompanyId();
500                            ownerType = PortletKeys.PREFS_OWNER_TYPE_COMPANY;
501                            plid = PortletKeys.PREFS_PLID_SHARED;
502                            portletId = PortletConstants.getRootPortletId(portletId);
503                    }
504                    else {
505                            if (portlet.isPreferencesUniquePerLayout()) {
506                                    ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
507                                    ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
508                                    plid = layout.getPlid();
509    
510                                    LayoutTypePortlet layoutTypePortlet =
511                                            (LayoutTypePortlet)layout.getLayoutType();
512    
513                                    if (layoutTypePortlet.isPortletEmbedded(portletId)) {
514                                            plid = PortletKeys.PREFS_PLID_SHARED;
515                                    }
516    
517                                    if (portlet.isPreferencesOwnedByGroup()) {
518                                    }
519                                    else {
520                                            if ((userId <= 0) || modeEditGuest) {
521                                                    userId = UserLocalServiceUtil.getDefaultUserId(
522                                                            layout.getCompanyId());
523                                            }
524    
525                                            ownerId = userId;
526                                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
527                                    }
528                            }
529                            else {
530                                    plid = PortletKeys.PREFS_PLID_SHARED;
531    
532                                    if (portlet.isPreferencesOwnedByGroup()) {
533                                            ownerId = siteGroupId;
534                                            ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
535                                            portletId = PortletConstants.getRootPortletId(portletId);
536                                    }
537                                    else {
538                                            if ((userId <= 0) || modeEditGuest) {
539                                                    userId = UserLocalServiceUtil.getDefaultUserId(
540                                                            layout.getCompanyId());
541                                            }
542    
543                                            ownerId = userId;
544                                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
545                                    }
546                            }
547                    }
548    
549                    return new PortletPreferencesIds(
550                            layout.getCompanyId(), ownerId, ownerType, plid, portletId);
551            }
552    
553            @Override
554            public PortletPreferencesIds getPortletPreferencesIds(
555                    long companyId, long siteGroupId, long plid, String portletId,
556                    String settingsScope) {
557    
558                    int ownerType = 0;
559                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
560    
561                    if (settingsScope.equals(
562                                    PortletPreferencesFactoryConstants.SETTINGS_SCOPE_COMPANY)) {
563    
564                            ownerId = companyId;
565                            ownerType = PortletKeys.PREFS_OWNER_TYPE_COMPANY;
566                            plid = PortletKeys.PREFS_PLID_SHARED;
567                    }
568                    else if (settingsScope.equals(
569                                            PortletPreferencesFactoryConstants.SETTINGS_SCOPE_GROUP)) {
570    
571                            ownerId = siteGroupId;
572                            ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
573                            plid = PortletKeys.PREFS_PLID_SHARED;
574                    }
575                    else if (settingsScope.equals(
576                                            PortletPreferencesFactoryConstants.
577                                                    SETTINGS_SCOPE_PORTLET_INSTANCE)) {
578    
579                            ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
580                            ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
581    
582                            if (PortletConstants.hasUserId(portletId)) {
583                                    ownerId = PortletConstants.getUserId(portletId);
584                                    ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
585                            }
586                    }
587    
588                    return new PortletPreferencesIds(
589                            companyId, ownerId, ownerType, plid, portletId);
590            }
591    
592            @Override
593            public PortletPreferences getPortletSetup(
594                    HttpServletRequest request, String portletId) {
595    
596                    return getPortletSetup(request, portletId, null);
597            }
598    
599            @Override
600            public PortletPreferences getPortletSetup(
601                    HttpServletRequest request, String portletId,
602                    String defaultPreferences) {
603    
604                    PortletRequest portletRequest = (PortletRequest)request.getAttribute(
605                            JavaConstants.JAVAX_PORTLET_REQUEST);
606    
607                    if (portletRequest instanceof ConfigurationPortletRequest) {
608                            PortletRequestWrapper portletRequestWrapper =
609                                    (PortletRequestWrapper)portletRequest;
610    
611                            return portletRequestWrapper.getPreferences();
612                    }
613    
614                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
615                            WebKeys.THEME_DISPLAY);
616    
617                    return getPortletSetup(
618                            themeDisplay.getSiteGroupId(), themeDisplay.getLayout(), portletId,
619                            defaultPreferences);
620            }
621    
622            @Override
623            public PortletPreferences getPortletSetup(
624                    Layout layout, String portletId, String defaultPreferences) {
625    
626                    return getPortletSetup(
627                            LayoutConstants.DEFAULT_PLID, layout, portletId,
628                            defaultPreferences);
629            }
630    
631            @Override
632            public PortletPreferences getPortletSetup(
633                    long siteGroupId, Layout layout, String portletId,
634                    String defaultPreferences) {
635    
636                    return getPortletSetup(
637                            siteGroupId, layout, portletId, defaultPreferences, false);
638            }
639    
640            @Override
641            public PortletPreferences getPortletSetup(PortletRequest portletRequest) {
642                    String portletId = PortalUtil.getPortletId(portletRequest);
643    
644                    return getPortletSetup(portletRequest, portletId);
645            }
646    
647            @Override
648            public PortletPreferences getPortletSetup(
649                    PortletRequest portletRequest, String portletId) {
650    
651                    if (portletRequest instanceof ConfigurationPortletRequest) {
652                            PortletRequestWrapper portletRequestWrapper =
653                                    (PortletRequestWrapper)portletRequest;
654    
655                            return portletRequestWrapper.getPreferences();
656                    }
657    
658                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
659                            portletRequest);
660    
661                    return getPortletSetup(request, portletId);
662            }
663    
664            @Override
665            public Map<Long, PortletPreferences> getPortletSetupMap(
666                    long companyId, long groupId, long ownerId, int ownerType,
667                    String portletId, boolean privateLayout) {
668    
669                    Map<Long, PortletPreferences> portletSetupMap = new HashMap<>();
670    
671                    List<com.liferay.portal.model.PortletPreferences>
672                            portletPreferencesList =
673                                    PortletPreferencesLocalServiceUtil.getPortletPreferences(
674                                            companyId, groupId, ownerId, ownerType, portletId,
675                                            privateLayout);
676    
677                    for (com.liferay.portal.model.PortletPreferences portletPreferences :
678                                    portletPreferencesList) {
679    
680                            PortletPreferences portletSetup =
681                                    PortletPreferencesLocalServiceUtil.getPreferences(
682                                            companyId, ownerId, ownerType, portletPreferences.getPlid(),
683                                            portletId);
684    
685                            portletSetupMap.put(portletPreferences.getPlid(), portletSetup);
686                    }
687    
688                    return portletSetupMap;
689            }
690    
691            @Override
692            public PortletPreferences getPreferences(HttpServletRequest request) {
693                    PortletRequest portletRequest = (PortletRequest)request.getAttribute(
694                            JavaConstants.JAVAX_PORTLET_REQUEST);
695    
696                    PortletPreferences portletPreferences = null;
697    
698                    if (portletRequest != null) {
699                            PortletPreferencesWrapper portletPreferencesWrapper =
700                                    (PortletPreferencesWrapper)portletRequest.getPreferences();
701    
702                            portletPreferences =
703                                    portletPreferencesWrapper.getPortletPreferencesImpl();
704                    }
705    
706                    return portletPreferences;
707            }
708    
709            @Override
710            public PreferencesValidator getPreferencesValidator(Portlet portlet) {
711                    return PortalUtil.getPreferencesValidator(portlet);
712            }
713    
714            @Override
715            public PortletPreferences getStrictLayoutPortletSetup(
716                    Layout layout, String portletId) {
717    
718                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
719                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
720    
721                    if (PortletConstants.hasUserId(portletId)) {
722                            ownerId = PortletConstants.getUserId(portletId);
723                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
724                    }
725    
726                    return PortletPreferencesLocalServiceUtil.getStrictPreferences(
727                            layout.getCompanyId(), ownerId, ownerType, layout.getPlid(),
728                            portletId);
729            }
730    
731            @Override
732            public PortletPreferences getStrictPortletSetup(
733                    Layout layout, String portletId) {
734    
735                    return getPortletSetup(
736                            LayoutConstants.DEFAULT_PLID, layout, portletId, StringPool.BLANK,
737                            true);
738            }
739    
740            @Override
741            public StrictPortletPreferencesImpl strictFromXML(
742                    long companyId, long ownerId, int ownerType, long plid,
743                    String portletId, String xml) {
744    
745                    Map<String, Preference> preferencesMap = toPreferencesMap(xml);
746    
747                    return new StrictPortletPreferencesImpl(
748                            companyId, ownerId, ownerType, plid, portletId, xml,
749                            preferencesMap);
750            }
751    
752            @Override
753            public String toXML(PortalPreferences portalPreferences) {
754                    PortalPreferencesImpl portalPreferencesImpl = null;
755    
756                    if (portalPreferences instanceof PortalPreferencesWrapper) {
757                            PortalPreferencesWrapper portalPreferencesWrapper =
758                                    (PortalPreferencesWrapper)portalPreferences;
759    
760                            portalPreferencesImpl =
761                                    portalPreferencesWrapper.getPortalPreferencesImpl();
762                    }
763                    else {
764                            portalPreferencesImpl = (PortalPreferencesImpl)portalPreferences;
765                    }
766    
767                    return portalPreferencesImpl.toXML();
768            }
769    
770            @Override
771            public String toXML(PortletPreferences portletPreferences) {
772                    PortletPreferencesImpl portletPreferencesImpl = null;
773    
774                    if (portletPreferences instanceof PortletPreferencesWrapper) {
775                            PortletPreferencesWrapper portletPreferencesWrapper =
776                                    (PortletPreferencesWrapper)portletPreferences;
777    
778                            portletPreferencesImpl =
779                                    portletPreferencesWrapper.getPortletPreferencesImpl();
780                    }
781                    else {
782                            portletPreferencesImpl = (PortletPreferencesImpl)portletPreferences;
783                    }
784    
785                    return portletPreferencesImpl.toXML();
786            }
787    
788            protected static Preference readPreference(XMLEventReader xmlEventReader)
789                    throws XMLStreamException {
790    
791                    String name = null;
792                    List<String> values = new ArrayList<>();
793                    boolean readOnly = false;
794    
795                    while (xmlEventReader.hasNext()) {
796                            XMLEvent xmlEvent = xmlEventReader.nextEvent();
797    
798                            if (xmlEvent.isStartElement()) {
799                                    StartElement startElement = xmlEvent.asStartElement();
800    
801                                    String elementName = startElement.getName().getLocalPart();
802    
803                                    if (elementName.equals("name")) {
804                                            name = StAXReaderUtil.read(xmlEventReader);
805                                    }
806                                    else if (elementName.equals("value")) {
807                                            String value = StAXReaderUtil.read(xmlEventReader);
808    
809                                            values.add(value);
810                                    }
811                                    else if (elementName.equals("read-only")) {
812                                            String value = StAXReaderUtil.read(xmlEventReader);
813    
814                                            readOnly = GetterUtil.getBoolean(value);
815                                    }
816                            }
817                            else if (xmlEvent.isEndElement()) {
818                                    EndElement endElement = xmlEvent.asEndElement();
819    
820                                    String elementName = endElement.getName().getLocalPart();
821    
822                                    if (elementName.equals("preference")) {
823                                            break;
824                                    }
825                            }
826                    }
827    
828                    return new Preference(
829                            name, values.toArray(new String[values.size()]), readOnly);
830            }
831    
832            protected PortletPreferences getPortletSetup(
833                    long siteGroupId, Layout layout, String portletId,
834                    String defaultPreferences, boolean strictMode) {
835    
836                    String originalPortletId = portletId;
837    
838                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
839                            layout.getCompanyId(), portletId);
840    
841                    boolean uniquePerLayout = false;
842                    boolean uniquePerGroup = false;
843    
844                    if (portlet.isPreferencesCompanyWide()) {
845                            portletId = PortletConstants.getRootPortletId(portletId);
846                    }
847                    else {
848                            if (portlet.isPreferencesUniquePerLayout()) {
849                                    uniquePerLayout = true;
850    
851                                    if (portlet.isPreferencesOwnedByGroup()) {
852                                            uniquePerGroup = true;
853                                    }
854                            }
855                            else {
856                                    if (portlet.isPreferencesOwnedByGroup()) {
857                                            uniquePerGroup = true;
858                                            portletId = PortletConstants.getRootPortletId(portletId);
859                                    }
860                            }
861                    }
862    
863                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
864                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
865                    long plid = layout.getPlid();
866    
867                    Group group = GroupLocalServiceUtil.fetchGroup(siteGroupId);
868    
869                    if ((group != null) && group.isLayout()) {
870                            plid = group.getClassPK();
871                    }
872    
873                    if (PortletConstants.hasUserId(originalPortletId)) {
874                            ownerId = PortletConstants.getUserId(originalPortletId);
875                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
876                    }
877                    else if (!uniquePerLayout) {
878                            plid = PortletKeys.PREFS_PLID_SHARED;
879    
880                            if (uniquePerGroup) {
881                                    if (siteGroupId > LayoutConstants.DEFAULT_PLID) {
882                                            ownerId = siteGroupId;
883                                    }
884                                    else {
885                                            ownerId = layout.getGroupId();
886                                    }
887    
888                                    ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
889                            }
890                            else {
891                                    ownerId = layout.getCompanyId();
892                                    ownerType = PortletKeys.PREFS_OWNER_TYPE_COMPANY;
893                            }
894                    }
895    
896                    if (strictMode) {
897                            return PortletPreferencesLocalServiceUtil.getStrictPreferences(
898                                    layout.getCompanyId(), ownerId, ownerType, plid, portletId);
899                    }
900    
901                    return PortletPreferencesLocalServiceUtil.getPreferences(
902                            layout.getCompanyId(), ownerId, ownerType, plid, portletId,
903                            defaultPreferences);
904            }
905    
906            protected Map<String, Preference> toPreferencesMap(String xml) {
907                    if (Validator.isNull(xml)) {
908                            return Collections.emptyMap();
909                    }
910    
911                    String cacheKey = _encodeCacheKey(xml);
912    
913                    Map<String, Preference> preferencesMap = _preferencesMapPortalCache.get(
914                            cacheKey);
915    
916                    if (preferencesMap != null) {
917                            return preferencesMap;
918                    }
919    
920                    preferencesMap = createPreferencesMap(xml);
921    
922                    _preferencesMapPortalCache.put(cacheKey, preferencesMap);
923    
924                    return preferencesMap;
925            }
926    
927            private String _encodeCacheKey(String xml) {
928                    if (xml.length() <=
929                                    PropsValues.PORTLET_PREFERENCES_CACHE_KEY_THRESHOLD_SIZE) {
930    
931                            return xml;
932                    }
933    
934                    CacheKeyGenerator cacheKeyGenerator =
935                            CacheKeyGeneratorUtil.getCacheKeyGenerator(
936                                    PortletPreferencesFactoryImpl.class.getName());
937    
938                    if (_log.isDebugEnabled()) {
939                            _log.debug("Cache key generator " + cacheKeyGenerator.getClass());
940                    }
941    
942                    return String.valueOf(cacheKeyGenerator.getCacheKey(xml));
943            }
944    
945            private static final Log _log = LogFactoryUtil.getLog(
946                    PortletPreferencesFactoryImpl.class);
947    
948            private final PortalCache<String, Map<String, Preference>>
949                    _preferencesMapPortalCache = SingleVMPoolUtil.getPortalCache(
950                            PortletPreferencesFactoryImpl.class.getName());
951    
952    }