parent
dfc66b56a6
commit
ed15e4d16e
|
|
@ -34,6 +34,9 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
import static org.libreccm.theming.ThemeConstants.*;
|
import static org.libreccm.theming.ThemeConstants.*;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Each theme contains a Manifest (either in XML or JSON format) which provides
|
* Each theme contains a Manifest (either in XML or JSON format) which provides
|
||||||
|
|
@ -88,8 +91,13 @@ public class ThemeManifest implements Serializable {
|
||||||
@XmlElement(name = "default-template", namespace = THEMES_XML_NS)
|
@XmlElement(name = "default-template", namespace = THEMES_XML_NS)
|
||||||
private String defaultTemplate;
|
private String defaultTemplate;
|
||||||
|
|
||||||
|
@XmlElementWrapper(name = "mvcTemplates", namespace = THEMES_XML_NS)
|
||||||
|
@XmlElement(name = "template", namespace = THEME_MANIFEST_XML)
|
||||||
|
private Map<String, Map<String, ThemeTemplate>> mvcTemplates;
|
||||||
|
|
||||||
public ThemeManifest() {
|
public ThemeManifest() {
|
||||||
templates = new ArrayList<>();
|
templates = new ArrayList<>();
|
||||||
|
mvcTemplates = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
|
@ -156,6 +164,65 @@ public class ThemeManifest implements Serializable {
|
||||||
this.defaultTemplate = defaultTemplate;
|
this.defaultTemplate = defaultTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, Map<String, ThemeTemplate>> getMvcTemplates() {
|
||||||
|
return Collections.unmodifiableMap(mvcTemplates);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Map<String, ThemeTemplate>> getMvcTemplatesOfCategory(
|
||||||
|
final String category
|
||||||
|
) {
|
||||||
|
return Optional.ofNullable(mvcTemplates.get(category));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMvcTemplatesCategory(final String category) {
|
||||||
|
mvcTemplates.put(category, new HashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMvcTemplatesCategory(
|
||||||
|
final String category, final Map<String, ThemeTemplate> templates
|
||||||
|
) {
|
||||||
|
mvcTemplates.put(category, templates);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<ThemeTemplate> getMvcTemplate(
|
||||||
|
final String category, final String objectType
|
||||||
|
) {
|
||||||
|
final Optional<Map<String, ThemeTemplate>> templatesInCat
|
||||||
|
= getMvcTemplatesOfCategory(category);
|
||||||
|
|
||||||
|
if (templatesInCat.isPresent()) {
|
||||||
|
return Optional.ofNullable(templatesInCat.get().get(objectType));
|
||||||
|
} else {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMvcTemplate(
|
||||||
|
final String category,
|
||||||
|
final String objectType,
|
||||||
|
final ThemeTemplate template
|
||||||
|
) {
|
||||||
|
if (!mvcTemplates.containsKey(category)) {
|
||||||
|
addMvcTemplatesCategory(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
mvcTemplates
|
||||||
|
.get(category)
|
||||||
|
.put(
|
||||||
|
objectType,
|
||||||
|
Objects.requireNonNull(
|
||||||
|
template,
|
||||||
|
"Template can't be null."
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setMvcTemplates(
|
||||||
|
final Map<String, Map<String, ThemeTemplate>> mvcTemplates
|
||||||
|
) {
|
||||||
|
this.mvcTemplates = mvcTemplates;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = 7;
|
int hash = 7;
|
||||||
|
|
@ -166,6 +233,7 @@ public class ThemeManifest implements Serializable {
|
||||||
hash = 83 * hash + Objects.hashCode(description);
|
hash = 83 * hash + Objects.hashCode(description);
|
||||||
hash = 83 * hash + Objects.hashCode(templates);
|
hash = 83 * hash + Objects.hashCode(templates);
|
||||||
hash = 83 * hash + Objects.hashCode(defaultTemplate);
|
hash = 83 * hash + Objects.hashCode(defaultTemplate);
|
||||||
|
hash = 83 * hash + Objects.hashCode(mvcTemplates);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,7 +270,10 @@ public class ThemeManifest implements Serializable {
|
||||||
if (!Objects.equals(templates, other.getTemplates())) {
|
if (!Objects.equals(templates, other.getTemplates())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return Objects.equals(defaultTemplate, other.getDefaultTemplate());
|
if (!Objects.equals(defaultTemplate, other.getDefaultTemplate())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return mvcTemplates.equals(other.getMvcTemplates());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canEqual(final Object obj) {
|
public boolean canEqual(final Object obj) {
|
||||||
|
|
@ -216,14 +287,16 @@ public class ThemeManifest implements Serializable {
|
||||||
|
|
||||||
public String toString(final String data) {
|
public String toString(final String data) {
|
||||||
|
|
||||||
return String.format("%s{ "
|
return String.format(
|
||||||
|
"%s{ "
|
||||||
+ "name = \"%s\", "
|
+ "name = \"%s\", "
|
||||||
+ "type = \"%s\", "
|
+ "type = \"%s\", "
|
||||||
+ "masterTheme = \"%s\", "
|
+ "masterTheme = \"%s\", "
|
||||||
+ "title = \"%s\", "
|
+ "title = \"%s\", "
|
||||||
+ "description = \"%s\", "
|
+ "description = \"%s\", "
|
||||||
+ "templates = %s, "
|
+ "templates = %s, "
|
||||||
+ "defaultTemplate%s"
|
+ "defaultTemplate, "
|
||||||
|
+ "mvcTemplates = %s%s"
|
||||||
+ " }",
|
+ " }",
|
||||||
super.toString(),
|
super.toString(),
|
||||||
name,
|
name,
|
||||||
|
|
@ -233,7 +306,9 @@ public class ThemeManifest implements Serializable {
|
||||||
Objects.toString(description),
|
Objects.toString(description),
|
||||||
Objects.toString(templates),
|
Objects.toString(templates),
|
||||||
defaultTemplate,
|
defaultTemplate,
|
||||||
data);
|
Objects.toString(mvcTemplates),
|
||||||
|
data
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.theming.manifest;
|
package org.libreccm.theming.manifest;
|
||||||
|
|
||||||
import static org.libreccm.theming.ThemeConstants.*;
|
import static org.libreccm.theming.ThemeConstants.THEME_MANIFEST_JSON;
|
||||||
|
import static org.libreccm.theming.ThemeConstants.THEME_MANIFEST_XML;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
|
@ -60,8 +61,6 @@ public class ThemeManifestUtil implements Serializable {
|
||||||
* @return The parsed manifest file.
|
* @return The parsed manifest file.
|
||||||
*/
|
*/
|
||||||
public ThemeManifest loadManifest(final Path path) {
|
public ThemeManifest loadManifest(final Path path) {
|
||||||
|
|
||||||
// final String pathStr = path.toString().toLowerCase(Locale.ROOT);
|
|
||||||
final BufferedReader reader;
|
final BufferedReader reader;
|
||||||
try {
|
try {
|
||||||
reader = Files.newBufferedReader(path, Charset.forName("UTF-8"));
|
reader = Files.newBufferedReader(path, Charset.forName("UTF-8"));
|
||||||
|
|
@ -70,34 +69,11 @@ public class ThemeManifestUtil implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseManifest(reader, path.toString());
|
return parseManifest(reader, path.toString());
|
||||||
|
|
||||||
// final ObjectMapper mapper;
|
|
||||||
// if (pathStr.endsWith(THEME_MANIFEST_JSON)) {
|
|
||||||
// mapper = new ObjectMapper();
|
|
||||||
// } else if (pathStr.endsWith(THEME_MANIFEST_XML)) {
|
|
||||||
// final JacksonXmlModule xmlModule = new JacksonXmlModule();
|
|
||||||
// mapper = new XmlMapper(xmlModule);
|
|
||||||
// } else {
|
|
||||||
// throw new IllegalArgumentException(String
|
|
||||||
// .format("The provided path \"%s\" does not point to a theme "
|
|
||||||
// + "manifest file.",
|
|
||||||
// path.toString()));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// mapper.registerModule(new JaxbAnnotationModule());
|
|
||||||
//
|
|
||||||
// final ThemeManifest manifest;
|
|
||||||
// try {
|
|
||||||
// manifest = mapper.readValue(reader, ThemeManifest.class);
|
|
||||||
// } catch (IOException ex) {
|
|
||||||
// throw new UnexpectedErrorException(ex);
|
|
||||||
// }
|
|
||||||
// return manifest;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ThemeManifest loadManifest(final InputStream inputStream,
|
public ThemeManifest loadManifest(
|
||||||
final String fileName) {
|
final InputStream inputStream, final String fileName
|
||||||
|
) {
|
||||||
final InputStreamReader reader;
|
final InputStreamReader reader;
|
||||||
try {
|
try {
|
||||||
reader = new InputStreamReader(inputStream, "UTF-8");
|
reader = new InputStreamReader(inputStream, "UTF-8");
|
||||||
|
|
@ -106,34 +82,11 @@ public class ThemeManifestUtil implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseManifest(reader, fileName);
|
return parseManifest(reader, fileName);
|
||||||
|
|
||||||
// final ObjectMapper mapper;
|
|
||||||
// if (fileName.endsWith(THEME_MANIFEST_JSON)) {
|
|
||||||
// mapper = new ObjectMapper();
|
|
||||||
// } else if (fileName.endsWith(THEME_MANIFEST_XML)) {
|
|
||||||
// final JacksonXmlModule xmlModule = new JacksonXmlModule();
|
|
||||||
// mapper = new XmlMapper(xmlModule);
|
|
||||||
// } else {
|
|
||||||
// throw new IllegalArgumentException(String
|
|
||||||
// .format("The provided path \"%s\" does not point to a theme "
|
|
||||||
// + "manifest file.",
|
|
||||||
// fileName));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// mapper.registerModule(new JaxbAnnotationModule());
|
|
||||||
//
|
|
||||||
// final ThemeManifest manifest;
|
|
||||||
// try {
|
|
||||||
// manifest = mapper.readValue(reader, ThemeManifest.class);
|
|
||||||
// } catch (IOException ex) {
|
|
||||||
// throw new UnexpectedErrorException(ex);
|
|
||||||
// }
|
|
||||||
// return manifest;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String serializeManifest(final ThemeManifest manifest,
|
public String serializeManifest(
|
||||||
final String format) {
|
final ThemeManifest manifest, final String format
|
||||||
|
) {
|
||||||
final ObjectMapper mapper;
|
final ObjectMapper mapper;
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,179 @@
|
||||||
|
/*
|
||||||
|
* 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.theming.mvc;
|
||||||
|
|
||||||
|
import org.libreccm.sites.Site;
|
||||||
|
import org.libreccm.sites.SiteRepository;
|
||||||
|
import org.libreccm.theming.ThemeInfo;
|
||||||
|
import org.libreccm.theming.ThemeVersion;
|
||||||
|
import org.libreccm.theming.Themes;
|
||||||
|
import org.libreccm.theming.manifest.ThemeManifest;
|
||||||
|
import org.libreccm.theming.manifest.ThemeTemplate;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
public class ThemesMvc {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SiteRepository siteRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Themes themes;
|
||||||
|
|
||||||
|
public String getMvcTemplate(
|
||||||
|
final UriInfo uriInfo,
|
||||||
|
final String application
|
||||||
|
) {
|
||||||
|
final Site site = getSite(uriInfo);
|
||||||
|
final String theme = parseThemeParam(uriInfo);
|
||||||
|
final ThemeVersion themeVersion = parsePreviewParam(uriInfo);
|
||||||
|
final ThemeInfo themeInfo = getTheme(
|
||||||
|
site,
|
||||||
|
theme,
|
||||||
|
themeVersion
|
||||||
|
);
|
||||||
|
final ThemeManifest manifest = themeInfo.getManifest();
|
||||||
|
final Map<String, ThemeTemplate> applicationTemplates = manifest
|
||||||
|
.getMvcTemplatesOfCategory("applications")
|
||||||
|
.orElseThrow(
|
||||||
|
() -> new WebApplicationException(
|
||||||
|
String.format(
|
||||||
|
"Manifest of theme %s has no application templates.",
|
||||||
|
themeInfo.getName()
|
||||||
|
),
|
||||||
|
Response.Status.INTERNAL_SERVER_ERROR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
final ThemeTemplate themeTemplate;
|
||||||
|
if (applicationTemplates.containsKey(application)) {
|
||||||
|
themeTemplate = applicationTemplates.get(application);
|
||||||
|
} else {
|
||||||
|
themeTemplate = Optional.ofNullable(
|
||||||
|
applicationTemplates.get("@default")
|
||||||
|
).orElseThrow(
|
||||||
|
() -> new WebApplicationException(
|
||||||
|
String.format(
|
||||||
|
"Theme %s does not provide a template for application "
|
||||||
|
+ "%s and has not default template for "
|
||||||
|
+ "applications.",
|
||||||
|
theme,
|
||||||
|
application
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.format(
|
||||||
|
"@themes/%s/%s/%s",
|
||||||
|
theme,
|
||||||
|
Objects.toString(themeVersion),
|
||||||
|
themeTemplate.getPath()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Site getSite(final UriInfo uriInfo) {
|
||||||
|
Objects.requireNonNull(uriInfo);
|
||||||
|
|
||||||
|
final String domain = uriInfo.getBaseUri().getHost();
|
||||||
|
|
||||||
|
final Site site;
|
||||||
|
if (siteRepo.hasSiteForDomain(domain)) {
|
||||||
|
site = siteRepo.findByDomain(domain).get();
|
||||||
|
} else {
|
||||||
|
site = siteRepo
|
||||||
|
.findDefaultSite()
|
||||||
|
.orElseThrow(() -> new NotFoundException(
|
||||||
|
"No matching Site and no default Site."));
|
||||||
|
}
|
||||||
|
|
||||||
|
return site;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ThemeInfo getTheme(
|
||||||
|
final Site site,
|
||||||
|
final String theme,
|
||||||
|
final ThemeVersion themeVersion) {
|
||||||
|
if ("--DEFAULT--".equals(theme)) {
|
||||||
|
return themes
|
||||||
|
.getTheme(site.getDefaultTheme(), themeVersion)
|
||||||
|
.orElseThrow(
|
||||||
|
() -> new WebApplicationException(
|
||||||
|
String.format(
|
||||||
|
"The configured default theme \"%s\" for "
|
||||||
|
+ "site \"%s\" is not available.",
|
||||||
|
site.getDefaultTheme(),
|
||||||
|
site.getDomainOfSite()
|
||||||
|
),
|
||||||
|
Response.Status.INTERNAL_SERVER_ERROR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return themes
|
||||||
|
.getTheme(theme, themeVersion)
|
||||||
|
.orElseThrow(
|
||||||
|
() -> new WebApplicationException(
|
||||||
|
String.format(
|
||||||
|
"The theme \"%s\" is not available.",
|
||||||
|
theme
|
||||||
|
),
|
||||||
|
Response.Status.BAD_REQUEST
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseThemeParam(final UriInfo uriInfo) {
|
||||||
|
if (uriInfo.getQueryParameters().containsKey("theme")) {
|
||||||
|
return uriInfo.getQueryParameters().getFirst("theme");
|
||||||
|
} else {
|
||||||
|
return "--DEFAULT--";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ThemeVersion parsePreviewParam(final UriInfo uriInfo) {
|
||||||
|
if (uriInfo.getQueryParameters().containsKey("preview")) {
|
||||||
|
final List<String> values = uriInfo
|
||||||
|
.getQueryParameters()
|
||||||
|
.get("preview");
|
||||||
|
if (values.contains("theme") || values.contains("all")) {
|
||||||
|
return ThemeVersion.DRAFT;
|
||||||
|
} else {
|
||||||
|
return ThemeVersion.LIVE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ThemeVersion.LIVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue