1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.helper;
17
18 import java.io.IOException;
19 import java.nio.file.FileVisitOption;
20 import java.nio.file.Files;
21 import java.nio.file.Path;
22 import java.nio.file.StandardCopyOption;
23 import java.util.Comparator;
24 import java.util.stream.Stream;
25 import java.util.zip.ZipEntry;
26 import java.util.zip.ZipInputStream;
27
28 import org.apache.logging.log4j.LogManager;
29 import org.apache.logging.log4j.Logger;
30 import org.codelibs.core.lang.StringUtil;
31 import org.codelibs.core.stream.StreamUtil;
32 import org.codelibs.fess.exception.ThemeException;
33 import org.codelibs.fess.helper.PluginHelper.Artifact;
34 import org.codelibs.fess.helper.PluginHelper.ArtifactType;
35 import org.codelibs.fess.util.ResourceUtil;
36
37 public class ThemeHelper {
38 private static final Logger logger = LogManager.getLogger(ThemeHelper.class);
39
40 public void install(final Artifact artifact) {
41 final Path jarPath = getJarFile(artifact);
42 final String themeName = getThemeName(artifact);
43 if (logger.isDebugEnabled()) {
44 logger.debug("Theme: {}", themeName);
45 }
46 try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(jarPath))) {
47 ZipEntry entry;
48 while ((entry = zis.getNextEntry()) != null) {
49 if (!entry.isDirectory()) {
50 final String[] names = StreamUtil.split(entry.getName(), "/")
51 .get(stream -> stream.filter(s -> !"..".equals(s)).toArray(n -> new String[n]));
52 if (names.length < 2) {
53 continue;
54 }
55 if (logger.isDebugEnabled()) {
56 logger.debug("Loading {}", entry.getName());
57 }
58 if ("view".equals(names[0])) {
59 names[0] = themeName;
60 final Path path = ResourceUtil.getViewTemplatePath(names);
61 Files.createDirectories(path.getParent());
62 Files.copy(zis, path, StandardCopyOption.REPLACE_EXISTING);
63 } else if ("css".equals(names[0])) {
64 names[0] = themeName;
65 final Path path = ResourceUtil.getCssPath(names);
66 Files.createDirectories(path.getParent());
67 Files.copy(zis, path, StandardCopyOption.REPLACE_EXISTING);
68 } else if ("js".equals(names[0])) {
69 names[0] = themeName;
70 final Path path = ResourceUtil.getJavaScriptPath(names);
71 Files.createDirectories(path.getParent());
72 Files.copy(zis, path, StandardCopyOption.REPLACE_EXISTING);
73 } else if ("images".equals(names[0])) {
74 names[0] = themeName;
75 final Path path = ResourceUtil.getImagePath(names);
76 Files.createDirectories(path.getParent());
77 Files.copy(zis, path, StandardCopyOption.REPLACE_EXISTING);
78 }
79 }
80 }
81 } catch (final IOException e) {
82 throw new ThemeException("Failed to install " + artifact, e);
83 }
84 }
85
86 public void uninstall(final Artifact artifact) {
87 final String themeName = getThemeName(artifact);
88
89 final Path viewPath = ResourceUtil.getViewTemplatePath(themeName);
90 closeQuietly(viewPath);
91 final Path imagePath = ResourceUtil.getImagePath(themeName);
92 closeQuietly(imagePath);
93 final Path cssPath = ResourceUtil.getCssPath(themeName);
94 closeQuietly(cssPath);
95 final Path jsPath = ResourceUtil.getJavaScriptPath(themeName);
96 closeQuietly(jsPath);
97 }
98
99 protected String getThemeName(final Artifact artifact) {
100 final String themeName = artifact.getName().substring(ArtifactType.THEME.getId().length() + 1);
101 if (StringUtil.isBlank(themeName)) {
102 throw new ThemeException("Theme name is empty: " + artifact);
103 }
104 return themeName;
105 }
106
107 protected void closeQuietly(final Path dir) {
108 if (Files.notExists(dir)) {
109 if (logger.isDebugEnabled()) {
110 logger.debug("{} does not exists.", dir);
111 }
112 return;
113 }
114 try (Stream<Path> walk = Files.walk(dir, FileVisitOption.FOLLOW_LINKS)) {
115 walk.sorted(Comparator.reverseOrder()).forEach(f -> {
116 if (logger.isDebugEnabled()) {
117 logger.debug("Deleting {}", f);
118 }
119 try {
120 Files.delete(f);
121 } catch (final IOException e) {
122 logger.warn("Failed to delete {}", f, e);
123 }
124 });
125 Files.deleteIfExists(dir);
126 } catch (final IOException e) {
127 logger.warn("Failed to delete {}", dir, e);
128 }
129 }
130
131 protected Path getJarFile(final Artifact artifact) {
132 final Path jarPath = ResourceUtil.getPluginPath(artifact.getFileName());
133 if (!Files.exists(jarPath)) {
134 throw new ThemeException(artifact.getFileName() + " does not exist.");
135 }
136 return jarPath;
137 }
138
139 }