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