All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.rapidoid.gui.HtmlPage Maven / Gradle / Ivy

/*-
 * #%L
 * rapidoid-gui
 * %%
 * Copyright (C) 2014 - 2017 Nikolche Mihajlovski and contributors
 * %%
 * 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.
 * #L%
 */

package org.rapidoid.gui;

import org.rapidoid.annotation.Authors;
import org.rapidoid.annotation.Since;
import org.rapidoid.commons.RapidoidInfo;
import org.rapidoid.commons.Str;
import org.rapidoid.config.Conf;
import org.rapidoid.gui.menu.PageMenu;
import org.rapidoid.gui.reqinfo.IReqInfo;
import org.rapidoid.gui.reqinfo.ReqInfo;
import org.rapidoid.gui.reqinfo.ReqInfoUtils;
import org.rapidoid.http.HttpVerb;
import org.rapidoid.render.Template;
import org.rapidoid.render.Templates;
import org.rapidoid.u.U;
import org.rapidoid.util.Msc;
import org.rapidoid.web.ScreenBean;
import org.rapidoid.writable.WritableOutputStream;
import org.rapidoid.writable.WritableUtils;

import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.Set;


@Authors("Nikolche Mihajlovski")
@Since("5.0.0")
public class HtmlPage extends ScreenBean {

	private static volatile String commonJs = Msc.isPlatform() ? "_rapidoid/platform.js" : "application.js";
	private static volatile String commonCss = Msc.isPlatform() ? "_rapidoid/platform.css" : "application.css";

	private static volatile Template PAGE_TEMPLATE = Templates.load("page.html");
	private static volatile Template PAGE_AJAX_TEMPLATE = Templates.load("page-ajax.html");

	public HtmlPage(Object[] content) {
		content(content);
	}

	@Override
	public String render() {
		Map model = pageModel();

		if (menu() != null) {
			PageMenu.from(menu()).renderContentTemplates(model);
		}

		String html;
		IReqInfo req = ReqInfo.get();
		if (req.isGetReq() && !GUI.isEvent()) {
			html = PAGE_TEMPLATE.render(model);
		} else {
			html = PAGE_AJAX_TEMPLATE.render(model);
		}

		return html;
	}

	@Override
	public void render(OutputStream out) {
		String html = render();
		WritableUtils.writeUTF8(new WritableOutputStream(out), html);
	}

	@SuppressWarnings("unchecked")
	private Map pageModel() {
		IReqInfo req = ReqInfo.get();

		Map model = U.map(req.data());

		model.put("req", req);

		model.put("appUrl", ReqInfoUtils.appUrl());
		model.put("adminUrl", ReqInfoUtils.adminUrl());

		model.put("loginUri", Msc.specialUri("login"));
		model.put("logoutUri", Msc.specialUri("logout"));
		model.put("profileUri", Msc.semiSpecialUri("profile"));
		model.put("graphsUri", Msc.specialUri("graphs"));

		model.put("dev", Msc.isDev());
		model.put("admin", "admin".equalsIgnoreCase(req.zone()));

		model.put("host", req.host());
		model.put("verb", req.verb());
		model.put("uri", req.uri());
		model.put("path", req.path());
		model.put("zone", req.zone());

		model.put("username", req.username());

		Set roles = req.roles();
		model.put("roles", roles);

		model.put("has", has());

		model.put("content", GUI.multi(content()));
		model.put("home", req.contextPath() + home());
		model.put("brand", brand());
		model.put("title", title());

		PageMenu pageMenu = PageMenu.from(menu());
		pageMenu.uri(req.path());
		model.put("menu", pageMenu);

		model.put("version", RapidoidInfo.version());
		model.put("embedded", embedded() || req.attrs().get("_embedded") != null || req.params().get("_embedded") != null);

		model.put("search", search());
		model.put("navbar", navbar());
		model.put("fluid", fluid());
		model.put("cdn", cdn());

		List assets = (List) Conf.GUI.entry("assets").getOrNull();

		if (U.notEmpty(assets)) {
			for (String asset : assets) {
				String res = asset.toLowerCase();

				if (res.endsWith(".js")) {
					js().add(res);
				} else if (res.endsWith(".css")) {
					css().add(res);
				} else {
					throw U.rte("Expected .css or .js asset, but found: " + res);
				}
			}
		}

		setupAssets(req, model);

		return model;
	}

	private void setupAssets(IReqInfo req, Map model) {
		String view = req.view();

		if (req.hasRoute(HttpVerb.GET, commonJs)) {
			js().add(commonJs);
		}

		if (req.hasRoute(HttpVerb.GET, commonCss)) {
			css().add(commonCss);
		}

		if (U.notEmpty(view)) {
			String pageJs = "/" + view + ".js";
			if (req.hasRoute(HttpVerb.GET, pageJs)) {
				js().add(pageJs);
			}

			String pageCss = "/" + view + ".css";
			if (req.hasRoute(HttpVerb.GET, pageCss)) {
				css().add(pageCss);
			}
		}

		model.put("js", withContextPath(js(), req.contextPath()));
		model.put("css", withContextPath(css(), req.contextPath()));
	}

	private static Set withContextPath(Set assets, String contextPath) {
		Set withContextPath = U.set();

		for (String asset : assets) {
			if (!asset.startsWith("http://") && !asset.startsWith("https://") && !asset.startsWith("//")) {
				asset = contextPath + "/" + Str.triml(asset, "/");
			}

			withContextPath.add(asset);
		}

		return withContextPath;
	}

	private Map has() {
		Map has = U.map();

		has.put("role", HtmlPageUtils.HAS_ROLE);
		has.put("path", HtmlPageUtils.HAS_PATH);
		has.put("zone", HtmlPageUtils.HAS_ZONE);
		has.put("page", HtmlPageUtils.HAS_PAGE);
		has.put("special_page", HtmlPageUtils.HAS_SPECIAL_PAGE);

		return has;
	}

	public static String commonJs() {
		return commonJs;
	}

	public static void commonJs(String commonJs) {
		HtmlPage.commonJs = commonJs;
	}

	public static String commonCss() {
		return commonCss;
	}

	public static void commonCss(String commonCss) {
		HtmlPage.commonCss = commonCss;
	}

	@Override
	public String toString() {
		return render();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy