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