Integration of CCM themes and EE/MVC Krazo
parent
303ca7e39c
commit
dfde296f83
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.libreccm.mvc.freemarker;
|
||||||
|
|
||||||
|
import freemarker.cache.MultiTemplateLoader;
|
||||||
|
import freemarker.cache.TemplateLoader;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* A copy of the {@link TemplateLoader} used by Krazo.
|
||||||
|
*
|
||||||
|
* The {@code TemplateLoader} used by Krazo is defined as inner class. This
|
||||||
|
* class provides the same behaviour as "real" class so that we can use it with
|
||||||
|
* Freemarker {@link MultiTemplateLoader}.
|
||||||
|
*
|
||||||
|
* As extension this implementation of the {@code TemplateLoader} interface will
|
||||||
|
* not process template paths which start with {@code @themes/} or
|
||||||
|
* {@code /@themes/}. These path are processed by the templates loaders for the
|
||||||
|
* theming system.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class KrazoTemplateLoader implements TemplateLoader {
|
||||||
|
|
||||||
|
private final ServletContext servletContext;
|
||||||
|
|
||||||
|
public KrazoTemplateLoader(final ServletContext servletContext) {
|
||||||
|
super();
|
||||||
|
this.servletContext = servletContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object findTemplateSource(final String name) throws IOException {
|
||||||
|
if (name.startsWith("@themes") || name.startsWith("/@themes")) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
// Freemarker drops "/"
|
||||||
|
return servletContext.getResourceAsStream(
|
||||||
|
String.format("/%s", name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLastModified(final Object templateSource) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Reader getReader(
|
||||||
|
final Object templateSource, final String encoding
|
||||||
|
) throws IOException {
|
||||||
|
return new InputStreamReader((InputStream) templateSource, encoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeTemplateSource(
|
||||||
|
final Object templateSource
|
||||||
|
) throws IOException {
|
||||||
|
final InputStream inputStream = (InputStream) templateSource;
|
||||||
|
inputStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.libreccm.mvc.freemarker;
|
||||||
|
|
||||||
|
import freemarker.cache.ClassTemplateLoader;
|
||||||
|
import freemarker.cache.MultiTemplateLoader;
|
||||||
|
import freemarker.cache.TemplateLoader;
|
||||||
|
import freemarker.cache.WebappTemplateLoader;
|
||||||
|
import freemarker.template.Configuration;
|
||||||
|
import freemarker.template.TemplateExceptionHandler;
|
||||||
|
import org.eclipse.krazo.engine.ViewEngineConfig;
|
||||||
|
import org.eclipse.krazo.ext.freemarker.DefaultConfigurationProducer;
|
||||||
|
import org.libreccm.theming.Themes;
|
||||||
|
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
import javax.enterprise.inject.Specializes;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extends the default configuration for Freemarker of Eclipse Krazo to
|
||||||
|
* support Freemarker templates in CCM themes.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@ApplicationScoped
|
||||||
|
public class MvcFreemarkerConfigurationProducer
|
||||||
|
extends DefaultConfigurationProducer {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ServletContext servletContext;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Themes themes;
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
@ViewEngineConfig
|
||||||
|
@Specializes
|
||||||
|
@Override
|
||||||
|
public Configuration getConfiguration() {
|
||||||
|
final Configuration configuration = new Configuration(
|
||||||
|
Configuration.VERSION_2_3_30
|
||||||
|
);
|
||||||
|
|
||||||
|
configuration.setDefaultEncoding("UTF-8");
|
||||||
|
configuration.setTemplateExceptionHandler(
|
||||||
|
TemplateExceptionHandler.RETHROW_HANDLER
|
||||||
|
);
|
||||||
|
configuration.setLogTemplateExceptions(false);
|
||||||
|
configuration.setWrapUncheckedExceptions(false);
|
||||||
|
configuration.setLocalizedLookup(false);
|
||||||
|
configuration.setTemplateLoader(
|
||||||
|
new MultiTemplateLoader(
|
||||||
|
new TemplateLoader[]{
|
||||||
|
new KrazoTemplateLoader(servletContext),
|
||||||
|
new ThemesTemplateLoader(themes),
|
||||||
|
// For loading Freemarker macro libraries from WEB-INF
|
||||||
|
// resources
|
||||||
|
new WebappTemplateLoader(
|
||||||
|
servletContext, "/themes/freemarker"
|
||||||
|
),
|
||||||
|
// For loading Freemarker macro libraries from classpath
|
||||||
|
// resources
|
||||||
|
new ClassTemplateLoader(getClass(), "/themes/freemarker")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.libreccm.mvc.freemarker;
|
||||||
|
|
||||||
|
import freemarker.cache.TemplateLoader;
|
||||||
|
import org.libreccm.theming.ThemeInfo;
|
||||||
|
import org.libreccm.theming.ThemeVersion;
|
||||||
|
import org.libreccm.theming.Themes;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads Freemarker templates from a theme.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class ThemesTemplateLoader implements TemplateLoader {
|
||||||
|
|
||||||
|
private final Themes themes;
|
||||||
|
|
||||||
|
public ThemesTemplateLoader(final Themes themes) {
|
||||||
|
this.themes = themes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the template from a theme. The path of the theme file must follow
|
||||||
|
* the following format:
|
||||||
|
*
|
||||||
|
* {@code @themes/$themeName/$version/$path/$to/$file}
|
||||||
|
*
|
||||||
|
* The {@code @themes} prefix is mandantory. {@code $themeName} is the name
|
||||||
|
* of the theme from which the template is loaded. {@code $version} is the
|
||||||
|
* version of the theme to use. This token is converted to
|
||||||
|
* {@link ThemeVersion}. Valid values are therefore {@code DRAFT} and
|
||||||
|
* {@code LIVE}. The remainder of the path is the path to the file inside the
|
||||||
|
* theme.
|
||||||
|
*
|
||||||
|
* @param path The path of the file. The path must include the theme and its
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
* @return An {@link InputStream} for the template if the template was found
|
||||||
|
* in the theme. Otherwise {@code null} is returned.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object findTemplateSource(final String path) throws IOException {
|
||||||
|
if (path.startsWith("@themes") || path.startsWith("/@themes")) {
|
||||||
|
final String[] tokens;
|
||||||
|
if (path.startsWith("/")) {
|
||||||
|
tokens = path.substring(1).split("/");
|
||||||
|
} else {
|
||||||
|
tokens = path.split("/");
|
||||||
|
}
|
||||||
|
return findTemplateSource(tokens);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputStream findTemplateSource(final String[] tokens) {
|
||||||
|
if (tokens.length >= 4) {
|
||||||
|
final String themeName = tokens[1];
|
||||||
|
final ThemeVersion themeVersion = ThemeVersion
|
||||||
|
.valueOf(tokens[2]);
|
||||||
|
final String filePath = String.join(
|
||||||
|
"/",
|
||||||
|
Arrays.copyOfRange(
|
||||||
|
tokens, 3, tokens.length, String[].class
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return findTemplateSource(themeName, themeVersion, filePath);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputStream findTemplateSource(
|
||||||
|
final String themeName,
|
||||||
|
final ThemeVersion themeVersion,
|
||||||
|
final String filePath
|
||||||
|
) {
|
||||||
|
final Optional<ThemeInfo> themeInfo = themes.getTheme(
|
||||||
|
themeName, themeVersion
|
||||||
|
);
|
||||||
|
if (themeInfo.isPresent()) {
|
||||||
|
return findTemplateSource(themeInfo.get(), filePath);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputStream findTemplateSource(
|
||||||
|
final ThemeInfo themeInfo, final String filePath
|
||||||
|
) {
|
||||||
|
final Optional<InputStream> source = themes.getFileFromTheme(
|
||||||
|
themeInfo, filePath
|
||||||
|
);
|
||||||
|
if (source.isPresent()) {
|
||||||
|
return source.get();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLastModified(Object templateSource) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Reader getReader(
|
||||||
|
final Object templateSource, final String encoding
|
||||||
|
) throws IOException {
|
||||||
|
final InputStream inputStream = (InputStream) templateSource;
|
||||||
|
return new InputStreamReader(inputStream, encoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeTemplateSource(
|
||||||
|
final Object templateSource
|
||||||
|
) throws IOException {
|
||||||
|
final InputStream inputStream = (InputStream) templateSource;
|
||||||
|
inputStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Integration of the Freemarker View Engine of Eclipse Krazo with LibreCCM.
|
||||||
|
*/
|
||||||
|
package org.libreccm.mvc.freemarker;
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* The classes in this package integrate LibreCCM with Jakarta EE MVC and its
|
||||||
|
* reference implementation Eclipse Krazo.
|
||||||
|
*
|
||||||
|
* @see https://www.mvc-spec.org/
|
||||||
|
*/
|
||||||
|
package org.libreccm.mvc;
|
||||||
Loading…
Reference in New Issue