Package juzu.impl.bridge.spi.portlet

Source Code of juzu.impl.bridge.spi.portlet.PortletMimeBridge

/*
* Copyright 2013 eXo Platform SAS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package juzu.impl.bridge.spi.portlet;

import juzu.PropertyType;
import juzu.Response;
import juzu.impl.asset.Asset;
import juzu.impl.bridge.Bridge;
import juzu.impl.common.Formatting;
import juzu.impl.common.Tools;
import juzu.impl.plugin.asset.AssetService;
import juzu.impl.request.ContextualParameter;
import juzu.request.Phase;
import juzu.io.Chunk;
import juzu.io.Stream;
import org.w3c.dom.Comment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import javax.portlet.MimeResponse;
import javax.portlet.PortletConfig;
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;

/** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */
public abstract class PortletMimeBridge<Rq extends PortletRequest, Rs extends MimeResponse> extends PortletRequestBridge<Rq, Rs> {

  PortletMimeBridge(Bridge bridge, Phase phase, Rq request, Rs response, PortletConfig config) {
    super(bridge, phase, request, response, config);
  }

  public abstract Stream createStream(String mimeType, Charset charset) throws IOException;

  @Override
  public Map<ContextualParameter, Object> getContextualArguments(Set<ContextualParameter> parameters) {
    return Collections.emptyMap();
  }

  @Override
  public void send() throws IOException, PortletException {
    if (response instanceof Response.Status) {

      //
      Response.Status status = (Response.Status)response;

      //
      final AssetService assetPlugin = (AssetService)bridge.getApplication().getPlugin("asset");

      //
      Stream stream = new Stream() {

        /** . */
        private Charset charset = Tools.ISO_8859_1;

        /** . */
        private String mimeType = null;

        /** . */
        private Stream dataStream = null;

        /** . */
        private final LinkedList<String> assets = new LinkedList<String>();

        public void provide(Chunk chunk) {
          if (chunk instanceof Chunk.Property) {
            Chunk.Property<?> property = (Chunk.Property<?>)chunk;
            if (property.type == PropertyType.ENCODING) {
              charset = (Charset)property.value;
            } else if (property.type == PropertyType.MIME_TYPE) {
              mimeType = (String)property.value;
            } else if (property.type == PropertyType.HEADER) {
              Map.Entry<String, String[]> header = (Map.Entry<String, String[]>)property.value;
              for (String value : header.getValue()) {
                resp.addProperty(header.getKey(), value);
              }
            } if (property.type == PropertyType.TITLE) {
              if (resp instanceof RenderResponse) {
                ((RenderResponse)resp).setTitle((String)property.value);
              }
            } else if (property.type == PropertyType.META_TAG) {
              Map.Entry<String, String> metaTag = (Map.Entry<String, String>)property.value;
              Element elt = resp.createElement("meta");
              elt.setAttribute("name", metaTag.getKey());
              elt.setAttribute("content", metaTag.getValue());
              resp.addProperty(MimeResponse.MARKUP_HEAD_ELEMENT, elt);
            } else if (property.type == PropertyType.ASSET) {
              assets.add(((String)property.value));
            } else if (property.type == PropertyType.HEADER_TAG) {
              Element headerTag = (Element)property.value;
              Element responseTag = resp.createElement(headerTag.getTagName());
              for (Node child : Tools.children(headerTag)) {
                child = responseTag.getOwnerDocument().importNode(headerTag, true);
                responseTag.appendChild(child);
              }
              resp.addProperty(MimeResponse.MARKUP_HEAD_ELEMENT, headerTag);
            }
          } else if (chunk instanceof Chunk.Data) {
            Chunk.Data data = (Chunk.Data)chunk;
            if (dataStream == null) {
              Iterable<Asset> resolvedAssets = assetPlugin.getAssetManager().resolveAssets(assets);
              for (Asset resolvedAsset : resolvedAssets) {
                Element elt;
                if (resolvedAsset.isStylesheet()) {
                  int pos = resolvedAsset.getURI().lastIndexOf('.');
                  String ext = pos == -1 ? "css" : resolvedAsset.getURI().substring(pos + 1);
                  elt = resp.createElement("link");
                  elt.setAttribute("media", "screen");
                  elt.setAttribute("rel", "stylesheet");
                  elt.setAttribute("type", "text/" + ext);
                  elt.setAttribute("href", PortletMimeBridge.this.getAssetURL(resolvedAsset));
                } else if (resolvedAsset.isScript()) {
                  String url = PortletMimeBridge.this.getAssetURL(resolvedAsset);
                  elt = resp.createElement("script");
                  elt.setAttribute("type", "text/javascript");
                  elt.setAttribute("src", url);
                  // This comment is needed for liferay to make the script pass the minifier
                  // it forces to have a <script></script> tag
                  String dummy = bridge.getApplication().getName() + " script ";
                  Comment comment = elt.getOwnerDocument().createComment(dummy);
                  elt.appendChild(comment);
                } else {
                  elt = null;
                }
                if (elt != null) {
                  resp.addProperty(MimeResponse.MARKUP_HEAD_ELEMENT, elt);
                }
              }
              try {
                dataStream = createStream(mimeType, charset);
              }
              catch (IOException e) {
                throw new UnsupportedOperationException("Handle me gracefully");
              }
            }
            dataStream.provide(data);
          }
        }

        public void close(Thread.UncaughtExceptionHandler errorHandler) {
        }
      };

      //
      if (status.getCode() != 200) {
        resp.addProperty(ResourceResponse.HTTP_STATUS_CODE, Integer.toString(status.getCode()));
      }
      status.streamable().send(stream);
    } else if (response instanceof Response.Error) {
      Response.Error error = (Response.Error)response;
      if (bridge.getRunMode().getPrettyFail()) {
        resp.setContentType("text/html");
        PrintWriter writer = resp.getWriter();
        writer.append("<div class=\"juzu\">");
        Throwable cause = error.getCause();
        if (cause != null) {
          Formatting.renderThrowable(null, writer, cause);
        } else {
          writer.append(error.getMessage());
        }
        writer.append("</div>");
        writer.close();
      } else {
        throw new PortletException(error.getCause());
      }
    }
  }
}
TOP

Related Classes of juzu.impl.bridge.spi.portlet.PortletMimeBridge

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.