/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.jooby.internal.sitemap;
import static java.util.Objects.requireNonNull;
import static javaslang.API.Case;
import static javaslang.API.Match;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;
import org.jooby.Env;
import org.jooby.Jooby;
import org.jooby.Route;
import org.jooby.sitemap.WebPageProvider;
import com.google.inject.Binder;
import com.google.inject.Key;
import com.google.inject.name.Names;
import com.typesafe.config.Config;
import cz.jiripinkas.jsitemapgenerator.WebPage;
import javaslang.Function1;
@SuppressWarnings("rawtypes")
public abstract class JSitemap<T extends JSitemap> implements Jooby.Module {
protected static final String SITEMAP = "/sitemap.xml";
static final Predicate<Route.Definition> NOT_ME = r -> {
return !r.pattern().equals(SITEMAP);
};
static final Predicate<Route.Definition> GET = r -> r.method().equals("GET");
private static final String SITEMAP_BASEURL = "sitemap.url";
private String path;
private Consumer<Binder> wpp;
private Predicate<Route.Definition> filter = GET;
private Optional<String> baseurl;
public JSitemap(final String path, final Optional<String> baseurl, final WebPageProvider wpp) {
this.path = path;
this.baseurl = baseurl;
this.wpp = binder -> binder
.bind(Key.get(WebPageProvider.class, Names.named(path))).toInstance(wpp);
}
@SuppressWarnings("unchecked")
public T filter(final Predicate<Route.Definition> filter) {
this.filter = requireNonNull(filter, "Filter is required.");
return (T) this;
}
@SuppressWarnings("unchecked")
public T with(final WebPageProvider wpp) {
requireNonNull(wpp, "WebPageProvider is required.");
this.wpp = binder -> binder.bind(Key.get(WebPageProvider.class, Names.named(path)))
.toInstance(wpp);
return (T) this;
}
@SuppressWarnings("unchecked")
public T with(final Class<? extends WebPageProvider> wpp) {
requireNonNull(wpp, "WebPageProvider is required.");
this.wpp = binder -> binder.bind(Key.get(WebPageProvider.class, Names.named(path)))
.to(wpp);
return (T) this;
}
@Override
public void configure(final Env env, final Config conf, final Binder binder) {
String baseurl = this.baseurl.orElseGet(() -> Match(conf.hasPath(SITEMAP_BASEURL)).of(
Case(true, () -> conf.getString(SITEMAP_BASEURL)),
Case(false, () -> {
Config $ = conf.getConfig("application");
return "http://" + $.getString("host") + ":" + $.getString("port") + $.getString("path");
})));
wpp.accept(binder);
env.router().get(path, new SitemapHandler(path, NOT_ME.and(filter), gen(baseurl)));
}
protected abstract Function1<List<WebPage>, String> gen(String baseurl);
}