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