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