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