001
014
015 package com.liferay.portal.patcher;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.patcher.PatchInconsistencyException;
020 import com.liferay.portal.kernel.patcher.Patcher;
021 import com.liferay.portal.kernel.security.pacl.DoPrivileged;
022 import com.liferay.portal.kernel.util.ArrayUtil;
023 import com.liferay.portal.kernel.util.FileUtil;
024 import com.liferay.portal.kernel.util.GetterUtil;
025 import com.liferay.portal.kernel.util.StreamUtil;
026 import com.liferay.portal.kernel.util.StringPool;
027 import com.liferay.portal.kernel.util.StringUtil;
028 import com.liferay.portal.kernel.util.Validator;
029
030 import java.io.File;
031 import java.io.IOException;
032 import java.io.InputStream;
033
034 import java.util.Arrays;
035 import java.util.Objects;
036 import java.util.Properties;
037
038
044 @DoPrivileged
045 public class PatcherImpl implements Patcher {
046
047 @Override
048 public boolean applyPatch(File patchFile) {
049 File patchDirectory = getPatchDirectory();
050
051 if (patchDirectory == null) {
052 return false;
053 }
054
055 try {
056 FileUtil.copyFile(
057 patchFile,
058 new File(
059 patchDirectory + StringPool.SLASH + patchFile.getName()));
060
061 return true;
062 }
063 catch (Exception e) {
064 _log.error(
065 "Unable to copy " + patchFile.getAbsolutePath() + " to " +
066 patchDirectory.getAbsolutePath());
067
068 return false;
069 }
070 }
071
072 @Override
073 public String[] getFixedIssues() {
074 if (_fixedIssueKeys != null) {
075 return _fixedIssueKeys;
076 }
077
078 Properties properties = getProperties();
079
080 _fixedIssueKeys = StringUtil.split(
081 properties.getProperty(PROPERTY_FIXED_ISSUES));
082
083 return _fixedIssueKeys;
084 }
085
086 @Override
087 public String[] getInstalledPatches() {
088 if (_installedPatchNames != null) {
089 return _installedPatchNames;
090 }
091
092 return _getInstalledPatches(null);
093 }
094
095 @Override
096 public File getPatchDirectory() {
097 if (_patchDirectory != null) {
098 return _patchDirectory;
099 }
100
101 Properties properties = getProperties();
102
103 String patchDirectoryName = properties.getProperty(
104 PROPERTY_PATCH_DIRECTORY);
105
106 if (Validator.isNotNull(patchDirectoryName)) {
107 _patchDirectory = new File(patchDirectoryName);
108
109 if (!_patchDirectory.exists()) {
110 _log.error("The patch directory does not exist");
111 }
112 }
113 else {
114 _log.error("The patch directory is not specified");
115 }
116
117 return _patchDirectory;
118 }
119
120 @Override
121 public int getPatchingToolVersion() {
122 if (_patchingToolVersion != 0) {
123 return _patchingToolVersion;
124 }
125
126 Properties properties = getProperties();
127
128 if (properties.containsKey(PROPERTY_PATCHING_TOOL_VERSION)) {
129 _patchingToolVersion = GetterUtil.getInteger(
130 properties.getProperty(PROPERTY_PATCHING_TOOL_VERSION));
131 }
132
133 return _patchingToolVersion;
134 }
135
136 @Override
137 public String getPatchingToolVersionDisplayName() {
138 if (_patchingToolVersionDisplayName != null) {
139 return _patchingToolVersionDisplayName;
140 }
141
142 Properties properties = getProperties();
143
144 if (properties.containsKey(
145 PROPERTY_PATCHING_TOOL_VERSION_DISPLAY_NAME)) {
146
147 _patchingToolVersionDisplayName = properties.getProperty(
148 PROPERTY_PATCHING_TOOL_VERSION_DISPLAY_NAME);
149 }
150 else {
151 _patchingToolVersionDisplayName = "1.0." + getPatchingToolVersion();
152 }
153
154 return _patchingToolVersionDisplayName;
155 }
156
157 @Override
158 public String[] getPatchLevels() {
159 if (_patchLevels != null) {
160 return _patchLevels;
161 }
162
163 Properties properties = getProperties();
164
165 _patchLevels = StringUtil.split(
166 properties.getProperty(PROPERTY_PATCH_LEVELS));
167
168 return _patchLevels;
169 }
170
171 @Override
172 public Properties getProperties() {
173 if (_properties != null) {
174 return _properties;
175 }
176
177 return _getProperties(PATCHER_PROPERTIES);
178 }
179
180 @Override
181 public boolean hasInconsistentPatchLevels() {
182 return _inconsistentPatchLevels;
183 }
184
185 @Override
186 public boolean isConfigured() {
187 return _configured;
188 }
189
190 @Override
191 public void verifyPatchLevels() throws PatchInconsistencyException {
192 Properties portalImplJARProperties = _getProperties(PATCHER_PROPERTIES);
193
194 String[] portalImplJARPatches = _getInstalledPatches(
195 portalImplJARProperties);
196
197 Arrays.sort(portalImplJARPatches);
198
199 Properties portalServiceJARProperties = _getProperties(
200 PATCHER_SERVICE_PROPERTIES);
201
202 String[] serviceJARPatches = _getInstalledPatches(
203 portalServiceJARProperties);
204
205 Arrays.sort(serviceJARPatches);
206
207 if (!Arrays.equals(portalImplJARPatches, serviceJARPatches)) {
208 _log.error("Inconsistent patch level detected");
209
210 if (_log.isWarnEnabled()) {
211 if (ArrayUtil.isEmpty(portalImplJARPatches)) {
212 _log.warn(
213 "There are no patches installed on portal-impl.jar");
214 }
215 else {
216 _log.warn(
217 "Patch level on portal-impl.jar: " +
218 Arrays.toString(portalImplJARPatches));
219 }
220
221 if (ArrayUtil.isEmpty(serviceJARPatches)) {
222 _log.warn(
223 "There are no patches installed on portal-kernel.jar");
224 }
225 else {
226 _log.warn(
227 "Patch level on portal-kernel.jar: " +
228 Arrays.toString(serviceJARPatches));
229 }
230 }
231
232 _inconsistentPatchLevels = true;
233
234 throw new PatchInconsistencyException();
235 }
236 }
237
238 private String[] _getInstalledPatches(Properties properties) {
239 if (properties == null) {
240 properties = getProperties();
241 }
242
243 _installedPatchNames = StringUtil.split(
244 properties.getProperty(PROPERTY_INSTALLED_PATCHES));
245
246 return _installedPatchNames;
247 }
248
249 private Properties _getProperties(String fileName) {
250 if (Validator.isNull(fileName)) {
251 fileName = PATCHER_PROPERTIES;
252 }
253
254 Properties properties = new Properties();
255
256 Class<?> clazz = getClass();
257
258 if (Objects.equals(fileName, PATCHER_SERVICE_PROPERTIES)) {
259 clazz = clazz.getInterfaces()[0];
260 }
261
262 ClassLoader classLoader = clazz.getClassLoader();
263
264 InputStream inputStream = classLoader.getResourceAsStream(fileName);
265
266 if (inputStream == null) {
267 if (_log.isDebugEnabled()) {
268 _log.debug("Unable to load " + fileName);
269 }
270 }
271 else {
272 try {
273 properties.load(inputStream);
274
275 _configured = true;
276 }
277 catch (IOException ioe) {
278 _log.error(ioe, ioe);
279 }
280 finally {
281 StreamUtil.cleanUp(inputStream);
282 }
283 }
284
285 _properties = properties;
286
287 return _properties;
288 }
289
290 private static final Log _log = LogFactoryUtil.getLog(PatcherImpl.class);
291
292 private boolean _configured;
293 private String[] _fixedIssueKeys;
294 private boolean _inconsistentPatchLevels;
295 private String[] _installedPatchNames;
296 private File _patchDirectory;
297 private int _patchingToolVersion;
298 private String _patchingToolVersionDisplayName;
299 private String[] _patchLevels;
300 private Properties _properties;
301
302 }