parent
dfc66b56a6
commit
ed15e4d16e
|
|
@ -34,6 +34,9 @@ import javax.xml.bind.annotation.XmlRootElement;
|
|||
import static org.libreccm.theming.ThemeConstants.*;
|
||||
|
||||
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
|
||||
|
|
@ -88,8 +91,13 @@ public class ThemeManifest implements Serializable {
|
|||
@XmlElement(name = "default-template", namespace = THEMES_XML_NS)
|
||||
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() {
|
||||
templates = new ArrayList<>();
|
||||
mvcTemplates = new HashMap<>();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
|
@ -156,6 +164,65 @@ public class ThemeManifest implements Serializable {
|
|||
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
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
|
|
@ -166,6 +233,7 @@ public class ThemeManifest implements Serializable {
|
|||
hash = 83 * hash + Objects.hashCode(description);
|
||||
hash = 83 * hash + Objects.hashCode(templates);
|
||||
hash = 83 * hash + Objects.hashCode(defaultTemplate);
|
||||
hash = 83 * hash + Objects.hashCode(mvcTemplates);
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
|
@ -202,7 +270,10 @@ public class ThemeManifest implements Serializable {
|
|||
if (!Objects.equals(templates, other.getTemplates())) {
|
||||
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) {
|
||||
|
|
@ -216,24 +287,28 @@ public class ThemeManifest implements Serializable {
|
|||
|
||||
public String toString(final String data) {
|
||||
|
||||
return String.format("%s{ "
|
||||
+ "name = \"%s\", "
|
||||
+ "type = \"%s\", "
|
||||
+ "masterTheme = \"%s\", "
|
||||
+ "title = \"%s\", "
|
||||
+ "description = \"%s\", "
|
||||
+ "templates = %s, "
|
||||
+ "defaultTemplate%s"
|
||||
+ " }",
|
||||
super.toString(),
|
||||
name,
|
||||
type,
|
||||
masterTheme,
|
||||
Objects.toString(title),
|
||||
Objects.toString(description),
|
||||
Objects.toString(templates),
|
||||
defaultTemplate,
|
||||
data);
|
||||
return String.format(
|
||||
"%s{ "
|
||||
+ "name = \"%s\", "
|
||||
+ "type = \"%s\", "
|
||||
+ "masterTheme = \"%s\", "
|
||||
+ "title = \"%s\", "
|
||||
+ "description = \"%s\", "
|
||||
+ "templates = %s, "
|
||||
+ "defaultTemplate, "
|
||||
+ "mvcTemplates = %s%s"
|
||||
+ " }",
|
||||
super.toString(),
|
||||
name,
|
||||
type,
|
||||
masterTheme,
|
||||
Objects.toString(title),
|
||||
Objects.toString(description),
|
||||
Objects.toString(templates),
|
||||
defaultTemplate,
|
||||
Objects.toString(mvcTemplates),
|
||||
data
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@
|
|||
*/
|
||||
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.SerializationFeature;
|
||||
|
|
@ -60,8 +61,6 @@ public class ThemeManifestUtil implements Serializable {
|
|||
* @return The parsed manifest file.
|
||||
*/
|
||||
public ThemeManifest loadManifest(final Path path) {
|
||||
|
||||
// final String pathStr = path.toString().toLowerCase(Locale.ROOT);
|
||||
final BufferedReader reader;
|
||||
try {
|
||||
reader = Files.newBufferedReader(path, Charset.forName("UTF-8"));
|
||||
|
|
@ -70,34 +69,11 @@ public class ThemeManifestUtil implements Serializable {
|
|||
}
|
||||
|
||||
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,
|
||||
final String fileName) {
|
||||
|
||||
public ThemeManifest loadManifest(
|
||||
final InputStream inputStream, final String fileName
|
||||
) {
|
||||
final InputStreamReader reader;
|
||||
try {
|
||||
reader = new InputStreamReader(inputStream, "UTF-8");
|
||||
|
|
@ -106,34 +82,11 @@ public class ThemeManifestUtil implements Serializable {
|
|||
}
|
||||
|
||||
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,
|
||||
final String format) {
|
||||
|
||||
public String serializeManifest(
|
||||
final ThemeManifest manifest, final String format
|
||||
) {
|
||||
final ObjectMapper mapper;
|
||||
|
||||
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