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