public WebConfig scan() throws IOException {

    // Parse the Servlet 3.0 META-INF/web-fragment.xml descriptor files found in the classpath.
    Enumeration<URL> webFragmentURLs = classLoader.getResources(WEB_FRAGMENT_META_INF_PATH);

    WebConfig webConfig = new WebConfigImpl();

    InputStream inputStream = null;

    if (webFragmentURLs != null) {

      while (webFragmentURLs.hasMoreElements()) {
        URL webFragmentURL = webFragmentURLs.nextElement();
        inputStream = webFragmentURL.openStream();

        WebConfigParser webConfigParser = newWebConfigParser();

        try {
          webConfig = webConfigParser.parse(inputStream, webConfig);
          inputStream.close();
        } catch (Exception e) {
          logger.error(e.getMessage());
        }
      }
    }

    // Parse the WEB-INF/web.xml descriptor.
    inputStream = resourceReader.getResourceAsStream(WEB_XML_PATH);

    if (inputStream != null) {
      logger.debug("Processing web-app: [{0}]", WEB_XML_PATH);

      WebConfigParser webConfigParser = newWebConfigParser();

      try {
        webConfig = webConfigParser.parse(inputStream, webConfig);
      } catch (IOException e) {
        logger.error(e);
        throw new IOException(e.getMessage());
      }
    }

    // Parse the WEB-INF/liferay-web.xml descriptor.
    inputStream = resourceReader.getResourceAsStream(WEB_XML_LIFERAY_PATH);

    if (inputStream != null) {
      logger.debug("Processing web-app: [{0}]", WEB_XML_LIFERAY_PATH);

      WebConfigParser webConfigParser = newWebConfigParser();

      try {
        webConfigParser.parse(inputStream, webConfig);
      } catch (IOException e) {
        logger.error(e);
        throw new IOException(e.getMessage());
      }
    }

    return webConfig;
  }
  public void handleFileUpload(FileUploadEvent fileUploadEvent) {

    List<UploadedFile> uploadedFiles = bridgeInputFileModelBean.getUploadedFiles();
    UploadedFile uploadedFile = fileUploadEvent.getUploadedFile();

    if (uploadedFile.getStatus() == UploadedFile.Status.FILE_SAVED) {

      FacesContext facesContext = FacesContext.getCurrentInstance();
      FacesMessage facesMessage =
          new FacesMessage(
              "Received fileUploadEvent for file named '"
                  + uploadedFile.getName()
                  + "' in the "
                  + fileUploadEvent.getPhaseId().toString()
                  + " phase.");
      facesContext.addMessage(null, facesMessage);
      uploadedFiles.add(uploadedFile);
      logger.debug(
          "Received fileName=[{0}] absolutePath=[{1}]",
          uploadedFile.getName(), uploadedFile.getAbsolutePath());
    } else {
      logger.error(
          "Failed to receive uploaded file due to error status=[{0}] message=[{1}]",
          uploadedFile.getStatus(), uploadedFile.getMessage());
    }
  }
  static {

    // Set the value of the LIFERAY_ATTRIBUTE_NAMES constant. Need to use reflection in order to
    // determine all of
    // the public constants because different versions of the portal source have different sets of
    // constants. This
    // approach minimizes diffs in the different source branches for the bridge.
    List<String> fieldList = new ArrayList<String>();
    Field[] fields = JavaConstants.class.getFields();

    for (Field field : fields) {

      String fieldName = field.getName();

      if ((fieldName != null) && fieldName.startsWith("JAVAX")) {

        try {
          Object value = field.get(null);

          if ((value != null) && (value instanceof String)) {
            fieldList.add((String) value);
          }
        } catch (Exception e) {
          logger.error(e);
        }
      }
    }

    LIFERAY_ATTRIBUTE_NAMES = fieldList.toArray(new String[fieldList.size()]);
  }
  public void deleteUploadedFile(ActionEvent actionEvent) {

    UICommand uiCommand = (UICommand) actionEvent.getComponent();
    String fileId = (String) uiCommand.getValue();

    try {
      List<UploadedFile> uploadedFiles = htmlInputFileModelBean.getUploadedFiles();

      UploadedFile uploadedFileToDelete = null;

      for (UploadedFile uploadedFile : uploadedFiles) {

        if (uploadedFile.getId().equals(fileId)) {
          uploadedFileToDelete = uploadedFile;

          break;
        }
      }

      if (uploadedFileToDelete != null) {
        uploadedFileToDelete.delete();
        uploadedFiles.remove(uploadedFileToDelete);
        logger.debug("Deleted file=[{0}]", uploadedFileToDelete.getName());
      }
    } catch (Exception e) {
      logger.error(e);
    }
  }
  public void deleteUploadedFile(ActionEvent actionEvent) {

    try {
      List<UploadedFile> uploadedFiles = applicantModelBean.getUploadedFiles();

      String uploadedFileId = applicantViewBean.getUploadedFileId();

      UploadedFile uploadedFileToDelete = null;

      for (UploadedFile uploadedFile : uploadedFiles) {

        if (uploadedFile.getId().equals(uploadedFileId)) {
          uploadedFileToDelete = uploadedFile;

          break;
        }
      }

      if (uploadedFileToDelete != null) {
        uploadedFileToDelete.delete();
        uploadedFiles.remove(uploadedFileToDelete);
        logger.debug("Deleted file=[{0}]", uploadedFileToDelete.getName());
      }
    } catch (Exception e) {
      logger.error(e);
    }
  }
  @Override
  public void setAttribute(String name, Object value) {

    Object wrappedRequest = getRequest();

    if (wrappedRequest.getClass().getName().equals(NAMESPACE_SERVLET_REQUEST_FQCN)) {

      try {

        // Calling NameSpaceServletRequest.setAttribute(String, Object, false) instead of
        // NameSpaceServletRequest.setAttribute(String, Object) will prevent the attribute name from
        // getting
        // prefixed with the response namespace. The method must be called reflectively since the
        // NameSpaceServletRequest is packaged in portal-impl.jar and is not available at
        // compile-time.
        Method method =
            wrappedRequest
                .getClass()
                .getMethod("setAttribute", String.class, Object.class, boolean.class);
        method.invoke(wrappedRequest, name, value, false);
      } catch (Exception e) {
        logger.error(e);
      }
    } else {
      super.setAttribute(name, value);
    }
  }
  public void deleteUploadedFile(ActionEvent actionEvent) {

    String fileId =
        (String)
            FacesContext.getCurrentInstance()
                .getExternalContext()
                .getRequestParameterMap()
                .get("fileId");

    try {
      List<UploadedFile> uploadedFiles = applicantModelBean.getUploadedFiles();

      UploadedFile uploadedFileToDelete = null;

      for (UploadedFile uploadedFile : uploadedFiles) {

        if (uploadedFile.getId().equals(fileId)) {
          uploadedFileToDelete = uploadedFile;

          break;
        }
      }

      if (uploadedFileToDelete != null) {
        File file = new File(uploadedFileToDelete.getAbsolutePath());
        file.delete();
        uploadedFiles.remove(uploadedFileToDelete);
        logger.debug("Deleted file=[{0}]", file);
      }
    } catch (Exception e) {
      logger.error(e);
    }
  }
  @Override
  public String getRequestCharacterEncoding() {

    if (portletRequest instanceof ClientDataRequest) {
      ClientDataRequest clientDataRequest = (ClientDataRequest) portletRequest;
      String requestCharacterEncoding = clientDataRequest.getCharacterEncoding();

      if (manageIncongruities) {

        try {
          incongruityContext.setRequestCharacterEncoding(requestCharacterEncoding);
        } catch (Exception e) {
          logger.error(e);
        }
      }

      return requestCharacterEncoding;
    } else {

      if (manageIncongruities) {
        return incongruityContext.getRequestCharacterEncoding();
      } else {

        // The Mojarra 2.x {@link MultiViewHandler#initView(FacesContext)} method expects a null
        // value to be
        // returned, so throwing an IllegalStateException is not an option.
        return null;
      }
    }
  }
  /** Returns the implementation singleton instance. */
  public static LiferayFacesContext getInstance() {

    if (instance == null) {
      logger.error("Instance not initialized -- caller might be static");
    }

    return instance;
  }
Exemple #10
0
  public static byte[] XHTML2PDF(String xhtml) throws IOException {
    byte[] pdf = null;
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

    try {
      ITextRenderer itextRenderer = new ITextRenderer();
      itextRenderer.setDocumentFromString(xhtml);
      itextRenderer.layout();
      itextRenderer.createPDF(byteArrayOutputStream);
      pdf = byteArrayOutputStream.toByteArray();
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      logger.error("vvv--- Offending XHTML ---vvv");
      logger.error(xhtml);
      throw new IOException(e.getMessage());
    }

    return pdf;
  }
  /**
   * This method is called after an attribute is added to the ServletRequest. Note that this should
   * only get called for remote WSRP portlets. For more info, see:
   * http://issues.liferay.com/browse/FACES-146
   */
  public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {

    // NOTE: We only care about phases prior to the RENDER_PHASE because we're concerned here about
    // managed beans
    // that get added to the request scope when the BridgeRequestScope begins. We're trying to
    // provide those managed
    // beans with an opportunity to prepare for an unexpected invocation of their methods annotated
    // with
    // @PreDestroy.
    ServletRequest servletRequest = servletRequestAttributeEvent.getServletRequest();
    PortletPhase phase = (PortletPhase) servletRequest.getAttribute(Bridge.PORTLET_LIFECYCLE_PHASE);

    // If this is taking place within a PortletRequest handled by the bridge in any phase prior to
    // the
    // RENDER_PHASE, then
    if ((phase != null) && (phase != PortletPhase.RENDER_PHASE)) {

      // If the attribute being added is not excluded, then invoke all methods on the attribute
      // value (class
      // instance) that are annotated with the BridgeRequestScopeAttributeAdded annotation.
      String attributeName = servletRequestAttributeEvent.getName();
      BridgeContext bridgeContext = BridgeContext.getCurrentInstance();
      BridgeConfig bridgeConfig = bridgeContext.getBridgeConfig();
      Set<String> excludedRequestScopeAttributes = bridgeConfig.getExcludedRequestAttributes();

      if (!excludedRequestScopeAttributes.contains(attributeName)) {

        Object attributeValue = servletRequestAttributeEvent.getValue();
        logger.trace("Attribute added name=[{0}] value=[{1}]", attributeName, attributeValue);

        if (attributeValue != null) {
          Method[] methods = attributeValue.getClass().getMethods();

          if (methods != null) {

            for (Method method : methods) {

              if (method != null) {

                if (method.isAnnotationPresent(BridgeRequestScopeAttributeAdded.class)) {

                  try {
                    method.invoke(attributeValue, new Object[] {});
                  } catch (Exception e) {
                    logger.error(e);
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  @Override
  public void setRequest(Object request) {
    this.portletRequest = (PortletRequest) request;

    try {
      boolean requestChanged = true;
      boolean responseChanged = false;
      preInitializeObjects(requestChanged, responseChanged);
    } catch (Exception e) {
      logger.error(e);
    }
  }
  public PreDestroyInvokerMojarraImpl(Map<String, Object> applicationMap) {

    this.mojarraInjectionProvider = getInjectionProvider(applicationMap);

    try {
      this.invokePreDestroyMethod =
          mojarraInjectionProvider
              .getClass()
              .getMethod(INVOKE_PRE_DESTROY, new Class[] {Object.class});
    } catch (Exception e) {
      logger.error(e);
    }
  }
  @Override
  public void encodeJavaScriptCustom(FacesContext facesContext, UIComponent uiComponent)
      throws IOException {

    ResponseWriter responseWriter = facesContext.getResponseWriter();

    Popover popover = (Popover) uiComponent;
    ClientComponent clientComponent = (ClientComponent) uiComponent;
    String clientVarName = getClientVarName(facesContext, clientComponent);
    String clientKey = clientComponent.getClientKey();

    if (clientKey == null) {
      clientKey = clientVarName;
    }

    if (popover.isHideIconRendered()) {

      // Add an "x" toolbar icon so that the popover can be hidden just like alloy:dialog can.
      responseWriter.write(LIFERAY_COMPONENT);
      responseWriter.write("('");
      responseWriter.write(clientKey);
      responseWriter.write(
          "').addToolbar([{cssClass:'close',label:'\u00D7',on:{click:function(event){Liferay.component('");
      responseWriter.write(clientKey);
      responseWriter.write("').hide();}},render:true}],'header');");
    }

    // Move the overlayBody div into the popover-content div.
    String clientId = popover.getClientId(facesContext);
    String overlayBodyClientId = clientId.concat(OVERLAY_BODY_SUFFIX);
    String escapedOverlayBodyClientId = escapeClientId(overlayBodyClientId);

    String contentBoxClientId = clientId.concat(CONTENT_BOX_SUFFIX);
    String escapedContentBoxClientId = escapeClientId(contentBoxClientId);

    responseWriter.write("A.one('#");
    responseWriter.write(escapedOverlayBodyClientId);
    responseWriter.write("').appendTo(A.one('div#");
    responseWriter.write(escapedContentBoxClientId);
    responseWriter.write(">div.popover-content'));");

    if (popover.isDismissible()) {
      encodeOverlayDismissible(responseWriter, popover, clientKey);
    }

    encodeOverlayJavaScriptCustom(responseWriter, facesContext, popover);

    if ((popover.getFor() == null) && facesContext.isProjectStage(ProjectStage.Development)) {
      logger.error("The 'for' attribute is required for alloy:popover");
    }
  }
  public String submit() {

    if (logger.isDebugEnabled()) {
      logger.debug("firstName=" + applicantModelBean.getFirstName());
      logger.debug("lastName=" + applicantModelBean.getLastName());
      logger.debug("emailAddress=" + applicantModelBean.getEmailAddress());
      logger.debug("phoneNumber=" + applicantModelBean.getPhoneNumber());
      logger.debug("dateOfBirth=" + applicantModelBean.getDateOfBirth());
      logger.debug("city=" + applicantModelBean.getCity());
      logger.debug("provinceId=" + applicantModelBean.getProvinceId());
      logger.debug("postalCode=" + applicantModelBean.getPostalCode());
      logger.debug("comments=" + applicantModelBean.getComments());

      List<UploadedFile> uploadedFiles = applicantModelBean.getUploadedFiles();

      for (UploadedFile uploadedFile : uploadedFiles) {
        logger.debug("uploadedFile=[{0}]", uploadedFile.getName());
      }
    }

    // Delete the uploaded files.
    try {
      List<UploadedFile> uploadedFiles = applicantModelBean.getUploadedFiles();

      for (UploadedFile uploadedFile : uploadedFiles) {
        File file = new File(uploadedFile.getAbsolutePath());
        file.delete();
        logger.debug("Deleted file=[{0}]", file);
      }

      // Store the applicant's first name in JSF 2 Flash Scope so that it can be picked up
      // for use inside of confirmation.xhtml
      FacesContext facesContext = FacesContext.getCurrentInstance();
      facesContext
          .getExternalContext()
          .getFlash()
          .put("firstName", applicantModelBean.getFirstName());

      applicantModelBean.clearProperties();

      return "success";

    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      FacesMessageUtil.addGlobalUnexpectedErrorMessage(FacesContext.getCurrentInstance());

      return "failure";
    }
  }
  public void postalCodeListener(ValueChangeEvent valueChangeEvent) {

    try {
      String newPostalCode = (String) valueChangeEvent.getNewValue();
      City city = listModelBean.getCityByPostalCode(newPostalCode);

      if (city != null) {
        applicantModelBean.setAutoFillCity(city.getCityName());
        applicantModelBean.setAutoFillProvinceId(city.getProvinceId());
      }
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      FacesMessageUtil.addGlobalUnexpectedErrorMessage(FacesContext.getCurrentInstance());
    }
  }
  public static boolean isStateExclusive(Object themeDisplay) {

    boolean stateExclusive = false;

    if ((IS_STATE_EXCLUSIVE_METHOD != null) && (themeDisplay != null)) {

      try {
        stateExclusive = (Boolean) IS_STATE_EXCLUSIVE_METHOD.invoke(themeDisplay, new Object[] {});
      } catch (Exception e) {
        logger.error(e);
      }
    }

    return stateExclusive;
  }
  public static boolean isIsolated(Object themeDisplay) {

    boolean isolated = false;

    if ((IS_ISOLATED_METHOD != null) && (themeDisplay != null)) {

      try {
        isolated = (Boolean) IS_ISOLATED_METHOD.invoke(themeDisplay, new Object[] {});
      } catch (Exception e) {
        logger.error(e);
      }
    }

    return isolated;
  }
  @Override
  public void processEvent(SystemEvent postConstructApplicationEvent)
      throws AbortProcessingException {

    // Due to ClassLoader problems during static initialization, it is necessary to delay creation
    // of singleton
    // instances of template classes until the PostConstructApplicationEvent is sent.
    try {
      FacesContext startupFacesContext = FacesContext.getCurrentInstance();
      boolean minified = startupFacesContext.isProjectStage(ProjectStage.Production);
      wysiwygTemplate = new WYSIWYGTemplate(minified);
    } catch (Exception e) {
      logger.error(e);
    }
  }
  public ExternalContextImpl(
      PortletContext portletContext,
      PortletRequest portletRequest,
      PortletResponse portletResponse) {

    super(portletContext, portletRequest, portletResponse);

    try {
      boolean requestChanged = false;
      boolean responseChanged = false;
      preInitializeObjects(requestChanged, responseChanged);
    } catch (Exception e) {
      logger.error(e);
    }
  }
  /**
   * This method overrides the {@link #decode(FacesContext, UIComponent)} method so that it can
   * avoid a Servlet-API dependency in the RichFaces FileUploadRenderer. Note that rich:fileUpload
   * will do an Ajax postback and invoke the JSF lifecycle for each individual file.
   */
  @Override
  public void decode(FacesContext facesContext, UIComponent uiComponent) {

    try {

      // Get the UploadedFile from the request attribute map.
      ContextMapFactory contextMapFactory =
          (ContextMapFactory) FactoryExtensionFinder.getFactory(ContextMapFactory.class);
      BridgeContext bridgeContext = BridgeContext.getCurrentInstance();
      Map<String, Collection<UploadedFile>> uploadedFileMap =
          contextMapFactory.getUploadedFileMap(bridgeContext);

      if (uploadedFileMap != null) {

        // Use reflection to create a dynamic proxy class that implements the RichFaces UploadedFile
        // interface.
        Class<?> uploadedFileInterface = Class.forName(RICHFACES_UPLOADED_FILE_FQCN);
        Class<?> fileUploadEventClass = Class.forName(RICHFACES_FILE_UPLOAD_EVENT_FQCN);
        ClassLoader classLoader = uploadedFileInterface.getClassLoader();

        String clientId = uiComponent.getClientId(facesContext);
        Collection<UploadedFile> uploadedFiles = uploadedFileMap.get(clientId);

        if (uploadedFiles != null) {

          for (UploadedFile uploadedFile : uploadedFiles) {
            RichFacesUploadedFileHandler richFacesUploadedFileHandler =
                new RichFacesUploadedFileHandler(uploadedFile);
            Object richFacesUploadedFile =
                Proxy.newProxyInstance(
                    classLoader, new Class[] {uploadedFileInterface}, richFacesUploadedFileHandler);
            FacesEvent fileUploadEvent =
                (FacesEvent)
                    fileUploadEventClass
                        .getConstructor(UIComponent.class, uploadedFileInterface)
                        .newInstance(uiComponent, richFacesUploadedFile);

            // Queue the RichFaces FileUploadEvent instance so that it can be handled with an
            // ActionListener.
            uiComponent.queueEvent(fileUploadEvent);
          }
        }
      }
    } catch (Exception e) {
      logger.error(e);
    }
  }
  public void replaceBackLinkParameter(FacesContext facesContext) {
    String backLinkViewId = facesContext.getViewRoot().getViewId();
    String backLinkURL =
        facesContext.getApplication().getViewHandler().getActionURL(facesContext, backLinkViewId);
    String backLinkEncodedActionURL = StringPool.BLANK;

    try {
      backLinkEncodedActionURL =
          URLEncoder.encode(
              facesContext.getExternalContext().encodeActionURL(backLinkURL), StringPool.UTF8);
    } catch (UnsupportedEncodingException e) {
      logger.error(e.getMessage());
    }

    String newParamName = removeParameter(Bridge.BACK_LINK);
    setParameter(newParamName, backLinkEncodedActionURL);
  }
  public ExternalContextImpl(
      PortletContext portletContext,
      PortletRequest portletRequest,
      PortletResponse portletResponse) {

    super(portletContext, portletRequest, portletResponse);

    BeanManagerFactory beanManagerFactory =
        (BeanManagerFactory) FactoryExtensionFinder.getFactory(BeanManagerFactory.class);
    this.beanManager = beanManagerFactory.getBeanManager();

    try {
      boolean requestChanged = false;
      boolean responseChanged = false;
      preInitializeObjects(requestChanged, responseChanged);
    } catch (Exception e) {
      logger.error(e);
    }
  }
  /**
   * @see {@link ExternalContext#addResponseCookie(String, String, Map)}
   * @since JSF 2.0
   */
  @Override
  public void addResponseCookie(String name, String value, Map<String, Object> properties) {
    Cookie cookie = new Cookie(name, value);

    if ((properties != null) && !properties.isEmpty()) {

      try {
        String comment = (String) properties.get(COOKIE_PROPERTY_COMMENT);

        if (comment != null) {
          cookie.setComment(comment);
        }

        String domain = (String) properties.get(COOKIE_PROPERTY_DOMAIN);

        if (domain != null) {
          cookie.setDomain(domain);
        }

        Integer maxAge = (Integer) properties.get(COOKIE_PROPERTY_MAX_AGE);

        if (maxAge != null) {
          cookie.setMaxAge(maxAge);
        }

        String path = (String) properties.get(COOKIE_PROPERTY_PATH);

        if (path != null) {
          cookie.setPath(path);
        }

        Boolean secure = (Boolean) properties.get(COOKIE_PROPERTY_SECURE);

        if (secure != null) {
          cookie.setSecure(secure);
        }
      } catch (ClassCastException e) {
        logger.error(e.getMessage(), e);
      }
    }

    portletResponse.addProperty(cookie);
  }
  protected Object getInjectionProvider(Map<String, Object> applicationMap) {

    try {

      Object applicationAssociate = applicationMap.get("com.sun.faces.ApplicationAssociate");

      // If the ApplicationAssociate instance is available, then return the InjectionProvider that
      // it knows about.
      if (applicationAssociate != null) {

        // Note that the ApplicationAssociate instance will be available during startup if the
        // Mojarra
        // ConfigureListener executes prior to the BridgeSessionListener. It will also be available
        // during
        // execution of the JSF lifecycle.
        Method getInjectionProviderMethod =
            applicationAssociate.getClass().getMethod("getInjectionProvider", new Class[] {});
        Object mojarraInjectionProvider =
            getInjectionProviderMethod.invoke(applicationAssociate, new Object[] {});

        logger.debug("mojarraInjectionProvider=[{0}]", mojarraInjectionProvider);

        return mojarraInjectionProvider;
      }

      // Otherwise, return null.
      else {

        // Note that the ApplicationAssociate instance will be null if this method is called during
        // startup and
        // the BridgeSessionListener executes prior to the Mojarra ConfigureListener. This can be
        // remedied by
        // explicitly specifying com.sun.faces.config.ConfigureListener as a listener in the
        // WEB-INF/web.xml
        // descriptor.
        return null;
      }
    } catch (Exception e) {
      logger.error(e);

      return null;
    }
  }
  /**
   * @see {@link ExternalContext#addResponseCookie(String, String, Map)}
   * @since JSF 2.0
   */
  @Override
  public void addResponseCookie(String name, String value, Map<String, Object> properties) {
    Cookie cookie = new Cookie(name, value);

    if ((properties != null) && !properties.isEmpty()) {

      try {
        cookie.setComment((String) properties.get(COOKIE_PROPERTY_COMMENT));
        cookie.setDomain((String) properties.get(COOKIE_PROPERTY_DOMAIN));
        cookie.setMaxAge((Integer) properties.get(COOKIE_PROPERTY_MAX_AGE));
        cookie.setPath((String) properties.get(COOKIE_PROPERTY_PATH));
        cookie.setSecure((Boolean) properties.get(COOKIE_PROPERTY_SECURE));
      } catch (ClassCastException e) {
        logger.error(e.getMessage(), e);
      }
    }

    portletResponse.addProperty(cookie);
  }
  @Override
  public void encodeMarkupBegin(FacesContext facesContext, UIComponent uiComponent)
      throws IOException {

    ResponseWriter responseWriter = facesContext.getResponseWriter();
    OutputTooltipResponseWriter outputTooltipResponseWriter =
        new OutputTooltipResponseWriter(responseWriter, uiComponent);

    OutputTooltip outputTooltip = (OutputTooltip) uiComponent;

    if (outputTooltip.getFor() == null) {

      if (facesContext.isProjectStage(ProjectStage.Development)) {
        logger.error(
            "The outputTooltip needs to point to something. Try using its 'for' attribute to point to an 'id' in the component tree.");
      }
    }

    // Mojarra's HTML Basic calls encodeEnd for fun
    super.encodeMarkupEnd(facesContext, uiComponent, outputTooltipResponseWriter);
  }
  @Override
  public UIComponent createComponent(
      FacesContext facesContext, String componentType, String rendererType) {

    UIComponent wrappedUIComponent =
        wrappedApplication.createComponent(facesContext, componentType, rendererType);

    if (componentType.equals(DataPaginator.COMPONENT_TYPE)) {

      // Workaround for: http://jira.icesoft.org/browse/ICE-6398
      DataPaginator dataPaginator = new DataPaginatorBridgeImpl(wrappedUIComponent);

      try {
        dataPaginator.setUIData(dataPaginator.findUIData(facesContext));
        wrappedUIComponent = dataPaginator;
      } catch (Exception e) {
        logger.error(e);
      }
    }

    return wrappedUIComponent;
  }
  @Override
  public void invokeAnnotatedMethods(Object managedBean, boolean preferPreDestroy) {

    if (preferPreDestroy) {

      if (invokePreDestroyMethod != null) {

        try {
          logger.debug(
              "Invoking methods annotated with @PreDestroy: mojarraInjectionProvider=[{0}] managedBean=[{1}]",
              mojarraInjectionProvider, managedBean);
          invokePreDestroyMethod.invoke(mojarraInjectionProvider, managedBean);
        } catch (Exception e) {
          logger.error(e);
        }
      } else {
        super.invokeAnnotatedMethods(managedBean, preferPreDestroy);
      }
    } else {
      super.invokeAnnotatedMethods(managedBean, preferPreDestroy);
    }
  }
  @Override
  public void setResponse(Object response) {

    // Assume that the JSP_AFTER_VIEW_CONTENT feature is deactivated.
    facesImplementationServletResponse = null;

    // If JSP AFTER_VIEW_CONTENT processing has been activated by the bridge's
    // ViewDeclarationLanguageJspImpl#buildView(FacesContext, UIViewRoot) method, then wrap the
    // specified response
    // object with a ServletResponse that is able to handle the AFTER_VIEW_CONTENT feature. This is
    // necessary
    // because the Mojarra JspViewHandlingStrategy#getWrapper(ExternalContext) method has a Servlet
    // API dependency
    // due to explicit casts to HttpServletResponse.
    if (bridgeContext.isProcessingAfterViewContent()) {

      // If the specified response is of type HttpServletResponseWrapper, then it is almost certain
      // that Mojarra's
      // JspViewHandlingStrategy#executePageToBuildView(FacesContext, UIViewRoot) method is
      // attempting to wrap the
      // bridge's response object (that it originally got by calling the
      // ExternalContext#getResponse() method)
      // with it's ViewHandlerResponseWrapper, which extends HttpServletResponseWrapper.
      if (response instanceof HttpServletResponseWrapper) {

        this.facesImplementationServletResponse = (ServletResponse) response;

        HttpServletResponseWrapper httpServletResponseWrapper =
            (HttpServletResponseWrapper) response;
        ServletResponse wrappedServletResponse = httpServletResponseWrapper.getResponse();

        if (wrappedServletResponse instanceof BridgeAfterViewContentResponse) {
          BridgeAfterViewContentResponse bridgeAfterViewContentPreResponse =
              (BridgeAfterViewContentResponse) wrappedServletResponse;
          PortletResponse wrappedPortletResponse = bridgeAfterViewContentPreResponse.getWrapped();

          BridgeWriteBehindSupportFactory bridgeWriteBehindSupportFactory =
              (BridgeWriteBehindSupportFactory)
                  FactoryExtensionFinder.getFactory(BridgeWriteBehindSupportFactory.class);
          BridgeWriteBehindResponse bridgeWriteBehindResponse =
              bridgeWriteBehindSupportFactory.getBridgeWriteBehindResponse(
                  (MimeResponse) wrappedPortletResponse, facesImplementationServletResponse);

          // Note: See comments in BridgeContextImpl#dispatch(String) regarding Liferay's inability
          // to
          // accept a wrapped response. This is indeed supported in Pluto.
          this.portletResponse = (PortletResponse) bridgeWriteBehindResponse;
        } else {

          // Since we're unable to determine the wrapped PortletResponse, the following line will
          // throw an
          // intentional ClassCastException. Note that this case should never happen.
          this.portletResponse = (PortletResponse) response;
        }
      }

      // Otherwise, the specified response is of type BridgeAfterViewContentResponse, then Mojarra's
      // JspViewHandlingStrategy#executePageToBuildView(FacesContext, UIViewRoot) method is trying
      // to restore the
      // bridge's response object that it originally got from calling the
      // ExternalContext#getResponse() method
      // prior to wrapping with it's ViewHandlerResponseWrapper.
      else if (response instanceof BridgeAfterViewContentResponse) {
        BridgeAfterViewContentResponse bridgeAfterViewContentResponse =
            (BridgeAfterViewContentResponse) response;
        this.portletResponse = bridgeAfterViewContentResponse.getWrapped();
      }

      // Otherwise, assume that the specified response is a PortletResponse.
      else {
        this.portletResponse = (PortletResponse) response;
      }

    }

    // Otherwise, since the JSF AFTER_VIEW_CONTENT feature is not activated, assume that the
    // specified response is
    // a PortletResponse.
    else {
      this.portletResponse = (PortletResponse) response;
    }

    try {
      boolean requestChanged = false;
      boolean responseChanged = true;
      preInitializeObjects(requestChanged, responseChanged);
    } catch (Exception e) {
      logger.error(e);
    }
  }