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