001    /**
002     * Copyright (c) 2000-present 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.UnsyncStringWriter;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.model.Layout;
023    import com.liferay.portal.kernel.model.LayoutConstants;
024    import com.liferay.portal.kernel.model.Portlet;
025    import com.liferay.portal.kernel.model.PortletApp;
026    import com.liferay.portal.kernel.model.PortletURLListener;
027    import com.liferay.portal.kernel.portlet.LiferayPortletResponse;
028    import com.liferay.portal.kernel.portlet.LiferayPortletURL;
029    import com.liferay.portal.kernel.portlet.PortletPreferencesFactoryUtil;
030    import com.liferay.portal.kernel.security.xml.SecureXMLFactoryProviderUtil;
031    import com.liferay.portal.kernel.service.LayoutLocalServiceUtil;
032    import com.liferay.portal.kernel.service.PortletLocalServiceUtil;
033    import com.liferay.portal.kernel.servlet.URLEncoder;
034    import com.liferay.portal.kernel.theme.ThemeDisplay;
035    import com.liferay.portal.kernel.util.ArrayUtil;
036    import com.liferay.portal.kernel.util.GetterUtil;
037    import com.liferay.portal.kernel.util.ParamUtil;
038    import com.liferay.portal.kernel.util.PortalUtil;
039    import com.liferay.portal.kernel.util.StringUtil;
040    import com.liferay.portal.kernel.util.Validator;
041    import com.liferay.portal.kernel.util.WebKeys;
042    import com.liferay.portal.security.lang.DoPrivilegedUtil;
043    import com.liferay.portal.struts.StrutsActionPortletURL;
044    import com.liferay.portal.util.PropsValues;
045    
046    import java.io.Writer;
047    
048    import java.lang.reflect.Constructor;
049    
050    import java.security.PrivilegedAction;
051    
052    import java.util.ArrayList;
053    import java.util.LinkedHashMap;
054    import java.util.List;
055    import java.util.Map;
056    import java.util.Set;
057    import java.util.concurrent.ConcurrentHashMap;
058    
059    import javax.portlet.MimeResponse;
060    import javax.portlet.PortletException;
061    import javax.portlet.PortletModeException;
062    import javax.portlet.PortletPreferences;
063    import javax.portlet.PortletRequest;
064    import javax.portlet.PortletResponse;
065    import javax.portlet.PortletURL;
066    import javax.portlet.PortletURLGenerationListener;
067    import javax.portlet.ResourceURL;
068    import javax.portlet.WindowStateException;
069    import javax.portlet.filter.PortletResponseWrapper;
070    
071    import javax.servlet.http.Cookie;
072    import javax.servlet.http.HttpServletRequest;
073    import javax.servlet.http.HttpServletResponse;
074    
075    import javax.xml.parsers.DocumentBuilder;
076    import javax.xml.parsers.DocumentBuilderFactory;
077    import javax.xml.parsers.ParserConfigurationException;
078    import javax.xml.transform.OutputKeys;
079    import javax.xml.transform.Transformer;
080    import javax.xml.transform.TransformerFactory;
081    import javax.xml.transform.dom.DOMSource;
082    import javax.xml.transform.stream.StreamResult;
083    
084    import org.w3c.dom.DOMException;
085    import org.w3c.dom.Document;
086    import org.w3c.dom.Element;
087    
088    /**
089     * @author Brian Wing Shun Chan
090     */
091    public abstract class PortletResponseImpl implements LiferayPortletResponse {
092    
093            public static PortletResponseImpl getPortletResponseImpl(
094                    PortletResponse portletResponse) {
095    
096                    while (!(portletResponse instanceof PortletResponseImpl)) {
097                            if (portletResponse instanceof PortletResponseWrapper) {
098                                    PortletResponseWrapper portletResponseWrapper =
099                                            (PortletResponseWrapper)portletResponse;
100    
101                                    portletResponse = portletResponseWrapper.getResponse();
102                            }
103                            else {
104                                    throw new RuntimeException(
105                                            "Unable to unwrap the portlet response from " +
106                                                    portletResponse.getClass());
107                            }
108                    }
109    
110                    return (PortletResponseImpl)portletResponse;
111            }
112    
113            @Override
114            public void addDateHeader(String name, long date) {
115                    if (Validator.isNull(name)) {
116                            throw new IllegalArgumentException();
117                    }
118    
119                    Long[] values = (Long[])_headers.get(name);
120    
121                    if (values == null) {
122                            setDateHeader(name, date);
123                    }
124                    else {
125                            values = ArrayUtil.append(values, Long.valueOf(date));
126    
127                            _headers.put(name, values);
128                    }
129            }
130    
131            @Override
132            public void addHeader(String name, String value) {
133                    if (Validator.isNull(name)) {
134                            throw new IllegalArgumentException();
135                    }
136    
137                    String[] values = (String[])_headers.get(name);
138    
139                    if (values == null) {
140                            setHeader(name, value);
141                    }
142                    else {
143                            values = ArrayUtil.append(values, value);
144    
145                            _headers.put(name, values);
146                    }
147            }
148    
149            @Override
150            public void addIntHeader(String name, int value) {
151                    if (Validator.isNull(name)) {
152                            throw new IllegalArgumentException();
153                    }
154    
155                    Integer[] values = (Integer[])_headers.get(name);
156    
157                    if (values == null) {
158                            setIntHeader(name, value);
159                    }
160                    else {
161                            values = ArrayUtil.append(values, Integer.valueOf(value));
162    
163                            _headers.put(name, values);
164                    }
165            }
166    
167            @Override
168            public void addProperty(Cookie cookie) {
169                    if (cookie == null) {
170                            throw new IllegalArgumentException();
171                    }
172    
173                    Cookie[] cookies = (Cookie[])_headers.get("cookies");
174    
175                    if (cookies == null) {
176                            _headers.put("cookies", new Cookie[] {cookie});
177                    }
178                    else {
179                            cookies = ArrayUtil.append(cookies, cookie);
180    
181                            _headers.put("cookies", cookies);
182                    }
183            }
184    
185            @Override
186            public void addProperty(String key, Element element) {
187                    if (key == null) {
188                            throw new IllegalArgumentException();
189                    }
190    
191                    if (StringUtil.equalsIgnoreCase(
192                                    key, MimeResponse.MARKUP_HEAD_ELEMENT)) {
193    
194                            List<Element> values = _markupHeadElements.get(key);
195    
196                            if (values != null) {
197                                    if (element != null) {
198                                            values.add(element);
199                                    }
200                                    else {
201                                            _markupHeadElements.remove(key);
202                                    }
203                            }
204                            else {
205                                    if (element != null) {
206                                            values = new ArrayList<>();
207    
208                                            values.add(element);
209    
210                                            _markupHeadElements.put(key, values);
211                                    }
212                            }
213                    }
214            }
215    
216            @Override
217            public void addProperty(String key, String value) {
218                    if (Validator.isNull(key)) {
219                            throw new IllegalArgumentException();
220                    }
221    
222                    addHeader(key, value);
223            }
224    
225            @Override
226            public PortletURL createActionURL() {
227                    return createActionURL(_portletName);
228            }
229    
230            @Override
231            public LiferayPortletURL createActionURL(String portletName) {
232                    return createLiferayPortletURL(
233                            portletName, PortletRequest.ACTION_PHASE);
234            }
235    
236            @Override
237            public Element createElement(String tagName) throws DOMException {
238                    if (_document == null) {
239                            try {
240                                    DocumentBuilderFactory documentBuilderFactory =
241                                            SecureXMLFactoryProviderUtil.newDocumentBuilderFactory();
242    
243                                    DocumentBuilder documentBuilder =
244                                            documentBuilderFactory.newDocumentBuilder();
245    
246                                    _document = documentBuilder.newDocument();
247                            }
248                            catch (ParserConfigurationException pce) {
249                                    throw new DOMException(
250                                            DOMException.INVALID_STATE_ERR, pce.getMessage());
251                            }
252                    }
253    
254                    return _document.createElement(tagName);
255            }
256    
257            @Override
258            public LiferayPortletURL createLiferayPortletURL(
259                    long plid, String portletName, String lifecycle) {
260    
261                    return createLiferayPortletURL(plid, portletName, lifecycle, true);
262            }
263    
264            @Override
265            public LiferayPortletURL createLiferayPortletURL(
266                    long plid, String portletName, String lifecycle,
267                    boolean includeLinkToLayoutUuid) {
268    
269                    return DoPrivilegedUtil.wrap(
270                            new LiferayPortletURLPrivilegedAction(
271                                    plid, portletName, lifecycle, includeLinkToLayoutUuid));
272            }
273    
274            @Override
275            public LiferayPortletURL createLiferayPortletURL(String lifecycle) {
276                    return createLiferayPortletURL(_portletName, lifecycle);
277            }
278    
279            @Override
280            public LiferayPortletURL createLiferayPortletURL(
281                    String portletName, String lifecycle) {
282    
283                    return createLiferayPortletURL(_plid, portletName, lifecycle);
284            }
285    
286            @Override
287            public PortletURL createRenderURL() {
288                    return createRenderURL(_portletName);
289            }
290    
291            @Override
292            public LiferayPortletURL createRenderURL(String portletName) {
293                    return createLiferayPortletURL(
294                            portletName, PortletRequest.RENDER_PHASE);
295            }
296    
297            @Override
298            public ResourceURL createResourceURL() {
299                    return createResourceURL(_portletName);
300            }
301    
302            @Override
303            public LiferayPortletURL createResourceURL(String portletName) {
304                    return createLiferayPortletURL(
305                            portletName, PortletRequest.RESOURCE_PHASE);
306            }
307    
308            @Override
309            public String encodeURL(String path) {
310                    if ((path == null) ||
311                            (!path.startsWith("#") && !path.startsWith("/") &&
312                             !path.contains("://"))) {
313    
314                            // Allow '#' as well to workaround a bug in Oracle ADF 10.1.3
315    
316                            throw new IllegalArgumentException(
317                                    "URL path must start with a '/' or include '://'");
318                    }
319    
320                    if (_urlEncoder != null) {
321                            return _urlEncoder.encodeURL(_response, path);
322                    }
323                    else {
324                            return path;
325                    }
326            }
327    
328            public long getCompanyId() {
329                    return _companyId;
330            }
331    
332            public HttpServletRequest getHttpServletRequest() {
333                    return _portletRequestImpl.getHttpServletRequest();
334            }
335    
336            @Override
337            public HttpServletResponse getHttpServletResponse() {
338                    return _response;
339            }
340    
341            public abstract String getLifecycle();
342    
343            @Override
344            public String getNamespace() {
345                    if (_wsrp) {
346                            return "wsrp_rewrite_";
347                    }
348    
349                    if (_namespace == null) {
350                            _namespace = PortalUtil.getPortletNamespace(_portletName);
351                    }
352    
353                    return _namespace;
354            }
355    
356            public long getPlid() {
357                    return _plid;
358            }
359    
360            @Override
361            public Portlet getPortlet() {
362                    if (_portlet == null) {
363                            try {
364                                    _portlet = PortletLocalServiceUtil.getPortletById(
365                                            _companyId, _portletName);
366                            }
367                            catch (Exception e) {
368                                    _log.error(e);
369                            }
370                    }
371    
372                    return _portlet;
373            }
374    
375            public String getPortletName() {
376                    return _portletName;
377            }
378    
379            public PortletRequestImpl getPortletRequest() {
380                    return _portletRequestImpl;
381            }
382    
383            @Override
384            public Map<String, String[]> getProperties() {
385                    Map<String, String[]> properties = new LinkedHashMap<>();
386    
387                    for (Map.Entry<String, Object> entry : _headers.entrySet()) {
388                            String name = entry.getKey();
389                            Object[] values = (Object[])entry.getValue();
390    
391                            String[] valuesString = new String[values.length];
392    
393                            for (int i = 0; i < values.length; i++) {
394                                    valuesString[i] = values[i].toString();
395                            }
396    
397                            properties.put(name, valuesString);
398                    }
399    
400                    return properties;
401            }
402    
403            public URLEncoder getUrlEncoder() {
404                    return _urlEncoder;
405            }
406    
407            @Override
408            public void setDateHeader(String name, long date) {
409                    if (Validator.isNull(name)) {
410                            throw new IllegalArgumentException();
411                    }
412    
413                    if (date <= 0) {
414                            _headers.remove(name);
415                    }
416                    else {
417                            _headers.put(name, new Long[] {Long.valueOf(date)});
418                    }
419            }
420    
421            @Override
422            public void setHeader(String name, String value) {
423                    if (Validator.isNull(name)) {
424                            throw new IllegalArgumentException();
425                    }
426    
427                    if (Validator.isNull(value)) {
428                            _headers.remove(name);
429                    }
430                    else {
431                            _headers.put(name, new String[] {value});
432                    }
433            }
434    
435            @Override
436            public void setIntHeader(String name, int value) {
437                    if (Validator.isNull(name)) {
438                            throw new IllegalArgumentException();
439                    }
440    
441                    if (value <= 0) {
442                            _headers.remove(name);
443                    }
444                    else {
445                            _headers.put(name, new Integer[] {Integer.valueOf(value)});
446                    }
447            }
448    
449            public void setPlid(long plid) {
450                    _plid = plid;
451    
452                    if (_plid <= 0) {
453                            Layout layout = (Layout)_portletRequestImpl.getAttribute(
454                                    WebKeys.LAYOUT);
455    
456                            if (layout != null) {
457                                    _plid = layout.getPlid();
458                            }
459                    }
460            }
461    
462            @Override
463            public void setProperty(String key, String value) {
464                    if (key == null) {
465                            throw new IllegalArgumentException();
466                    }
467    
468                    setHeader(key, value);
469            }
470    
471            public void setURLEncoder(URLEncoder urlEncoder) {
472                    _urlEncoder = urlEncoder;
473            }
474    
475            public void transferHeaders(HttpServletResponse response) {
476                    for (Map.Entry<String, Object> entry : _headers.entrySet()) {
477                            String name = entry.getKey();
478                            Object values = entry.getValue();
479    
480                            if (values instanceof Integer[]) {
481                                    Integer[] intValues = (Integer[])values;
482    
483                                    for (int value : intValues) {
484                                            if (response.containsHeader(name)) {
485                                                    response.addIntHeader(name, value);
486                                            }
487                                            else {
488                                                    response.setIntHeader(name, value);
489                                            }
490                                    }
491                            }
492                            else if (values instanceof Long[]) {
493                                    Long[] dateValues = (Long[])values;
494    
495                                    for (long value : dateValues) {
496                                            if (response.containsHeader(name)) {
497                                                    response.addDateHeader(name, value);
498                                            }
499                                            else {
500                                                    response.setDateHeader(name, value);
501                                            }
502                                    }
503                            }
504                            else if (values instanceof String[]) {
505                                    String[] stringValues = (String[])values;
506    
507                                    for (String value : stringValues) {
508                                            if (response.containsHeader(name)) {
509                                                    response.addHeader(name, value);
510                                            }
511                                            else {
512                                                    response.setHeader(name, value);
513                                            }
514                                    }
515                            }
516                            else if (values instanceof Cookie[]) {
517                                    Cookie[] cookies = (Cookie[])values;
518    
519                                    for (Cookie cookie : cookies) {
520                                            response.addCookie(cookie);
521                                    }
522                            }
523                    }
524            }
525    
526            @Override
527            public void transferMarkupHeadElements() {
528                    List<Element> elements = _markupHeadElements.get(
529                            MimeResponse.MARKUP_HEAD_ELEMENT);
530    
531                    if ((elements == null) || elements.isEmpty()) {
532                            return;
533                    }
534    
535                    HttpServletRequest request = getHttpServletRequest();
536    
537                    List<String> markupHeadElements = (List<String>)request.getAttribute(
538                            MimeResponse.MARKUP_HEAD_ELEMENT);
539    
540                    if (markupHeadElements == null) {
541                            markupHeadElements = new ArrayList<>();
542    
543                            request.setAttribute(
544                                    MimeResponse.MARKUP_HEAD_ELEMENT, markupHeadElements);
545                    }
546    
547                    for (Element element : elements) {
548                            try {
549                                    Writer writer = new UnsyncStringWriter();
550    
551                                    TransformerFactory transformerFactory =
552                                            TransformerFactory.newInstance();
553    
554                                    Transformer transformer = transformerFactory.newTransformer();
555    
556                                    transformer.setOutputProperty(
557                                            OutputKeys.OMIT_XML_DECLARATION, "yes");
558    
559                                    transformer.transform(
560                                            new DOMSource(element), new StreamResult(writer));
561    
562                                    markupHeadElements.add(writer.toString());
563                            }
564                            catch (Exception e) {
565                                    if (_log.isWarnEnabled()) {
566                                            _log.warn(e, e);
567                                    }
568                            }
569                    }
570            }
571    
572            protected LiferayPortletURL doCreateLiferayPortletURL(
573                    long plid, String portletName, String lifecycle,
574                    boolean includeLinkToLayoutUuid) {
575    
576                    try {
577                            Layout layout = (Layout)_portletRequestImpl.getAttribute(
578                                    WebKeys.LAYOUT);
579    
580                            if (layout == null) {
581                                    ThemeDisplay themeDisplay =
582                                            (ThemeDisplay)_portletRequestImpl.getAttribute(
583                                                    WebKeys.THEME_DISPLAY);
584    
585                                    if (themeDisplay != null) {
586                                            layout = themeDisplay.getLayout();
587                                    }
588                            }
589    
590                            if (_portletSetup == null) {
591                                    _portletSetup =
592                                            PortletPreferencesFactoryUtil.getStrictLayoutPortletSetup(
593                                                    layout, _portletName);
594                            }
595    
596                            String linkToLayoutUuid = GetterUtil.getString(
597                                    _portletSetup.getValue("portletSetupLinkToLayoutUuid", null));
598    
599                            if (PropsValues.PORTLET_CROSS_LAYOUT_INVOCATION_MODE.equals(
600                                            "render") &&
601                                    !PortletRequest.RENDER_PHASE.equals(lifecycle)) {
602    
603                                    includeLinkToLayoutUuid = false;
604                            }
605    
606                            if (Validator.isNotNull(linkToLayoutUuid) &&
607                                    includeLinkToLayoutUuid) {
608    
609                                    try {
610                                            Layout linkedLayout =
611                                                    LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
612                                                            linkToLayoutUuid, layout.getGroupId(),
613                                                            layout.isPrivateLayout());
614    
615                                            plid = linkedLayout.getPlid();
616                                    }
617                                    catch (PortalException pe) {
618                                    }
619                            }
620                    }
621                    catch (SystemException se) {
622                            if (_log.isWarnEnabled()) {
623                                    _log.warn(se);
624                            }
625                    }
626    
627                    if (plid == LayoutConstants.DEFAULT_PLID) {
628                            plid = _plid;
629                    }
630    
631                    PortletURLImpl portletURLImpl = null;
632    
633                    Portlet portlet = getPortlet();
634    
635                    String portletURLClass = portlet.getPortletURLClass();
636    
637                    if (portlet.getPortletId().equals(portletName) &&
638                            Validator.isNotNull(portletURLClass)) {
639    
640                            if (portletURLClass.equals(
641                                            StrutsActionPortletURL.class.getName())) {
642    
643                                    portletURLImpl = new StrutsActionPortletURL(
644                                            this, plid, lifecycle);
645                            }
646                            else {
647                                    try {
648                                            Constructor<? extends PortletURLImpl> constructor =
649                                                    _constructors.get(portletURLClass);
650    
651                                            if (constructor == null) {
652                                                    Class<?> portletURLClassObj = Class.forName(
653                                                            portletURLClass);
654    
655                                                    constructor =
656                                                            (Constructor<? extends PortletURLImpl>)
657                                                                    portletURLClassObj.getConstructor(
658                                                                            new Class[] {
659                                                                                    PortletResponseImpl.class, long.class,
660                                                                                    String.class
661                                                                            });
662    
663                                                    _constructors.put(portletURLClass, constructor);
664                                            }
665    
666                                            portletURLImpl = constructor.newInstance(
667                                                    new Object[] {this, plid, lifecycle});
668                                    }
669                                    catch (Exception e) {
670                                            _log.error(e);
671                                    }
672                            }
673                    }
674    
675                    if (portletURLImpl == null) {
676                            portletURLImpl = new PortletURLImpl(
677                                    _portletRequestImpl, portletName, plid, lifecycle);
678                    }
679    
680                    PortletApp portletApp = portlet.getPortletApp();
681    
682                    Set<PortletURLListener> portletURLListeners =
683                            portletApp.getPortletURLListeners();
684    
685                    for (PortletURLListener portletURLListener : portletURLListeners) {
686                            try {
687                                    PortletURLGenerationListener portletURLGenerationListener =
688                                            PortletURLListenerFactory.create(portletURLListener);
689    
690                                    if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
691                                            portletURLGenerationListener.filterActionURL(
692                                                    portletURLImpl);
693                                    }
694                                    else if (lifecycle.equals(PortletRequest.RENDER_PHASE)) {
695                                            portletURLGenerationListener.filterRenderURL(
696                                                    portletURLImpl);
697                                    }
698                                    else if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
699                                            portletURLGenerationListener.filterResourceURL(
700                                                    portletURLImpl);
701                                    }
702                            }
703                            catch (PortletException pe) {
704                                    _log.error(pe, pe);
705                            }
706                    }
707    
708                    try {
709                            portletURLImpl.setWindowState(_portletRequestImpl.getWindowState());
710                    }
711                    catch (WindowStateException wse) {
712                            _log.error(wse.getMessage());
713                    }
714    
715                    try {
716                            portletURLImpl.setPortletMode(_portletRequestImpl.getPortletMode());
717                    }
718                    catch (PortletModeException pme) {
719                            _log.error(pme.getMessage());
720                    }
721    
722                    if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
723                            portletURLImpl.setCopyCurrentRenderParameters(true);
724                    }
725    
726                    return portletURLImpl;
727            }
728    
729            protected void init(
730                    PortletRequestImpl portletRequestImpl, HttpServletResponse response,
731                    String portletName, long companyId, long plid) {
732    
733                    _portletRequestImpl = portletRequestImpl;
734                    _response = response;
735                    _portletName = portletName;
736                    _companyId = companyId;
737                    _wsrp = ParamUtil.getBoolean(getHttpServletRequest(), "wsrp");
738    
739                    setPlid(plid);
740            }
741    
742            private static final Log _log = LogFactoryUtil.getLog(
743                    PortletResponseImpl.class);
744    
745            private long _companyId;
746            private final Map<String, Constructor<? extends PortletURLImpl>>
747                    _constructors = new ConcurrentHashMap<>();
748            private Document _document;
749            private final Map<String, Object> _headers = new LinkedHashMap<>();
750            private final Map<String, List<Element>> _markupHeadElements =
751                    new LinkedHashMap<>();
752            private String _namespace;
753            private long _plid;
754            private Portlet _portlet;
755            private String _portletName;
756            private PortletRequestImpl _portletRequestImpl;
757            private PortletPreferences _portletSetup;
758            private HttpServletResponse _response;
759            private URLEncoder _urlEncoder;
760            private boolean _wsrp;
761    
762            private class LiferayPortletURLPrivilegedAction
763                    implements PrivilegedAction<LiferayPortletURL> {
764    
765                    public LiferayPortletURLPrivilegedAction(
766                            long plid, String portletName, String lifecycle,
767                            boolean includeLinkToLayoutUuid) {
768    
769                            _plid = plid;
770                            _portletName = portletName;
771                            _lifecycle = lifecycle;
772                            _includeLinkToLayoutUuid = includeLinkToLayoutUuid;
773                    }
774    
775                    @Override
776                    public LiferayPortletURL run() {
777                            return doCreateLiferayPortletURL(
778                                    _plid, _portletName, _lifecycle, _includeLinkToLayoutUuid);
779                    }
780    
781                    private final boolean _includeLinkToLayoutUuid;
782                    private final String _lifecycle;
783                    private long _plid;
784                    private String _portletName;
785    
786            }
787    
788    }