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.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
020    import com.liferay.portal.kernel.portlet.LiferayPortletMode;
021    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.JavaConstants;
024    import com.liferay.portal.kernel.util.ParamUtil;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.Validator;
027    import com.liferay.portal.model.Group;
028    import com.liferay.portal.model.Layout;
029    import com.liferay.portal.model.LayoutConstants;
030    import com.liferay.portal.model.LayoutTypePortlet;
031    import com.liferay.portal.model.Portlet;
032    import com.liferay.portal.model.PortletConstants;
033    import com.liferay.portal.model.PortletPreferencesIds;
034    import com.liferay.portal.security.auth.PrincipalException;
035    import com.liferay.portal.security.permission.ActionKeys;
036    import com.liferay.portal.security.permission.PermissionChecker;
037    import com.liferay.portal.security.permission.PermissionThreadLocal;
038    import com.liferay.portal.service.GroupLocalServiceUtil;
039    import com.liferay.portal.service.PortalPreferencesLocalServiceUtil;
040    import com.liferay.portal.service.PortletLocalServiceUtil;
041    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
042    import com.liferay.portal.service.UserLocalServiceUtil;
043    import com.liferay.portal.service.permission.LayoutPermissionUtil;
044    import com.liferay.portal.theme.ThemeDisplay;
045    import com.liferay.portal.util.PortalUtil;
046    import com.liferay.portal.util.PortletKeys;
047    import com.liferay.portal.util.WebKeys;
048    import com.liferay.portal.xml.StAXReaderUtil;
049    
050    import java.util.ArrayList;
051    import java.util.HashMap;
052    import java.util.List;
053    import java.util.Map;
054    
055    import javax.portlet.PortletPreferences;
056    import javax.portlet.PortletRequest;
057    import javax.portlet.PreferencesValidator;
058    
059    import javax.servlet.http.HttpServletRequest;
060    import javax.servlet.http.HttpSession;
061    
062    import javax.xml.stream.XMLEventReader;
063    import javax.xml.stream.XMLInputFactory;
064    import javax.xml.stream.XMLStreamException;
065    import javax.xml.stream.events.EndElement;
066    import javax.xml.stream.events.StartElement;
067    import javax.xml.stream.events.XMLEvent;
068    
069    /**
070     * @author Brian Wing Shun Chan
071     * @author Alexander Chow
072     * @author Minhchau Dang
073     * @author Raymond Augé
074     */
075    @DoPrivileged
076    public class PortletPreferencesFactoryImpl
077            implements PortletPreferencesFactory {
078    
079            public PortletPreferences fromDefaultXML(String xml)
080                    throws SystemException {
081    
082                    Map<String, Preference> preferencesMap =
083                            new HashMap<String, Preference>();
084    
085                    populateMap(xml, preferencesMap);
086    
087                    return new PortletPreferencesImpl(xml, preferencesMap);
088            }
089    
090            public PortletPreferencesImpl fromXML(
091                            long companyId, long ownerId, int ownerType, long plid,
092                            String portletId, String xml)
093                    throws SystemException {
094    
095                    try {
096                            Map<String, Preference> preferencesMap =
097                                    new HashMap<String, Preference>();
098    
099                            populateMap(xml, preferencesMap);
100    
101                            return new PortletPreferencesImpl(
102                                    companyId, ownerId, ownerType, plid, portletId, xml,
103                                    preferencesMap);
104                    }
105                    catch (SystemException se) {
106                            throw se;
107                    }
108            }
109    
110            public PortalPreferencesImpl fromXML(
111                            long companyId, long ownerId, int ownerType, String xml)
112                    throws SystemException {
113    
114                    try {
115                            Map<String, Preference> preferencesMap =
116                                    new HashMap<String, Preference>();
117    
118                            populateMap(xml, preferencesMap);
119    
120                            return new PortalPreferencesImpl(
121                                    companyId, ownerId, ownerType, xml, preferencesMap, false);
122                    }
123                    catch (SystemException se) {
124                            throw se;
125                    }
126            }
127    
128            public PortletPreferences getLayoutPortletSetup(
129                            Layout layout, String portletId)
130                    throws SystemException {
131    
132                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
133                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
134    
135                    if (PortletConstants.hasUserId(portletId)) {
136                            ownerId = PortletConstants.getUserId(portletId);
137                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
138                    }
139    
140                    return PortletPreferencesLocalServiceUtil.getPreferences(
141                            layout.getCompanyId(), ownerId, ownerType, layout.getPlid(),
142                            portletId);
143            }
144    
145            public PortalPreferences getPortalPreferences(HttpServletRequest request)
146                    throws SystemException {
147    
148                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
149                            WebKeys.THEME_DISPLAY);
150    
151                    return getPortalPreferences(
152                            request.getSession(), themeDisplay.getCompanyId(),
153                            themeDisplay.getUserId(), themeDisplay.isSignedIn());
154            }
155    
156            public PortalPreferences getPortalPreferences(
157                            HttpSession session, long companyId, long userId, boolean signedIn)
158                    throws SystemException {
159    
160                    long ownerId = userId;
161                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
162    
163                    PortalPreferences portalPreferences = null;
164    
165                    if (signedIn) {
166                            PortalPreferencesWrapper portalPreferencesWrapper =
167                                    (PortalPreferencesWrapper)
168                                            PortalPreferencesLocalServiceUtil.getPreferences(
169                                                    companyId, ownerId, ownerType);
170    
171                            portalPreferences =
172                                    portalPreferencesWrapper.getPortalPreferencesImpl();
173                    }
174                    else {
175                            if (session != null) {
176                                    portalPreferences = (PortalPreferences)session.getAttribute(
177                                            WebKeys.PORTAL_PREFERENCES);
178                            }
179    
180                            if (portalPreferences == null) {
181                                    PortalPreferencesWrapper portalPreferencesWrapper =
182                                            (PortalPreferencesWrapper)
183                                                    PortalPreferencesLocalServiceUtil.getPreferences(
184                                                            companyId, ownerId, ownerType);
185    
186                                    PortalPreferencesImpl portalPreferencesImpl =
187                                            portalPreferencesWrapper.getPortalPreferencesImpl();
188    
189                                    portalPreferences =
190                                            (PortalPreferences)portalPreferencesImpl.clone();
191    
192                                    if (session != null) {
193                                            session.setAttribute(
194                                                    WebKeys.PORTAL_PREFERENCES, portalPreferences);
195                                    }
196                            }
197                    }
198    
199                    portalPreferences.setSignedIn(signedIn);
200                    portalPreferences.setUserId(userId);
201    
202                    return portalPreferences;
203            }
204    
205            public PortalPreferences getPortalPreferences(
206                            long companyId, long userId, boolean signedIn)
207                    throws SystemException {
208    
209                    return getPortalPreferences(null, companyId, userId, signedIn);
210            }
211    
212            public PortalPreferences getPortalPreferences(PortletRequest portletRequest)
213                    throws SystemException {
214    
215                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
216                            portletRequest);
217    
218                    return getPortalPreferences(request);
219            }
220    
221            public PortletPreferences getPortletPreferences(
222                            HttpServletRequest request, String portletId)
223                    throws PortalException, SystemException {
224    
225                    PortletPreferencesIds portletPreferencesIds = getPortletPreferencesIds(
226                            request, portletId);
227    
228                    return PortletPreferencesLocalServiceUtil.getPreferences(
229                            portletPreferencesIds);
230            }
231    
232            public PortletPreferencesIds getPortletPreferencesIds(
233                            HttpServletRequest request, Layout layout, String portletId)
234                    throws PortalException, SystemException {
235    
236                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
237                            WebKeys.THEME_DISPLAY);
238    
239                    long scopeGroupId = PortalUtil.getScopeGroupId(
240                            request, portletId, true);
241                    long userId = PortalUtil.getUserId(request);
242                    LayoutTypePortlet layoutTypePortlet =
243                            themeDisplay.getLayoutTypePortlet();
244    
245                    boolean modeEditGuest = false;
246    
247                    String portletMode = ParamUtil.getString(request, "p_p_mode");
248    
249                    if (portletMode.equals(LiferayPortletMode.EDIT_GUEST.toString()) ||
250                            ((layoutTypePortlet != null) &&
251                             layoutTypePortlet.hasModeEditGuestPortletId(portletId))) {
252    
253                            modeEditGuest = true;
254                    }
255    
256                    return getPortletPreferencesIds(
257                            scopeGroupId, userId, layout, portletId, modeEditGuest);
258            }
259    
260            public PortletPreferencesIds getPortletPreferencesIds(
261                            HttpServletRequest request, String portletId)
262                    throws PortalException, SystemException {
263    
264                    Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
265    
266                    return getPortletPreferencesIds(request, layout, portletId);
267            }
268    
269            public PortletPreferencesIds getPortletPreferencesIds(
270                            long scopeGroupId, long userId, Layout layout, String portletId,
271                            boolean modeEditGuest)
272                    throws PortalException, SystemException {
273    
274                    PermissionChecker permissionChecker =
275                            PermissionThreadLocal.getPermissionChecker();
276    
277                    String originalPortletId = portletId;
278    
279                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
280                            layout.getCompanyId(), portletId);
281    
282                    long ownerId = 0;
283                    int ownerType = 0;
284                    long plid = 0;
285    
286                    if (modeEditGuest) {
287                            boolean hasUpdateLayoutPermission = LayoutPermissionUtil.contains(
288                                    permissionChecker, layout, ActionKeys.UPDATE);
289    
290                            if (!layout.isPrivateLayout() && hasUpdateLayoutPermission) {
291                            }
292                            else {
293    
294                                    // Only users with the correct permissions can update guest
295                                    // preferences
296    
297                                    throw new PrincipalException();
298                            }
299                    }
300    
301                    if (PortletConstants.hasUserId(originalPortletId) &&
302                            (PortletConstants.getUserId(originalPortletId) == userId)) {
303    
304                            ownerId = userId;
305                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
306                            plid = layout.getPlid();
307                    }
308                    else if (portlet.isPreferencesCompanyWide()) {
309                            ownerId = layout.getCompanyId();
310                            ownerType = PortletKeys.PREFS_OWNER_TYPE_COMPANY;
311                            plid = PortletKeys.PREFS_PLID_SHARED;
312                            portletId = PortletConstants.getRootPortletId(portletId);
313                    }
314                    else {
315                            if (portlet.isPreferencesUniquePerLayout()) {
316                                    ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
317                                    ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
318                                    plid = layout.getPlid();
319    
320                                    if (portlet.isPreferencesOwnedByGroup()) {
321                                    }
322                                    else {
323                                            if ((userId <= 0) || modeEditGuest) {
324                                                    userId = UserLocalServiceUtil.getDefaultUserId(
325                                                            layout.getCompanyId());
326                                            }
327    
328                                            ownerId = userId;
329                                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
330                                    }
331                            }
332                            else {
333                                    plid = PortletKeys.PREFS_PLID_SHARED;
334    
335                                    if (portlet.isPreferencesOwnedByGroup()) {
336                                            ownerId = scopeGroupId;
337                                            ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
338                                            portletId = PortletConstants.getRootPortletId(portletId);
339                                    }
340                                    else {
341                                            if ((userId <= 0) || modeEditGuest) {
342                                                    userId = UserLocalServiceUtil.getDefaultUserId(
343                                                            layout.getCompanyId());
344                                            }
345    
346                                            ownerId = userId;
347                                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
348                                    }
349                            }
350                    }
351    
352                    return new PortletPreferencesIds(
353                            layout.getCompanyId(), ownerId, ownerType, plid, portletId);
354            }
355    
356            public PortletPreferences getPortletSetup(
357                            HttpServletRequest request, String portletId)
358                    throws PortalException, SystemException {
359    
360                    return getPortletSetup(request, portletId, null);
361            }
362    
363            public PortletPreferences getPortletSetup(
364                            HttpServletRequest request, String portletId,
365                            String defaultPreferences)
366                    throws PortalException, SystemException {
367    
368                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
369                            WebKeys.THEME_DISPLAY);
370    
371                    long scopeGroupId = PortalUtil.getScopeGroupId(
372                            request, portletId, true);
373    
374                    return getPortletSetup(
375                            scopeGroupId, themeDisplay.getLayout(), portletId,
376                            defaultPreferences);
377            }
378    
379            public PortletPreferences getPortletSetup(
380                            Layout layout, String portletId, String defaultPreferences)
381                    throws SystemException {
382    
383                    return getPortletSetup(
384                            LayoutConstants.DEFAULT_PLID, layout, portletId,
385                            defaultPreferences);
386            }
387    
388            public PortletPreferences getPortletSetup(
389                            long scopeGroupId, Layout layout, String portletId,
390                            String defaultPreferences)
391                    throws SystemException {
392    
393                    return getPortletSetup(
394                            scopeGroupId, layout, portletId, defaultPreferences, false);
395            }
396    
397            public PortletPreferences getPortletSetup(PortletRequest portletRequest)
398                    throws PortalException, SystemException {
399    
400                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
401                            portletRequest);
402                    String portletId = PortalUtil.getPortletId(portletRequest);
403    
404                    return getPortletSetup(request, portletId);
405            }
406    
407            public PortletPreferences getPortletSetup(
408                            PortletRequest portletRequest, String portletId)
409                    throws PortalException, SystemException {
410    
411                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
412                            portletRequest);
413    
414                    return getPortletSetup(request, portletId);
415            }
416    
417            public Map<Long, PortletPreferences> getPortletSetupMap(
418                            long companyId, long groupId, long ownerId, int ownerType,
419                            String portletId, boolean privateLayout)
420                    throws SystemException {
421    
422                    Map<Long, PortletPreferences> portletSetupMap =
423                            new HashMap<Long, PortletPreferences>();
424    
425                    List<com.liferay.portal.model.PortletPreferences>
426                            portletPreferencesList =
427                                    PortletPreferencesLocalServiceUtil.getPortletPreferences(
428                                            companyId, groupId, ownerId, ownerType, portletId,
429                                            privateLayout);
430    
431                    for (com.liferay.portal.model.PortletPreferences portletPreferences :
432                                    portletPreferencesList) {
433    
434                            PortletPreferences portletSetup =
435                                    PortletPreferencesLocalServiceUtil.getPreferences(
436                                            companyId, ownerId, ownerType, portletPreferences.getPlid(),
437                                            portletId);
438    
439                            portletSetupMap.put(portletPreferences.getPlid(), portletSetup);
440                    }
441    
442                    return portletSetupMap;
443            }
444    
445            public PortletPreferences getPreferences(HttpServletRequest request) {
446                    PortletRequest portletRequest = (PortletRequest)request.getAttribute(
447                            JavaConstants.JAVAX_PORTLET_REQUEST);
448    
449                    PortletPreferences portletPreferences = null;
450    
451                    if (portletRequest != null) {
452                            PortletPreferencesWrapper portletPreferencesWrapper =
453                                    (PortletPreferencesWrapper)portletRequest.getPreferences();
454    
455                            portletPreferences =
456                                    portletPreferencesWrapper.getPortletPreferencesImpl();
457                    }
458    
459                    return portletPreferences;
460            }
461    
462            public PreferencesValidator getPreferencesValidator(Portlet portlet) {
463                    return PortalUtil.getPreferencesValidator(portlet);
464            }
465    
466            public PortletPreferences getStrictLayoutPortletSetup(
467                            Layout layout, String portletId)
468                    throws SystemException {
469    
470                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
471                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
472    
473                    if (PortletConstants.hasUserId(portletId)) {
474                            ownerId = PortletConstants.getUserId(portletId);
475                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
476                    }
477    
478                    return PortletPreferencesLocalServiceUtil.getStrictPreferences(
479                            layout.getCompanyId(), ownerId, ownerType, layout.getPlid(),
480                            portletId);
481            }
482    
483            public PortletPreferences getStrictPortletSetup(
484                            Layout layout, String portletId)
485                    throws SystemException {
486    
487                    return getPortletSetup(
488                            LayoutConstants.DEFAULT_PLID, layout, portletId, StringPool.BLANK,
489                            true);
490            }
491    
492            public String toXML(PortalPreferences portalPreferences) {
493                    PortalPreferencesImpl portalPreferencesImpl =
494                            (PortalPreferencesImpl)portalPreferences;
495    
496                    return portalPreferencesImpl.toXML();
497            }
498    
499            public String toXML(PortletPreferences portletPreferences) {
500                    PortletPreferencesImpl portletPreferencesImpl =
501                            (PortletPreferencesImpl)portletPreferences;
502    
503                    return portletPreferencesImpl.toXML();
504            }
505    
506            protected PortletPreferences getPortletSetup(
507                            long scopeGroupId, Layout layout, String portletId,
508                            String defaultPreferences, boolean strictMode)
509                    throws SystemException {
510    
511                    String originalPortletId = portletId;
512    
513                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
514                            layout.getCompanyId(), portletId);
515    
516                    boolean uniquePerLayout = false;
517                    boolean uniquePerGroup = false;
518    
519                    if (portlet.isPreferencesCompanyWide()) {
520                            portletId = PortletConstants.getRootPortletId(portletId);
521                    }
522                    else {
523                            if (portlet.isPreferencesUniquePerLayout()) {
524                                    uniquePerLayout = true;
525    
526                                    if (portlet.isPreferencesOwnedByGroup()) {
527                                            uniquePerGroup = true;
528                                    }
529                            }
530                            else {
531                                    if (portlet.isPreferencesOwnedByGroup()) {
532                                            uniquePerGroup = true;
533                                            portletId = PortletConstants.getRootPortletId(portletId);
534                                    }
535                            }
536                    }
537    
538                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
539                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
540                    long plid = layout.getPlid();
541    
542                    Group group = GroupLocalServiceUtil.fetchGroup(scopeGroupId);
543    
544                    if ((group != null) && group.isLayout()) {
545                            plid = group.getClassPK();
546                    }
547    
548                    if (PortletConstants.hasUserId(originalPortletId)) {
549                            ownerId = PortletConstants.getUserId(originalPortletId);
550                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
551                    }
552                    else if (!uniquePerLayout) {
553                            plid = PortletKeys.PREFS_PLID_SHARED;
554    
555                            if (uniquePerGroup) {
556                                    if (scopeGroupId > LayoutConstants.DEFAULT_PLID) {
557                                            ownerId = scopeGroupId;
558                                    }
559                                    else {
560                                            ownerId = layout.getGroupId();
561                                    }
562    
563                                    ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
564                            }
565                            else {
566                                    ownerId = layout.getCompanyId();
567                                    ownerType = PortletKeys.PREFS_OWNER_TYPE_COMPANY;
568                            }
569                    }
570    
571                    if (strictMode) {
572                            return PortletPreferencesLocalServiceUtil.getStrictPreferences(
573                                    layout.getCompanyId(), ownerId, ownerType, plid, portletId);
574                    }
575    
576                    return PortletPreferencesLocalServiceUtil.getPreferences(
577                            layout.getCompanyId(), ownerId, ownerType, plid, portletId,
578                            defaultPreferences);
579            }
580    
581            protected void populateMap(
582                            String xml, Map<String, Preference> preferencesMap)
583                    throws SystemException {
584    
585                    if (Validator.isNull(xml)) {
586                            return;
587                    }
588    
589                    XMLEventReader xmlEventReader = null;
590    
591                    try {
592                            XMLInputFactory xmlInputFactory =
593                                    StAXReaderUtil.getXMLInputFactory();
594    
595                            xmlEventReader = xmlInputFactory.createXMLEventReader(
596                                    new UnsyncStringReader(xml));
597    
598                            while (xmlEventReader.hasNext()) {
599                                    XMLEvent xmlEvent = xmlEventReader.nextEvent();
600    
601                                    if (xmlEvent.isStartElement()) {
602                                            StartElement startElement = xmlEvent.asStartElement();
603    
604                                            String elementName = startElement.getName().getLocalPart();
605    
606                                            if (elementName.equals("preference")) {
607                                                    Preference preference = readPreference(xmlEventReader);
608    
609                                                    preferencesMap.put(preference.getName(), preference);
610                                            }
611                                    }
612                            }
613                    }
614                    catch (XMLStreamException xse) {
615                            throw new SystemException(xse);
616                    }
617                    finally {
618                            if (xmlEventReader != null) {
619                                    try {
620                                            xmlEventReader.close();
621                                    }
622                                    catch (XMLStreamException xse) {
623                                    }
624                            }
625                    }
626            }
627    
628            protected Preference readPreference(XMLEventReader xmlEventReader)
629                    throws XMLStreamException {
630    
631                    String name = null;
632                    List<String> values = new ArrayList<String>();
633                    boolean readOnly = false;
634    
635                    while (xmlEventReader.hasNext()) {
636                            XMLEvent xmlEvent = xmlEventReader.nextEvent();
637    
638                            if (xmlEvent.isStartElement()) {
639                                    StartElement startElement = xmlEvent.asStartElement();
640    
641                                    String elementName = startElement.getName().getLocalPart();
642    
643                                    if (elementName.equals("name")) {
644                                            name = StAXReaderUtil.read(xmlEventReader);
645                                    }
646                                    else if (elementName.equals("value")) {
647                                            String value = StAXReaderUtil.read(xmlEventReader);
648    
649                                            values.add(value);
650                                    }
651                                    else if (elementName.equals("read-only")) {
652                                            String value = StAXReaderUtil.read(xmlEventReader);
653    
654                                            readOnly = GetterUtil.getBoolean(value);
655                                    }
656                            }
657                            else if (xmlEvent.isEndElement()) {
658                                    EndElement endElement = xmlEvent.asEndElement();
659    
660                                    String elementName = endElement.getName().getLocalPart();
661    
662                                    if (elementName.equals("preference")) {
663                                            break;
664                                    }
665                            }
666                    }
667    
668                    return new Preference(
669                            name, values.toArray(new String[values.size()]), readOnly);
670            }
671    
672    }