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