Skip to content

Commit 5452837

Browse files
committed
Add Environment.getClassLoader
1 parent 6c2f817 commit 5452837

File tree

10 files changed

+226
-173
lines changed

10 files changed

+226
-173
lines changed

jooby/src/main/java/io/jooby/Environment.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,23 +52,28 @@ public class Environment {
5252

5353
private final Config conf;
5454

55+
private final ClassLoader classLoader;
56+
5557
/**
5658
* Creates a new environment.
5759
*
60+
* @param classLoader Class loader.
5861
* @param conf Application configuration.
5962
* @param actives Active environment names.
6063
*/
61-
public Environment(@Nonnull Config conf, @Nonnull String... actives) {
62-
this(conf, Arrays.asList(actives));
64+
public Environment(@Nonnull ClassLoader classLoader, @Nonnull Config conf, @Nonnull String... actives) {
65+
this(classLoader, conf, Arrays.asList(actives));
6366
}
6467

6568
/**
6669
* Creates a new environment.
6770
*
71+
* @param classLoader Class loader.
6872
* @param conf Application configuration.
6973
* @param actives Active environment names.
7074
*/
71-
public Environment(@Nonnull Config conf, @Nonnull List<String> actives) {
75+
public Environment(@Nonnull ClassLoader classLoader, @Nonnull Config conf, @Nonnull List<String> actives) {
76+
this.classLoader = classLoader;
7277
this.actives = actives.stream()
7378
.map(String::trim)
7479
.map(String::toLowerCase)
@@ -106,6 +111,15 @@ public boolean isActive(String name, String... names) {
106111
|| Stream.of(names).map(String::toLowerCase).anyMatch(this.actives::contains);
107112
}
108113

114+
/**
115+
* Application class loader.
116+
*
117+
* @return Application class loader.
118+
*/
119+
public ClassLoader getClassLoader() {
120+
return classLoader;
121+
}
122+
109123
@Override public String toString() {
110124
return actives + "\n" + toString(conf).trim();
111125
}
@@ -226,7 +240,7 @@ private String configTree(final String[] sources, final int i) {
226240
.withFallback(defaults())
227241
.resolve();
228242

229-
return new Environment(result, actives);
243+
return new Environment(options.getClassLoader(), result, actives);
230244
}
231245

232246
/**

jooby/src/test/java/io/jooby/EnvironmentTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public void envfromfs() {
8686
@Test
8787
public void objectLookup() {
8888

89-
Environment env = new Environment(ConfigFactory.parseMap(mapOf("h.pool", "1", "h.db.pool", "2")), "test");
89+
Environment env = new Environment(getClass().getClassLoader(), ConfigFactory.parseMap(mapOf("h.pool", "1", "h.db.pool", "2")), "test");
9090

9191
assertEquals("1", env.getConfig().getString("h.pool"));
9292
assertEquals("2", env.getConfig().getString("h.db.pool"));

modules/jooby-freemarker/src/main/java/io/jooby/freemarker/Freemarker.java

Lines changed: 0 additions & 137 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package io.jooby.freemarker;
2+
3+
import freemarker.template.Configuration;
4+
import freemarker.template.Template;
5+
import io.jooby.Context;
6+
import io.jooby.ModelAndView;
7+
import io.jooby.TemplateEngine;
8+
9+
import java.io.StringWriter;
10+
import java.util.HashMap;
11+
import java.util.Map;
12+
13+
class FreemarkerTemplateEngine implements TemplateEngine {
14+
15+
private final Configuration freemarker;
16+
17+
public FreemarkerTemplateEngine(Configuration freemarker) {
18+
this.freemarker = freemarker;
19+
}
20+
21+
@Override public String apply(Context ctx, ModelAndView modelAndView) throws Exception {
22+
Template template = freemarker.getTemplate(modelAndView.view);
23+
StringWriter writer = new StringWriter();
24+
Map<String, Object> model = new HashMap<>(ctx.getAttributes());
25+
model.putAll(modelAndView.model);
26+
template.process(model, writer);
27+
return writer.toString();
28+
}
29+
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/**
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*
14+
* Copyright 2014 Edgar Espina
15+
*/
16+
package io.jooby.freemarker;
17+
18+
import com.typesafe.config.Config;
19+
import freemarker.cache.CacheStorage;
20+
import freemarker.cache.ClassTemplateLoader;
21+
import freemarker.cache.FileTemplateLoader;
22+
import freemarker.cache.NullCacheStorage;
23+
import freemarker.cache.SoftCacheStorage;
24+
import freemarker.cache.TemplateLoader;
25+
import freemarker.core.HTMLOutputFormat;
26+
import freemarker.core.OutputFormat;
27+
import freemarker.template.Configuration;
28+
import io.jooby.Environment;
29+
import io.jooby.Extension;
30+
import io.jooby.Jooby;
31+
import io.jooby.MediaType;
32+
import io.jooby.Throwing;
33+
34+
import javax.annotation.Nonnull;
35+
import java.nio.file.Files;
36+
import java.nio.file.Path;
37+
import java.nio.file.Paths;
38+
import java.util.HashMap;
39+
import java.util.Map;
40+
41+
import static io.jooby.Throwing.throwingConsumer;
42+
43+
public class Freemarkerby implements Extension {
44+
45+
public static class Builder {
46+
47+
private TemplateLoader templateLoader;
48+
49+
private Map<String, String> settings = new HashMap<>();
50+
51+
private CacheStorage cacheStorage;
52+
53+
private OutputFormat outputFormat = HTMLOutputFormat.INSTANCE;
54+
55+
private String templatePath = "views";
56+
57+
public @Nonnull Builder setTemplateLoader(@Nonnull TemplateLoader loader) {
58+
this.templateLoader = loader;
59+
return this;
60+
}
61+
62+
public @Nonnull Builder setSetting(@Nonnull String name, @Nonnull String value) {
63+
this.settings.put(name, value);
64+
return this;
65+
}
66+
67+
public @Nonnull Builder setCache(@Nonnull CacheStorage cacheStorage) {
68+
this.cacheStorage = cacheStorage;
69+
return this;
70+
}
71+
72+
public @Nonnull Builder setOutputFormat(@Nonnull OutputFormat outputFormat) {
73+
this.outputFormat = outputFormat;
74+
return this;
75+
}
76+
77+
public @Nonnull Builder setTemplatePath(@Nonnull String templatePath) {
78+
if (templatePath.startsWith("/")) {
79+
this.templatePath = templatePath.substring(1);
80+
} else {
81+
this.templatePath = templatePath;
82+
}
83+
return this;
84+
}
85+
86+
public @Nonnull Configuration build(@Nonnull Environment env) {
87+
Configuration freemarker = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
88+
freemarker.setOutputFormat(outputFormat);
89+
90+
/** Settings: */
91+
Config conf = env.getConfig();
92+
if (conf.hasPath("freemarker")) {
93+
conf.getConfig("freemarker").root().unwrapped()
94+
.forEach((k, v) -> settings.put(k, v.toString()));
95+
}
96+
settings.putIfAbsent("defaultEncoding", "UTF-8");
97+
settings.forEach(throwingConsumer(freemarker::setSetting));
98+
99+
/** Template loader: */
100+
if (templateLoader == null) {
101+
templateLoader = defaultTemplateLoader(env);
102+
}
103+
freemarker.setTemplateLoader(templateLoader);
104+
105+
/** Cache storage: */
106+
if (this.cacheStorage == null) {
107+
this.cacheStorage = env.isActive("dev", "test")
108+
? NullCacheStorage.INSTANCE
109+
: new SoftCacheStorage();
110+
}
111+
freemarker.setCacheStorage(this.cacheStorage);
112+
113+
// clear
114+
this.templateLoader = null;
115+
this.settings.clear();
116+
this.settings = null;
117+
this.cacheStorage = null;
118+
return freemarker;
119+
}
120+
121+
private TemplateLoader defaultTemplateLoader(Environment env) {
122+
try {
123+
Path templateDir = Paths.get(System.getProperty("user.dir"), templatePath);
124+
if (Files.exists(templateDir)) {
125+
return new FileTemplateLoader(templateDir.toFile());
126+
}
127+
return new ClassTemplateLoader(env.getClassLoader(), "/" + templatePath);
128+
} catch (Exception x) {
129+
throw Throwing.sneakyThrow(x);
130+
}
131+
}
132+
}
133+
134+
private Configuration freemarker;
135+
136+
public Freemarkerby(@Nonnull Configuration freemarker) {
137+
this.freemarker = freemarker;
138+
}
139+
140+
public Freemarkerby() {
141+
}
142+
143+
@Override public void install(@Nonnull Jooby application) {
144+
if (freemarker == null) {
145+
freemarker = create().build(application.getEnvironment());
146+
}
147+
application.renderer(MediaType.html, new FreemarkerTemplateEngine(freemarker));
148+
}
149+
150+
public static Freemarkerby.Builder create() {
151+
return new Freemarkerby.Builder();
152+
}
153+
}

0 commit comments

Comments
 (0)