/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.patcher; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.patcher.PatchInconsistencyException; import com.liferay.portal.kernel.patcher.Patcher; import com.liferay.portal.kernel.security.pacl.DoPrivileged; import com.liferay.portal.kernel.util.ArrayUtil; import com.liferay.portal.kernel.util.FileUtil; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.StreamUtil; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.Validator; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import java.util.Objects; import java.util.Properties; /** * @author Zsolt Balogh * @author Brian Wing Shun Chan * @author Igor Beslic * @author Zoltán Takács */ @DoPrivileged public class PatcherImpl implements Patcher { public PatcherImpl() { _properties = _getProperties(PATCHER_PROPERTIES); _fixedIssueKeys = StringUtil.split( _properties.getProperty(PROPERTY_FIXED_ISSUES)); _installedPatchNames = StringUtil.split( _properties.getProperty(PROPERTY_INSTALLED_PATCHES)); _patchLevels = StringUtil.split( _properties.getProperty(PROPERTY_PATCH_LEVELS)); _patchingToolVersion = GetterUtil.getInteger( _properties.get(PROPERTY_PATCHING_TOOL_VERSION)); _patchingToolVersionDisplayName = getPatchingToolVersionDisplayName(); _separated = GetterUtil.getBoolean( _properties.getProperty(PROPERTY_SEPARATED)); _separationId = _properties.getProperty(PROPERTY_SEPARATION_ID); } @Override public boolean applyPatch(File patchFile) { File patchDirectory = getPatchDirectory(); if (patchDirectory == null) { return false; } try { FileUtil.copyFile( patchFile, new File( patchDirectory + StringPool.SLASH + patchFile.getName())); return true; } catch (Exception e) { _log.error( "Unable to copy " + patchFile.getAbsolutePath() + " to " + patchDirectory.getAbsolutePath()); return false; } } @Override public String[] getFixedIssues() { return _fixedIssueKeys; } @Override public String[] getInstalledPatches() { return _installedPatchNames; } @Override public File getPatchDirectory() { String patchDirectoryName = _properties.getProperty( PROPERTY_PATCH_DIRECTORY); File patchDirectory = null; if (Validator.isNotNull(patchDirectoryName)) { patchDirectory = new File(patchDirectoryName); if (!patchDirectory.exists()) { _log.error("The patch directory does not exist"); _configured = false; } else { _configured = true; } } else { if (_log.isDebugEnabled()) { _log.debug("The patch directory is not specified"); } _configured = false; } return patchDirectory; } @Override public int getPatchingToolVersion() { return _patchingToolVersion; } @Override public String getPatchingToolVersionDisplayName() { if (_patchingToolVersionDisplayName != null) { return _patchingToolVersionDisplayName; } String patchingToolVersionDisplayName = "1.0." + getPatchingToolVersion(); if (_properties.containsKey( PROPERTY_PATCHING_TOOL_VERSION_DISPLAY_NAME)) { patchingToolVersionDisplayName = _properties.getProperty( PROPERTY_PATCHING_TOOL_VERSION_DISPLAY_NAME); } return patchingToolVersionDisplayName; } @Override public String[] getPatchLevels() { return _patchLevels; } @Override public Properties getProperties() { return _properties; } @Override public String getSeparationId() { return _separationId; } @Override public boolean hasInconsistentPatchLevels() { return _inconsistentPatchLevels; } @Override public boolean isConfigured() { getPatchDirectory(); return _configured; } @Override public boolean isSeparated() { return _separated; } @Override public void verifyPatchLevels() throws PatchInconsistencyException { Properties portalKernelJARProperties = _getProperties( PATCHER_SERVICE_PROPERTIES); String[] kernelJARPatches = _getInstalledPatches( portalKernelJARProperties); Arrays.sort(kernelJARPatches); Properties portalImplJARProperties = _getProperties(PATCHER_PROPERTIES); String[] portalImplJARPatches = _getInstalledPatches( portalImplJARProperties); Arrays.sort(portalImplJARPatches); if (!Arrays.equals(portalImplJARPatches, kernelJARPatches)) { _log.error("Inconsistent patch level detected"); if (_log.isWarnEnabled()) { if (ArrayUtil.isEmpty(portalImplJARPatches)) { _log.warn( "There are no patches installed on portal-impl.jar"); } else { _log.warn( "Patch level on portal-impl.jar: " + Arrays.toString(portalImplJARPatches)); } if (ArrayUtil.isEmpty(kernelJARPatches)) { _log.warn( "There are no patches installed on portal-kernel.jar"); } else { _log.warn( "Patch level on portal-kernel.jar: " + Arrays.toString(kernelJARPatches)); } } _inconsistentPatchLevels = true; throw new PatchInconsistencyException(); } } private String[] _getInstalledPatches(Properties properties) { if (properties == null) { properties = getProperties(); } String[] installedPatchNames = StringUtil.split( properties.getProperty(PROPERTY_INSTALLED_PATCHES)); return installedPatchNames; } private Properties _getProperties(String fileName) { if (Validator.isNull(fileName)) { fileName = PATCHER_PROPERTIES; } Properties properties = new Properties(); Class<?> clazz = getClass(); if (Objects.equals(fileName, PATCHER_SERVICE_PROPERTIES)) { clazz = clazz.getInterfaces()[0]; } ClassLoader classLoader = clazz.getClassLoader(); InputStream inputStream = classLoader.getResourceAsStream(fileName); if (inputStream == null) { if (_log.isDebugEnabled()) { _log.debug("Unable to load " + fileName); } } else { try { properties.load(inputStream); } catch (IOException ioe) { _log.error(ioe, ioe); } finally { StreamUtil.cleanUp(inputStream); } } return properties; } private static final Log _log = LogFactoryUtil.getLog(PatcherImpl.class); private boolean _configured; private final String[] _fixedIssueKeys; private boolean _inconsistentPatchLevels; private final String[] _installedPatchNames; private final int _patchingToolVersion; private final String _patchingToolVersionDisplayName; private final String[] _patchLevels; private final Properties _properties; private final boolean _separated; private final String _separationId; }