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.model.Group;
034    import com.liferay.portal.model.Layout;
035    import com.liferay.portal.model.LayoutConstants;
036    import com.liferay.portal.model.LayoutTypePortlet;
037    import com.liferay.portal.model.Portlet;
038    import com.liferay.portal.model.PortletConstants;
039    import com.liferay.portal.model.PortletPreferencesIds;
040    import com.liferay.portal.security.auth.PrincipalException;
041    import com.liferay.portal.security.permission.ActionKeys;
042    import com.liferay.portal.security.permission.PermissionChecker;
043    import com.liferay.portal.security.permission.PermissionThreadLocal;
044    import com.liferay.portal.service.GroupLocalServiceUtil;
045    import com.liferay.portal.service.PortalPreferencesLocalServiceUtil;
046    import com.liferay.portal.service.PortletLocalServiceUtil;
047    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
048    import com.liferay.portal.service.UserLocalServiceUtil;
049    import com.liferay.portal.service.permission.LayoutPermissionUtil;
050    import com.liferay.portal.service.permission.PortletPermissionUtil;
051    import com.liferay.portal.theme.ThemeDisplay;
052    import com.liferay.portal.util.PortalUtil;
053    import com.liferay.portal.util.PortletKeys;
054    import com.liferay.portal.util.PropsValues;
055    import com.liferay.portal.util.WebKeys;
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 PortletPreferencesLocalServiceUtil.getPreferences(
274                            layout.getCompanyId(), ownerId, ownerType, layout.getPlid(),
275                            portletId, defaultPreferences);
276            }
277    
278            @Override
279            public PortalPreferences getPortalPreferences(HttpServletRequest request) {
280                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
281                            WebKeys.THEME_DISPLAY);
282    
283                    return getPortalPreferences(
284                            request.getSession(), themeDisplay.getUserId(),
285                            themeDisplay.isSignedIn());
286            }
287    
288            @Override
289            public PortalPreferences getPortalPreferences(
290                    HttpSession session, long userId, boolean signedIn) {
291    
292                    long ownerId = userId;
293                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
294    
295                    PortalPreferences portalPreferences = null;
296    
297                    if (signedIn) {
298                            PortalPreferencesWrapper portalPreferencesWrapper =
299                                    PortalPreferencesWrapperCacheUtil.get(ownerId, ownerType);
300    
301                            if (portalPreferencesWrapper == null) {
302                                    portalPreferencesWrapper =
303                                            (PortalPreferencesWrapper)
304                                                    PortalPreferencesLocalServiceUtil.getPreferences(
305                                                            ownerId, ownerType);
306    
307                                    portalPreferences =
308                                            portalPreferencesWrapper.getPortalPreferencesImpl();
309                            }
310                            else {
311                                    PortalPreferencesImpl portalPreferencesImpl =
312                                            portalPreferencesWrapper.getPortalPreferencesImpl();
313    
314                                    portalPreferences = portalPreferencesImpl.clone();
315                            }
316                    }
317                    else {
318                            if (session != null) {
319                                    portalPreferences = (PortalPreferences)session.getAttribute(
320                                            WebKeys.PORTAL_PREFERENCES);
321                            }
322    
323                            if (portalPreferences == null) {
324                                    PortalPreferencesWrapper portalPreferencesWrapper =
325                                            PortalPreferencesWrapperCacheUtil.get(ownerId, ownerType);
326    
327                                    if (portalPreferencesWrapper == null) {
328                                            portalPreferencesWrapper =
329                                                    (PortalPreferencesWrapper)
330                                                            PortalPreferencesLocalServiceUtil.getPreferences(
331                                                                    ownerId, ownerType);
332    
333                                            portalPreferences =
334                                                    portalPreferencesWrapper.getPortalPreferencesImpl();
335                                    }
336                                    else {
337                                            PortalPreferencesImpl portalPreferencesImpl =
338                                                    portalPreferencesWrapper.getPortalPreferencesImpl();
339    
340                                            portalPreferences = portalPreferencesImpl.clone();
341                                    }
342    
343                                    if (session != null) {
344                                            session.setAttribute(
345                                                    WebKeys.PORTAL_PREFERENCES, portalPreferences);
346                                    }
347                            }
348                    }
349    
350                    portalPreferences.setSignedIn(signedIn);
351                    portalPreferences.setUserId(userId);
352    
353                    return portalPreferences;
354            }
355    
356            /**
357             * @deprecated As of 6.2.0, replaced by {@link
358             *             #getPortalPreferences(HttpSession, long, boolean)}
359             */
360            @Deprecated
361            @Override
362            public PortalPreferences getPortalPreferences(
363                    HttpSession session, long companyId, long userId, boolean signedIn) {
364    
365                    return getPortalPreferences(session, userId, signedIn);
366            }
367    
368            @Override
369            public PortalPreferences getPortalPreferences(
370                    long userId, boolean signedIn) {
371    
372                    return getPortalPreferences(null, userId, signedIn);
373            }
374    
375            /**
376             * @deprecated As of 6.2.0, replaced by {@link #getPortalPreferences(long,
377             *             boolean)}
378             */
379            @Deprecated
380            @Override
381            public PortalPreferences getPortalPreferences(
382                    long companyId, long userId, boolean signedIn) {
383    
384                    return getPortalPreferences(userId, signedIn);
385            }
386    
387            @Override
388            public PortalPreferences getPortalPreferences(
389                    PortletRequest portletRequest) {
390    
391                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
392                            portletRequest);
393    
394                    return getPortalPreferences(request);
395            }
396    
397            @Override
398            public PortletPreferences getPortletPreferences(
399                            HttpServletRequest request, String portletId)
400                    throws PortalException {
401    
402                    PortletPreferencesIds portletPreferencesIds = getPortletPreferencesIds(
403                            request, portletId);
404    
405                    return PortletPreferencesLocalServiceUtil.getPreferences(
406                            portletPreferencesIds);
407            }
408    
409            @Override
410            public PortletPreferencesIds getPortletPreferencesIds(
411                            HttpServletRequest request, Layout layout, String portletId)
412                    throws PortalException {
413    
414                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
415                            WebKeys.THEME_DISPLAY);
416    
417                    long siteGroupId = themeDisplay.getSiteGroupId();
418                    long userId = PortalUtil.getUserId(request);
419                    LayoutTypePortlet layoutTypePortlet =
420                            themeDisplay.getLayoutTypePortlet();
421    
422                    boolean modeEditGuest = false;
423    
424                    String portletMode = ParamUtil.getString(request, "p_p_mode");
425    
426                    if (portletMode.equals(LiferayPortletMode.EDIT_GUEST.toString()) ||
427                            ((layoutTypePortlet != null) &&
428                             layoutTypePortlet.hasModeEditGuestPortletId(portletId))) {
429    
430                            modeEditGuest = true;
431                    }
432    
433                    return getPortletPreferencesIds(
434                            siteGroupId, userId, layout, portletId, modeEditGuest);
435            }
436    
437            @Override
438            public PortletPreferencesIds getPortletPreferencesIds(
439                            HttpServletRequest request, String portletId)
440                    throws PortalException {
441    
442                    Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
443    
444                    return getPortletPreferencesIds(request, layout, portletId);
445            }
446    
447            @Override
448            public PortletPreferencesIds getPortletPreferencesIds(
449                            long siteGroupId, long userId, Layout layout, String portletId,
450                            boolean modeEditGuest)
451                    throws PortalException {
452    
453                    PermissionChecker permissionChecker =
454                            PermissionThreadLocal.getPermissionChecker();
455    
456                    String originalPortletId = portletId;
457    
458                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
459                            layout.getCompanyId(), portletId);
460    
461                    long ownerId = 0;
462                    int ownerType = 0;
463                    long plid = 0;
464    
465                    if (modeEditGuest) {
466                            boolean hasUpdateLayoutPermission = LayoutPermissionUtil.contains(
467                                    permissionChecker, layout, ActionKeys.UPDATE);
468    
469                            if (!layout.isPrivateLayout() && hasUpdateLayoutPermission) {
470                            }
471                            else {
472    
473                                    // Only users with the correct permissions can update guest
474                                    // preferences
475    
476                                    throw new PrincipalException.MustHavePermission(
477                                            permissionChecker, Layout.class.getName(),
478                                            layout.getLayoutId(), ActionKeys.UPDATE);
479                            }
480                    }
481    
482                    if (PortletConstants.hasUserId(originalPortletId) &&
483                            (PortletConstants.getUserId(originalPortletId) == userId)) {
484    
485                            ownerId = userId;
486                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
487                            plid = layout.getPlid();
488                    }
489                    else if (portlet.isPreferencesCompanyWide()) {
490                            ownerId = layout.getCompanyId();
491                            ownerType = PortletKeys.PREFS_OWNER_TYPE_COMPANY;
492                            plid = PortletKeys.PREFS_PLID_SHARED;
493                            portletId = PortletConstants.getRootPortletId(portletId);
494                    }
495                    else {
496                            if (portlet.isPreferencesUniquePerLayout()) {
497                                    ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
498                                    ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
499                                    plid = layout.getPlid();
500    
501                                    if (portlet.isPreferencesOwnedByGroup()) {
502                                    }
503                                    else {
504                                            if ((userId <= 0) || modeEditGuest) {
505                                                    userId = UserLocalServiceUtil.getDefaultUserId(
506                                                            layout.getCompanyId());
507                                            }
508    
509                                            ownerId = userId;
510                                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
511                                    }
512                            }
513                            else {
514                                    plid = PortletKeys.PREFS_PLID_SHARED;
515    
516                                    if (portlet.isPreferencesOwnedByGroup()) {
517                                            ownerId = siteGroupId;
518                                            ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
519                                            portletId = PortletConstants.getRootPortletId(portletId);
520                                    }
521                                    else {
522                                            if ((userId <= 0) || modeEditGuest) {
523                                                    userId = UserLocalServiceUtil.getDefaultUserId(
524                                                            layout.getCompanyId());
525                                            }
526    
527                                            ownerId = userId;
528                                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
529                                    }
530                            }
531                    }
532    
533                    return new PortletPreferencesIds(
534                            layout.getCompanyId(), ownerId, ownerType, plid, portletId);
535            }
536    
537            @Override
538            public PortletPreferencesIds getPortletPreferencesIds(
539                    long companyId, long siteGroupId, long plid, String portletId,
540                    String settingsScope) {
541    
542                    int ownerType = 0;
543                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
544    
545                    if (settingsScope.equals(
546                                    PortletPreferencesFactoryConstants.SETTINGS_SCOPE_COMPANY)) {
547    
548                            ownerId = companyId;
549                            ownerType = PortletKeys.PREFS_OWNER_TYPE_COMPANY;
550                            plid = PortletKeys.PREFS_PLID_SHARED;
551                    }
552                    else if (settingsScope.equals(
553                                            PortletPreferencesFactoryConstants.SETTINGS_SCOPE_GROUP)) {
554    
555                            ownerId = siteGroupId;
556                            ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
557                            plid = PortletKeys.PREFS_PLID_SHARED;
558                    }
559                    else if (settingsScope.equals(
560                                            PortletPreferencesFactoryConstants.
561                                                    SETTINGS_SCOPE_PORTLET_INSTANCE)) {
562    
563                            ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
564                            ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
565    
566                            if (PortletConstants.hasUserId(portletId)) {
567                                    ownerId = PortletConstants.getUserId(portletId);
568                                    ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
569                            }
570                    }
571    
572                    return new PortletPreferencesIds(
573                            companyId, ownerId, ownerType, plid, portletId);
574            }
575    
576            @Override
577            public PortletPreferences getPortletSetup(
578                    HttpServletRequest request, String portletId) {
579    
580                    return getPortletSetup(request, portletId, null);
581            }
582    
583            @Override
584            public PortletPreferences getPortletSetup(
585                    HttpServletRequest request, String portletId,
586                    String defaultPreferences) {
587    
588                    PortletRequest portletRequest = (PortletRequest)request.getAttribute(
589                            JavaConstants.JAVAX_PORTLET_REQUEST);
590    
591                    if (portletRequest instanceof ConfigurationPortletRequest) {
592                            PortletRequestWrapper portletRequestWrapper =
593                                    (PortletRequestWrapper)portletRequest;
594    
595                            return portletRequestWrapper.getPreferences();
596                    }
597    
598                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
599                            WebKeys.THEME_DISPLAY);
600    
601                    return getPortletSetup(
602                            themeDisplay.getSiteGroupId(), themeDisplay.getLayout(), portletId,
603                            defaultPreferences);
604            }
605    
606            @Override
607            public PortletPreferences getPortletSetup(
608                    Layout layout, String portletId, String defaultPreferences) {
609    
610                    return getPortletSetup(
611                            LayoutConstants.DEFAULT_PLID, layout, portletId,
612                            defaultPreferences);
613            }
614    
615            @Override
616            public PortletPreferences getPortletSetup(
617                    long siteGroupId, Layout layout, String portletId,
618                    String defaultPreferences) {
619    
620                    return getPortletSetup(
621                            siteGroupId, layout, portletId, defaultPreferences, false);
622            }
623    
624            @Override
625            public PortletPreferences getPortletSetup(PortletRequest portletRequest) {
626                    String portletId = PortalUtil.getPortletId(portletRequest);
627    
628                    return getPortletSetup(portletRequest, portletId);
629            }
630    
631            @Override
632            public PortletPreferences getPortletSetup(
633                    PortletRequest portletRequest, String portletId) {
634    
635                    if (portletRequest instanceof ConfigurationPortletRequest) {
636                            PortletRequestWrapper portletRequestWrapper =
637                                    (PortletRequestWrapper)portletRequest;
638    
639                            return portletRequestWrapper.getPreferences();
640                    }
641    
642                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
643                            portletRequest);
644    
645                    return getPortletSetup(request, portletId);
646            }
647    
648            @Override
649            public Map<Long, PortletPreferences> getPortletSetupMap(
650                    long companyId, long groupId, long ownerId, int ownerType,
651                    String portletId, boolean privateLayout) {
652    
653                    Map<Long, PortletPreferences> portletSetupMap = new HashMap<>();
654    
655                    List<com.liferay.portal.model.PortletPreferences>
656                            portletPreferencesList =
657                                    PortletPreferencesLocalServiceUtil.getPortletPreferences(
658                                            companyId, groupId, ownerId, ownerType, portletId,
659                                            privateLayout);
660    
661                    for (com.liferay.portal.model.PortletPreferences portletPreferences :
662                                    portletPreferencesList) {
663    
664                            PortletPreferences portletSetup =
665                                    PortletPreferencesLocalServiceUtil.getPreferences(
666                                            companyId, ownerId, ownerType, portletPreferences.getPlid(),
667                                            portletId);
668    
669                            portletSetupMap.put(portletPreferences.getPlid(), portletSetup);
670                    }
671    
672                    return portletSetupMap;
673            }
674    
675            @Override
676            public PortletPreferences getPreferences(HttpServletRequest request) {
677                    PortletRequest portletRequest = (PortletRequest)request.getAttribute(
678                            JavaConstants.JAVAX_PORTLET_REQUEST);
679    
680                    PortletPreferences portletPreferences = null;
681    
682                    if (portletRequest != null) {
683                            PortletPreferencesWrapper portletPreferencesWrapper =
684                                    (PortletPreferencesWrapper)portletRequest.getPreferences();
685    
686                            portletPreferences =
687                                    portletPreferencesWrapper.getPortletPreferencesImpl();
688                    }
689    
690                    return portletPreferences;
691            }
692    
693            @Override
694            public PreferencesValidator getPreferencesValidator(Portlet portlet) {
695                    return PortalUtil.getPreferencesValidator(portlet);
696            }
697    
698            @Override
699            public PortletPreferences getStrictLayoutPortletSetup(
700                    Layout layout, String portletId) {
701    
702                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
703                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
704    
705                    if (PortletConstants.hasUserId(portletId)) {
706                            ownerId = PortletConstants.getUserId(portletId);
707                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
708                    }
709    
710                    return PortletPreferencesLocalServiceUtil.getStrictPreferences(
711                            layout.getCompanyId(), ownerId, ownerType, layout.getPlid(),
712                            portletId);
713            }
714    
715            @Override
716            public PortletPreferences getStrictPortletSetup(
717                    Layout layout, String portletId) {
718    
719                    return getPortletSetup(
720                            LayoutConstants.DEFAULT_PLID, layout, portletId, StringPool.BLANK,
721                            true);
722            }
723    
724            @Override
725            public StrictPortletPreferencesImpl strictFromXML(
726                    long companyId, long ownerId, int ownerType, long plid,
727                    String portletId, String xml) {
728    
729                    Map<String, Preference> preferencesMap = toPreferencesMap(xml);
730    
731                    return new StrictPortletPreferencesImpl(
732                            companyId, ownerId, ownerType, plid, portletId, xml,
733                            preferencesMap);
734            }
735    
736            @Override
737            public String toXML(PortalPreferences portalPreferences) {
738                    PortalPreferencesImpl portalPreferencesImpl = null;
739    
740                    if (portalPreferences instanceof PortalPreferencesWrapper) {
741                            PortalPreferencesWrapper portalPreferencesWrapper =
742                                    (PortalPreferencesWrapper)portalPreferences;
743    
744                            portalPreferencesImpl =
745                                    portalPreferencesWrapper.getPortalPreferencesImpl();
746                    }
747                    else {
748                            portalPreferencesImpl = (PortalPreferencesImpl)portalPreferences;
749                    }
750    
751                    return portalPreferencesImpl.toXML();
752            }
753    
754            @Override
755            public String toXML(PortletPreferences portletPreferences) {
756                    PortletPreferencesImpl portletPreferencesImpl = null;
757    
758                    if (portletPreferences instanceof PortletPreferencesWrapper) {
759                            PortletPreferencesWrapper portletPreferencesWrapper =
760                                    (PortletPreferencesWrapper)portletPreferences;
761    
762                            portletPreferencesImpl =
763                                    portletPreferencesWrapper.getPortletPreferencesImpl();
764                    }
765                    else {
766                            portletPreferencesImpl = (PortletPreferencesImpl)portletPreferences;
767                    }
768    
769                    return portletPreferencesImpl.toXML();
770            }
771    
772            protected static Preference readPreference(XMLEventReader xmlEventReader)
773                    throws XMLStreamException {
774    
775                    String name = null;
776                    List<String> values = new ArrayList<>();
777                    boolean readOnly = false;
778    
779                    while (xmlEventReader.hasNext()) {
780                            XMLEvent xmlEvent = xmlEventReader.nextEvent();
781    
782                            if (xmlEvent.isStartElement()) {
783                                    StartElement startElement = xmlEvent.asStartElement();
784    
785                                    String elementName = startElement.getName().getLocalPart();
786    
787                                    if (elementName.equals("name")) {
788                                            name = StAXReaderUtil.read(xmlEventReader);
789                                    }
790                                    else if (elementName.equals("value")) {
791                                            String value = StAXReaderUtil.read(xmlEventReader);
792    
793                                            values.add(value);
794                                    }
795                                    else if (elementName.equals("read-only")) {
796                                            String value = StAXReaderUtil.read(xmlEventReader);
797    
798                                            readOnly = GetterUtil.getBoolean(value);
799                                    }
800                            }
801                            else if (xmlEvent.isEndElement()) {
802                                    EndElement endElement = xmlEvent.asEndElement();
803    
804                                    String elementName = endElement.getName().getLocalPart();
805    
806                                    if (elementName.equals("preference")) {
807                                            break;
808                                    }
809                            }
810                    }
811    
812                    return new Preference(
813                            name, values.toArray(new String[values.size()]), readOnly);
814            }
815    
816            protected PortletPreferences getPortletSetup(
817                    long siteGroupId, Layout layout, String portletId,
818                    String defaultPreferences, boolean strictMode) {
819    
820                    String originalPortletId = portletId;
821    
822                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
823                            layout.getCompanyId(), portletId);
824    
825                    boolean uniquePerLayout = false;
826                    boolean uniquePerGroup = false;
827    
828                    if (portlet.isPreferencesCompanyWide()) {
829                            portletId = PortletConstants.getRootPortletId(portletId);
830                    }
831                    else {
832                            if (portlet.isPreferencesUniquePerLayout()) {
833                                    uniquePerLayout = true;
834    
835                                    if (portlet.isPreferencesOwnedByGroup()) {
836                                            uniquePerGroup = true;
837                                    }
838                            }
839                            else {
840                                    if (portlet.isPreferencesOwnedByGroup()) {
841                                            uniquePerGroup = true;
842                                            portletId = PortletConstants.getRootPortletId(portletId);
843                                    }
844                            }
845                    }
846    
847                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
848                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
849                    long plid = layout.getPlid();
850    
851                    Group group = GroupLocalServiceUtil.fetchGroup(siteGroupId);
852    
853                    if ((group != null) && group.isLayout()) {
854                            plid = group.getClassPK();
855                    }
856    
857                    if (PortletConstants.hasUserId(originalPortletId)) {
858                            ownerId = PortletConstants.getUserId(originalPortletId);
859                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
860                    }
861                    else if (!uniquePerLayout) {
862                            plid = PortletKeys.PREFS_PLID_SHARED;
863    
864                            if (uniquePerGroup) {
865                                    if (siteGroupId > LayoutConstants.DEFAULT_PLID) {
866                                            ownerId = siteGroupId;
867                                    }
868                                    else {
869                                            ownerId = layout.getGroupId();
870                                    }
871    
872                                    ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
873                            }
874                            else {
875                                    ownerId = layout.getCompanyId();
876                                    ownerType = PortletKeys.PREFS_OWNER_TYPE_COMPANY;
877                            }
878                    }
879    
880                    if (strictMode) {
881                            return PortletPreferencesLocalServiceUtil.getStrictPreferences(
882                                    layout.getCompanyId(), ownerId, ownerType, plid, portletId);
883                    }
884    
885                    return PortletPreferencesLocalServiceUtil.getPreferences(
886                            layout.getCompanyId(), ownerId, ownerType, plid, portletId,
887                            defaultPreferences);
888            }
889    
890            protected Map<String, Preference> toPreferencesMap(String xml) {
891                    if (Validator.isNull(xml)) {
892                            return Collections.emptyMap();
893                    }
894    
895                    String cacheKey = _encodeCacheKey(xml);
896    
897                    Map<String, Preference> preferencesMap = _preferencesMapPortalCache.get(
898                            cacheKey);
899    
900                    if (preferencesMap != null) {
901                            return preferencesMap;
902                    }
903    
904                    preferencesMap = createPreferencesMap(xml);
905    
906                    _preferencesMapPortalCache.put(cacheKey, preferencesMap);
907    
908                    return preferencesMap;
909            }
910    
911            private String _encodeCacheKey(String xml) {
912                    if (xml.length() <=
913                                    PropsValues.PORTLET_PREFERENCES_CACHE_KEY_THRESHOLD_SIZE) {
914    
915                            return xml;
916                    }
917    
918                    CacheKeyGenerator cacheKeyGenerator =
919                            CacheKeyGeneratorUtil.getCacheKeyGenerator(
920                                    PortletPreferencesFactoryImpl.class.getName());
921    
922                    if (_log.isDebugEnabled()) {
923                            _log.debug("Cache key generator " + cacheKeyGenerator.getClass());
924                    }
925    
926                    return String.valueOf(cacheKeyGenerator.getCacheKey(xml));
927            }
928    
929            private static final Log _log = LogFactoryUtil.getLog(
930                    PortletPreferencesFactoryImpl.class);
931    
932            private final PortalCache<String, Map<String, Preference>>
933                    _preferencesMapPortalCache = SingleVMPoolUtil.getPortalCache(
934                            PortletPreferencesFactoryImpl.class.getName());
935    
936    }