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