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