org.rakam.ui.customreport.CustomPageHttpService.java Source code

Java tutorial

Introduction

Here is the source code for org.rakam.ui.customreport.CustomPageHttpService.java

Source

/*
 * 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 org.rakam.ui.customreport;

import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import com.google.common.io.ByteStreams;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.handler.codec.http.DefaultHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.LastHttpContent;
import org.rakam.config.EncryptionConfig;
import org.rakam.server.http.HttpService;
import org.rakam.server.http.RakamHttpRequest;
import org.rakam.server.http.annotations.Api;
import org.rakam.server.http.annotations.ApiOperation;
import org.rakam.server.http.annotations.ApiParam;
import org.rakam.server.http.annotations.Authorization;
import org.rakam.server.http.annotations.BodyParam;
import org.rakam.server.http.annotations.HeaderParam;
import org.rakam.server.http.annotations.IgnoreApi;
import org.rakam.server.http.annotations.JsonRequest;
import org.rakam.ui.ProtectEndpoint;
import org.rakam.ui.UIPermissionParameterProvider;
import org.rakam.ui.page.CustomPageDatabase;
import org.rakam.ui.user.WebUserService;
import org.rakam.util.RakamException;
import org.rakam.util.SuccessMessage;

import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
import static io.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND;
import static io.netty.handler.codec.http.HttpResponseStatus.NOT_IMPLEMENTED;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

@Path("/ui/custom-page")
@IgnoreApi
@Api(value = "/ui/custom-page", tags = "rakam-ui", authorizations = @Authorization(value = "read_key"))
public class CustomPageHttpService extends HttpService {
    private final Optional<CustomPageDatabase> database;

    @Inject
    public CustomPageHttpService(Optional<CustomPageDatabase> database) {
        this.database = database;
    }

    @Path("/frame")
    @GET
    public void frame(RakamHttpRequest request) {
        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
        String data = "<!DOCTYPE html> \n" + "<html>\n" + "   <body>\n" + "  \t  <script>\n"
                + "        var frame;\n" + "        window.onerror = function(message, url, lineNumber) {\n"
                + "            window.parent.postMessage({\n" + "                type: 'error',\n"
                + "                message: message,\n" + "                url: url,\n"
                + "                lineNumber: lineNumber\n" + "            }, '*');\n" + "        };\n"
                + "        window.addEventListener('message', function(e) {\n"
                + "            var data = JSON.parse(e.data);\n" + "            if (data.html) {\n"
                + "                if(frame) document.body.removeChild(frame);\n"
                + "                frame = document.createElement('iframe');\n"
                + "                frame.setAttribute('style', 'border:none;width:100%;height:100%;margin:0;padding:0;position:absolute;');\n"
                + "                frame.setAttribute('sandbox', 'allow-forms allow-popups allow-scripts allow-same-origin');\n"
                + "                document.body.appendChild(frame);\n"
                + "                frame.contentWindow.document.write(data.html);\n"
                + "                frame.contentWindow.document.close();\n" + "            }\n" + "        });\n"
                + "\t  </script>\n" + "   </body>\n" + "</html>";

        response.headers().set(CONTENT_TYPE, "text/html");
        HttpHeaders.setContentLength(response, data.length());
        request.context().write(response);
        request.context().write(Unpooled.wrappedBuffer(data.getBytes()));
        ChannelFuture lastContentFuture = request.context().writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);

        if (!HttpHeaders.isKeepAlive(request)) {
            lastContentFuture.addListener(ChannelFutureListener.CLOSE);
        }
    }

    @Path("/save")
    @POST
    @JsonRequest
    @ProtectEndpoint(writeOperation = true)
    @ApiOperation(value = "Save Report", authorizations = @Authorization(value = "read_key"), response = SuccessMessage.class, request = CustomPageDatabase.Page.class)
    public SuccessMessage save(@Named("user_id") UIPermissionParameterProvider.Project project,
            @BodyParam CustomPageDatabase.Page report) {
        database.get().save(project.userId, project.project, report);
        return SuccessMessage.success();
    }

    @Path("/delete")
    @ApiOperation(value = "Delete Report", authorizations = @Authorization(value = "read_key"))
    @JsonRequest
    @ProtectEndpoint(writeOperation = true)
    public SuccessMessage delete(
            @com.google.inject.name.Named("user_id") UIPermissionParameterProvider.Project project,
            @ApiParam("name") String name) {
        if (!database.isPresent()) {
            throw new RakamException(NOT_IMPLEMENTED);
        }

        database.get().delete(project.project, name);
        return SuccessMessage.success();
    }

    @Path("/check")
    @ApiOperation(value = "Check feature exists", authorizations = @Authorization(value = "read_key"))
    @GET
    public boolean check() {
        return !database.isPresent();
    }

    @Path("/get")
    @ApiOperation(value = "Get Report", authorizations = @Authorization(value = "read_key"))
    @JsonRequest
    public Map<String, String> get(
            @com.google.inject.name.Named("user_id") UIPermissionParameterProvider.Project project,
            @ApiParam("slug") String slug) {
        if (!database.isPresent()) {
            throw new RakamException(NOT_IMPLEMENTED);
        }
        return database.get().get(project.project, slug);
    }

    @Path("/display/*")
    @GET
    public void display(RakamHttpRequest request) {
        if (!database.isPresent()) {
            throw new RakamException(NOT_IMPLEMENTED);
        }
        String path = request.path().substring(21);
        String[] projectCustomPage = path.split("/", 3);
        byte[] bytes;
        try {
            InputStream file = database.get().getFile(Integer.parseInt(projectCustomPage[0]), projectCustomPage[1],
                    projectCustomPage[2]);
            if (file == null) {
                request.response(NOT_FOUND.reasonPhrase(), NOT_FOUND).end();
            }
            bytes = ByteStreams.toByteArray(file);
        } catch (IOException e) {
            throw Throwables.propagate(e);
        }
        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);

        response.headers().set(CONTENT_TYPE, "text/html");
        HttpHeaders.setContentLength(response, bytes.length);
        request.context().write(response);
        request.context().write(Unpooled.wrappedBuffer(bytes));
        ChannelFuture lastContentFuture = request.context().writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);

        if (!HttpHeaders.isKeepAlive(request)) {
            lastContentFuture.addListener(ChannelFutureListener.CLOSE);
        }
    }

    @Path("/list")
    @ApiOperation(value = "Get Report", authorizations = @Authorization(value = "read_key"))
    @JsonRequest
    public List<CustomPageDatabase.Page> list(@Named("user_id") UIPermissionParameterProvider.Project project) {
        if (!database.isPresent()) {
            return null;
        }
        return database.get().list(project.project);
    }
}