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