co.cask.cdap.internal.app.runtime.webapp.ServePathGenerator.java Source code

Java tutorial

Introduction

Here is the source code for co.cask.cdap.internal.app.runtime.webapp.ServePathGenerator.java

Source

/*
 * Copyright  2014 Cask Data, Inc.
 *
 * 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 co.cask.cdap.internal.app.runtime.webapp;

import co.cask.cdap.common.conf.Constants;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;

import java.net.URI;

/**
 * Determines the path to serve based on the Host header.
 */
public class ServePathGenerator {
    public static final String SRC_PATH = "/src/";
    public static final String DEFAULT_DIR_NAME = "default";
    private static final String GATEWAY_PATH_V3 = Constants.Gateway.API_VERSION_3.substring(1) + "/";

    private static final String DEFAULT_PORT_STR = ":80";

    private final String baseDir;
    private final Predicate<String> fileExists;

    public ServePathGenerator(String baseDir, Predicate<String> fileExists) {
        this.baseDir = baseDir.replaceAll("/+$", "");
        this.fileExists = fileExists;
    }

    public String getServePath(String hostHeader, String uriString) {
        URI uri = URI.create(uriString);
        String path = uri.getPath();
        String query = uri.getQuery();

        if (path.startsWith("/")) {
            path = path.substring(1);
        }

        if (path.endsWith("/")) {
            path = path.substring(0, path.length() - 1);
        }

        // If exact match present, return it
        String servePath = findPath(hostHeader, path, query);
        if (servePath != null) {
            return constructURI(servePath);
        }

        boolean isDefaultPort = hostHeader.endsWith(DEFAULT_PORT_STR);
        boolean hasNoPort = hostHeader.indexOf(':') == -1;

        // Strip DEFAULT_PORT_STR and try again
        if (isDefaultPort) {
            servePath = findPath(hostHeader.substring(0, hostHeader.length() - DEFAULT_PORT_STR.length()), path,
                    query);
            if (servePath != null) {
                return constructURI(servePath);
            }
        }

        // Add DEFAULT_PORT_STR and try
        if (hasNoPort) {
            servePath = findPath(hostHeader + DEFAULT_PORT_STR, path, query);
            if (servePath != null) {
                return constructURI(servePath);
            }
        }

        // Else if "default" is present, that is the serve dir
        servePath = findPath(DEFAULT_DIR_NAME, path, query);
        if (servePath != null) {
            return constructURI(servePath);
        }

        return constructURI(path);
    }

    private String constructURI(String servePath) {
        return servePath.startsWith("/") ? servePath : "/" + servePath;
    }

    private String findPath(String hostHeader, String path, String query) {
        // First try firstPathPart/src/restPath
        Iterable<String> pathParts = Splitter.on('/').limit(2).split(path);
        String servePath;
        if (Iterables.size(pathParts) > 1) {
            String part1 = Iterables.get(pathParts, 1);
            if (part1.startsWith(GATEWAY_PATH_V3) || part1.equals("status")) {
                return constructPath(part1, query);
            }

            servePath = String.format("%s/%s/%s%s%s", baseDir, hostHeader, Iterables.get(pathParts, 0), SRC_PATH,
                    Iterables.get(pathParts, 1));
            if (fileExists.apply(servePath)) {
                return servePath;
            }

        } else if (Iterables.size(pathParts) == 1) {
            servePath = String.format("%s/%s/%s%s%s", baseDir, hostHeader, Iterables.get(pathParts, 0), SRC_PATH,
                    "index.html");
            if (fileExists.apply(servePath)) {
                return servePath;
            }
        }

        // Next try src/path
        if (path.startsWith(GATEWAY_PATH_V3) || path.equals("status")) {
            return constructPath(path, query);
        }

        path = path.isEmpty() ? "index.html" : path;
        servePath = String.format("%s/%s%s%s", baseDir, hostHeader, SRC_PATH, path);
        if (fileExists.apply(servePath)) {
            return servePath;
        }

        return null;
    }

    private String constructPath(String path, String query) {
        return query == null ? path : String.format("%s?%s", path, query);
    }
}