diff --git a/ccm-core/src/main/java/com/arsdigita/categorization/ui/ACSObjectCategoryController.java b/ccm-core/src/main/java/com/arsdigita/categorization/ui/ACSObjectCategoryController.java index f46b6cbe4..93de15253 100644 --- a/ccm-core/src/main/java/com/arsdigita/categorization/ui/ACSObjectCategoryController.java +++ b/ccm-core/src/main/java/com/arsdigita/categorization/ui/ACSObjectCategoryController.java @@ -27,6 +27,7 @@ import org.libreccm.core.CcmObjectRepository; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; import javax.enterprise.context.RequestScoped; @@ -42,10 +43,10 @@ class ACSObjectCategoryController { @Inject private CategoryRepository categoryRepo; - + @Inject private CategoryManager categoryManager; - + @Inject private CcmObjectRepository ccmObjectRepo; @@ -81,19 +82,19 @@ class ACSObjectCategoryController { object.getObjectId()))); final Category cat = categoryRepo - .findById(category.getObjectId()) - .orElseThrow(() -> new IllegalArgumentException(String + .findById(category.getObjectId()) + .orElseThrow(() -> new IllegalArgumentException(String .format("No Category with ID %d in the database.", category.getObjectId()))); - + categoryManager.addObjectToCategory(ccmObject, cat); } - + @Transactional(Transactional.TxType.REQUIRED) protected void removeObjectFromCategory(final CcmObject object, - final Category category) + final Category category) throws ObjectNotAssignedToCategoryException { - + Objects.requireNonNull(object); Objects.requireNonNull(category); @@ -104,12 +105,24 @@ class ACSObjectCategoryController { object.getObjectId()))); final Category cat = categoryRepo - .findById(category.getObjectId()) - .orElseThrow(() -> new IllegalArgumentException(String + .findById(category.getObjectId()) + .orElseThrow(() -> new IllegalArgumentException(String .format("No Category with ID %d in the database.", category.getObjectId()))); - + categoryManager.removeObjectFromCategory(ccmObject, cat); } + @Transactional(Transactional.TxType.REQUIRED) + protected long getParentCategoryId(final Category forCategory) { + + final Category category = categoryRepo + .findById(forCategory.getObjectId()) + .orElseThrow(() -> new IllegalArgumentException(String + .format("No Category with ID %d in the database.", + forCategory.getObjectId()))); + + return category.getParentCategory().getObjectId(); + } + } diff --git a/ccm-core/src/main/java/com/arsdigita/categorization/ui/ACSObjectCategoryForm.java b/ccm-core/src/main/java/com/arsdigita/categorization/ui/ACSObjectCategoryForm.java index fce1594a9..3827f3dd6 100755 --- a/ccm-core/src/main/java/com/arsdigita/categorization/ui/ACSObjectCategoryForm.java +++ b/ccm-core/src/main/java/com/arsdigita/categorization/ui/ACSObjectCategoryForm.java @@ -194,7 +194,11 @@ public abstract class ACSObjectCategoryForm extends Form { final Category category) { if (category.getParentCategory() != null) { - ancestorCats.add(category.getParentCategory().getObjectId()); + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final ACSObjectCategoryController controller = cdiUtil + .findBean(ACSObjectCategoryController.class); + ancestorCats + .add(controller.getParentCategoryId(category)); } } diff --git a/ccm-core/src/main/java/org/libreccm/theming/ThemeFiles.java b/ccm-core/src/main/java/org/libreccm/theming/ThemeFiles.java new file mode 100644 index 000000000..a840aa5ff --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/theming/ThemeFiles.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2018 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; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.ws.rs.GET; +import javax.ws.rs.NotFoundException; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Path("/{theme}") +public class ThemeFiles { + + @Inject + private Themes themes; + + @GET + @Path("/{path}") + public Response getFile(@PathParam("theme") final String theme, + @PathParam("path") final String path) { + + final ThemeInfo info = themes + .getTheme(theme, ThemeVersion.LIVE) + .orElseThrow(() -> new NotFoundException(String + .format("Theme \"%s\" does not exist.", theme))); + + final InputStream inputStream = themes + .getFileFromTheme(info, path) + .orElseThrow(() -> new NotFoundException(String + .format("The file \"%s\" does exist in the theme \"%s\".", + path, + theme))); + + final MediaType mediaType = getMediaTypeFromPath(path); + + final BufferedReader reader = new BufferedReader( + new InputStreamReader(inputStream)); + final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try { + int value = reader.read(); + while (value != -1) { + outputStream.write(value); + value = reader.read(); + } + } catch (IOException ex) { + throw new WebApplicationException(ex); + } + + final byte[] data = outputStream.toByteArray(); + return Response.ok(data, mediaType).build(); + } + + private MediaType getMediaTypeFromPath(final String path) { + + if (path.endsWith(".css")) { + return new MediaType("text", "css"); + } else { + return MediaType.WILDCARD_TYPE; + } + + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/theming/Themes.java b/ccm-core/src/main/java/org/libreccm/theming/Themes.java index d4d0a1b7c..e4cf7c0f8 100644 --- a/ccm-core/src/main/java/org/libreccm/theming/Themes.java +++ b/ccm-core/src/main/java/org/libreccm/theming/Themes.java @@ -23,6 +23,7 @@ import org.apache.logging.log4j.Logger; import org.libreccm.core.UnexpectedErrorException; import org.libreccm.pagemodel.PageModel; +import java.io.InputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -144,4 +145,36 @@ public class Themes implements Serializable { return processor.process(page, theme, provider); } + /** + * Retrieve a file from a theme using the {@link ThemeProvider} for the + * theme. + * + * @param theme The theme from which the file is retrieved. + * @param path The path of the file relative to the root directory of the + * theme. + * + * @return An {@link Optional} containing an {@link InputStream} for reading + * the contents of the file or an empty {@link Optional} if the file + * was not found. + */ + public Optional getFileFromTheme(final ThemeInfo theme, + final String path) { + + final Instance forTheme = providers.select( + theme.getProvider()); + + if (forTheme.isUnsatisfied()) { + LOGGER.error("ThemeProvider \"{}\" not found.", + theme.getProvider().getName()); + throw new UnexpectedErrorException(String.format( + "ThemeProvider \"%s\" not found.", + theme.getProvider().getName())); + } + + final ThemeProvider provider = forTheme.get(); + return provider.getThemeFileAsStream(theme.getName(), + theme.getVersion(), + path); + } + } diff --git a/ccm-core/src/main/java/org/libreccm/theming/ThemesService.java b/ccm-core/src/main/java/org/libreccm/theming/ThemesService.java new file mode 100644 index 000000000..20a178880 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/theming/ThemesService.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2018 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; + +import java.util.HashSet; +import java.util.Set; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; + +/** + * + * @author Jens Pelzetter + */ +@ApplicationPath("/theming") +public class ThemesService extends Application { + + @Override + public Set> getClasses() { + + final Set> classes = new HashSet<>(); + classes.add(ThemeFiles.class); + + return classes; + } + +} diff --git a/ccm-core/src/main/resources/themes/ccm/category-page.xsl b/ccm-core/src/main/resources/themes/ccm/category-page.xsl index 58b5afc58..1da2b8e4d 100644 --- a/ccm-core/src/main/resources/themes/ccm/category-page.xsl +++ b/ccm-core/src/main/resources/themes/ccm/category-page.xsl @@ -4,31 +4,36 @@ xmlns:ccm="http://xmlns.libreccm.org" exclude-result-prefixes="ccm xsl"> - + Category page - +
    - -
    -                                    
    -                                
    - -
    - - - +
  • + + + + + + + +
@@ -38,7 +43,7 @@

- +