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
38
39
40
41 public class ThemeHelper {
42 private static final Logger logger = LogManager.getLogger(ThemeHelper.class);
43
44
45
46
47 public ThemeHelper() {
48
49 }
50
51
52
53
54
55
56
57
58 public void install(final Artifact artifact) {
59 final Path jarPath = getJarFile(artifact);
60 final String themeName = getThemeName(artifact);
61 if (logger.isDebugEnabled()) {
62 logger.debug("Theme: name={}", themeName);
63 }
64 try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(jarPath))) {
65 ZipEntry entry;
66 while ((entry = zis.getNextEntry()) != null) {
67 if (!entry.isDirectory()) {
68 final String[] names = StreamUtil.split(entry.getName(), "/")
69 .get(stream -> stream.filter(s -> !"..".equals(s)).toArray(n -> new String[n]));
70 if (names.length < 2) {
71 continue;
72 }
73 if (logger.isDebugEnabled()) {
74 logger.debug("Loading entry: name={}", entry.getName());
75 }
76 if ("view".equals(names[0])) {
77 names[0] = themeName;
78 final Path path = ResourceUtil.getViewTemplatePath(names);
79 Files.createDirectories(path.getParent());
80 Files.copy(zis, path, StandardCopyOption.REPLACE_EXISTING);
81 } else if ("css".equals(names[0])) {
82 names[0] = themeName;
83 final Path path = ResourceUtil.getCssPath(names);
84 Files.createDirectories(path.getParent());
85 Files.copy(zis, path, StandardCopyOption.REPLACE_EXISTING);
86 } else if ("js".equals(names[0])) {
87 names[0] = themeName;
88 final Path path = ResourceUtil.getJavaScriptPath(names);
89 Files.createDirectories(path.getParent());
90 Files.copy(zis, path, StandardCopyOption.REPLACE_EXISTING);
91 } else if ("images".equals(names[0])) {
92 names[0] = themeName;
93 final Path path = ResourceUtil.getImagePath(names);
94 Files.createDirectories(path.getParent());
95 Files.copy(zis, path, StandardCopyOption.REPLACE_EXISTING);
96 }
97 }
98 }
99 } catch (final IOException e) {
100 throw new ThemeException("Failed to install " + artifact, e);
101 }
102 }
103
104
105
106
107
108
109 public void uninstall(final Artifact artifact) {
110 final String themeName = getThemeName(artifact);
111
112 final Path viewPath = ResourceUtil.getViewTemplatePath(themeName);
113 closeQuietly(viewPath);
114 final Path imagePath = ResourceUtil.getImagePath(themeName);
115 closeQuietly(imagePath);
116 final Path cssPath = ResourceUtil.getCssPath(themeName);
117 closeQuietly(cssPath);
118 final Path jsPath = ResourceUtil.getJavaScriptPath(themeName);
119 closeQuietly(jsPath);
120 }
121
122
123
124
125
126
127
128
129 protected String getThemeName(final Artifact artifact) {
130 final String themeName = artifact.getName().substring(ArtifactType.THEME.getId().length() + 1);
131 if (StringUtil.isBlank(themeName)) {
132 throw new ThemeException("Theme name is empty: " + artifact);
133 }
134 return themeName;
135 }
136
137
138
139
140
141
142
143 protected void closeQuietly(final Path dir) {
144 if (Files.notExists(dir)) {
145 if (logger.isDebugEnabled()) {
146 logger.debug("Path does not exist: path={}", dir);
147 }
148 return;
149 }
150 try (Stream<Path> walk = Files.walk(dir, FileVisitOption.FOLLOW_LINKS)) {
151 walk.sorted(Comparator.reverseOrder()).forEach(f -> {
152 if (logger.isDebugEnabled()) {
153 logger.debug("Deleting: path={}", f);
154 }
155 try {
156 Files.delete(f);
157 } catch (final IOException e) {
158 logger.warn("Failed to delete: path={}", f, e);
159 }
160 });
161 Files.deleteIfExists(dir);
162 } catch (final IOException e) {
163 logger.warn("Failed to delete: path={}", dir, e);
164 }
165 }
166
167
168
169
170
171
172
173
174 protected Path getJarFile(final Artifact artifact) {
175 final Path jarPath = ResourceUtil.getPluginPath(artifact.getFileName());
176 if (!Files.exists(jarPath)) {
177 throw new ThemeException(artifact.getFileName() + " does not exist.");
178 }
179 return jarPath;
180 }
181
182 }