Allow sub-directories for icons (#2946)

* Allow sub-directories for icons

Signed-off-by: Jan N. Klug <github@klug.nrw>
This commit is contained in:
J-N-K 2022-05-16 22:33:32 +02:00 committed by GitHub
parent d4a68c83fe
commit d8ebbb5857
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 18 deletions

View File

@ -12,13 +12,14 @@
*/
package org.openhab.core.ui.icon.internal;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
@ -46,19 +47,23 @@ public class CustomIconProvider extends AbstractResourceIconProvider {
super(i18nProvider);
}
private @Nullable File getIconFile(String filename, String iconSetId) {
File folder = new File(OpenHAB.getConfigFolder() + File.separator + "icons" + File.separator + iconSetId);
File file = new File(folder, filename);
return file.exists() ? file : null;
private @Nullable Path getIconFile(String filename, String iconSetId) {
Path folder = Path.of(OpenHAB.getConfigFolder(), "icons", iconSetId);
try (Stream<Path> stream = Files.walk(folder)) {
return stream.filter(file -> !Files.isDirectory(file) && filename.equals(file.getFileName().toString()))
.findAny().orElse(null);
} catch (IOException e) {
return null;
}
}
@Override
protected @Nullable InputStream getResource(String iconSetId, String resourceName) {
File file = getIconFile(resourceName, iconSetId);
Path file = getIconFile(resourceName, iconSetId);
if (file != null) {
try {
return new FileInputStream(file);
} catch (FileNotFoundException e) {
return Files.newInputStream(file);
} catch (IOException e) {
return null;
}
}

View File

@ -108,6 +108,12 @@ public class IconServlet extends OpenHABServlet {
}
String category = getCategory(req);
if (category.isEmpty()) {
logger.debug("URI must start with '{}' but is '{}'", SERVLET_NAME, req.getRequestURI());
resp.sendError(400);
return;
}
String state = getState(req);
String iconSetId = getIconSetId(req);

View File

@ -96,7 +96,7 @@ public class IconServletTest {
@Test
public void testOldUrlStyle() throws ServletException, IOException {
when(requestMock.getRequestURI()).thenReturn("/y-34.png");
when(requestMock.getRequestURI()).thenReturn("/icon/y-34.png");
when(responseMock.getOutputStream()).thenReturn(responseOutputStream);
@ -113,7 +113,7 @@ public class IconServletTest {
@Test
public void testPriority() throws ServletException, IOException {
when(requestMock.getRequestURI()).thenReturn("/x");
when(requestMock.getRequestURI()).thenReturn("/icon/x");
when(requestMock.getParameter(PARAM_FORMAT)).thenReturn("svg");
when(requestMock.getParameter(PARAM_ICONSET)).thenReturn("test");
when(requestMock.getParameter(PARAM_STATE)).thenReturn("34");
@ -158,7 +158,7 @@ public class IconServletTest {
@Test
public void testAnyFormatFalse() throws ServletException, IOException {
when(requestMock.getRequestURI()).thenReturn("/z");
when(requestMock.getRequestURI()).thenReturn("/icon/z");
when(requestMock.getParameter(PARAM_FORMAT)).thenReturn("svg");
when(requestMock.getParameter(PARAM_ANY_FORMAT)).thenReturn("false");
when(requestMock.getParameter(PARAM_ICONSET)).thenReturn("test");
@ -180,7 +180,7 @@ public class IconServletTest {
@Test
public void testAnyFormatSameProviders() throws ServletException, IOException {
when(requestMock.getRequestURI()).thenReturn("/z");
when(requestMock.getRequestURI()).thenReturn("/icon/z");
when(requestMock.getParameter(PARAM_FORMAT)).thenReturn("svg");
when(requestMock.getParameter(PARAM_ANY_FORMAT)).thenReturn("true");
when(requestMock.getParameter(PARAM_ICONSET)).thenReturn("test");
@ -204,7 +204,7 @@ public class IconServletTest {
@Test
public void testAnyFormatHigherPriorityOtherFormat() throws ServletException, IOException {
when(requestMock.getRequestURI()).thenReturn("/z");
when(requestMock.getRequestURI()).thenReturn("/icon/z");
when(requestMock.getParameter(PARAM_FORMAT)).thenReturn("svg");
when(requestMock.getParameter(PARAM_ANY_FORMAT)).thenReturn("true");
when(requestMock.getParameter(PARAM_ICONSET)).thenReturn("test");
@ -234,7 +234,7 @@ public class IconServletTest {
@Test
public void testAnyFormatHigherPriorityRequestedFormat() throws ServletException, IOException {
when(requestMock.getRequestURI()).thenReturn("/z");
when(requestMock.getRequestURI()).thenReturn("/icon/z");
when(requestMock.getParameter(PARAM_FORMAT)).thenReturn("svg");
when(requestMock.getParameter(PARAM_ANY_FORMAT)).thenReturn("true");
when(requestMock.getParameter(PARAM_ICONSET)).thenReturn("test");
@ -264,7 +264,7 @@ public class IconServletTest {
@Test
public void testAnyFormatNoOtherFormat() throws ServletException, IOException {
when(requestMock.getRequestURI()).thenReturn("/z");
when(requestMock.getRequestURI()).thenReturn("/icon/z");
when(requestMock.getParameter(PARAM_FORMAT)).thenReturn("svg");
when(requestMock.getParameter(PARAM_ANY_FORMAT)).thenReturn("true");
when(requestMock.getParameter(PARAM_ICONSET)).thenReturn("test");
@ -288,7 +288,7 @@ public class IconServletTest {
@Test
public void testAnyFormatNoRequestedFormat() throws ServletException, IOException {
when(requestMock.getRequestURI()).thenReturn("/z");
when(requestMock.getRequestURI()).thenReturn("/icon/z");
when(requestMock.getParameter(PARAM_FORMAT)).thenReturn("svg");
when(requestMock.getParameter(PARAM_ANY_FORMAT)).thenReturn("true");
when(requestMock.getParameter(PARAM_ICONSET)).thenReturn("test");