/** * 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.lpkg.deployer.override; import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.util.FileImpl; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.DirectoryStream; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.nio.file.StandardOpenOption; import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.jar.Attributes; import java.util.jar.Manifest; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.junit.Assert; import org.junit.Test; import org.osgi.framework.Version; /** * @author Matthew Tambara */ public class LPKGOverrideTest { @Test public void testOverrideLPKG() throws IOException { String liferayHome = System.getProperty("liferay.home"); Assert.assertFalse( "Missing system property \"liferay.home\"", Validator.isNull(liferayHome)); File file = new File(liferayHome, "/osgi/marketplace/override"); _fileImpl.deltree(file); _fileImpl.mkdirs(file); Map<String, String> overrides = new HashMap<>(); try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream( Paths.get(liferayHome, "/osgi/marketplace"), "*.lpkg")) { for (Path lpkgPath : directoryStream) { try (ZipFile zipFile = new ZipFile(lpkgPath.toFile())) { Enumeration<? extends ZipEntry> zipEntries = zipFile.entries(); while (zipEntries.hasMoreElements()) { ZipEntry zipEntry = zipEntries.nextElement(); String name = zipEntry.getName(); if (!(name.startsWith("com.liferay") && name.endsWith(".jar")) && !name.endsWith(".war")) { continue; } Matcher matcher = _pattern.matcher(name); Assert.assertTrue( name + " does not match " + _pattern, matcher.matches()); name = matcher.group(1) + matcher.group(4); String lpkgPathString = lpkgPath.toString(); if (lpkgPathString.endsWith("Static.lpkg")) { Path staticOverridePath = Paths.get( liferayHome, "/osgi/static/", name); Files.copy( zipFile.getInputStream(zipEntry), staticOverridePath, StandardCopyOption.REPLACE_EXISTING); _upgradeModuleVersion(staticOverridePath, null); overrides.put( "static.".concat(matcher.group(1)), null); } else { Path overridePath = Paths.get( file.toString(), name); Files.copy( zipFile.getInputStream(zipEntry), overridePath, StandardCopyOption.REPLACE_EXISTING); if (name.endsWith(".war")) { String fileName = matcher.group(1); fileName = fileName.replace( "-dxp", StringPool.BLANK); overrides.put("war.".concat(fileName), null); continue; } _upgradeModuleVersion(overridePath, overrides); } } } } } StringBundler sb = new StringBundler(overrides.size() * 4); for (Entry<String, String> entry : overrides.entrySet()) { sb.append(entry.getKey()); sb.append(StringPool.COLON); sb.append(entry.getValue()); sb.append(StringPool.NEW_LINE); } sb.setIndex(sb.index() - 1); Files.write( Paths.get(liferayHome, "/overrides"), Arrays.asList(sb.toString()), StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE); } private void _upgradeModuleVersion(Path path, Map<String, String> overrides) throws IOException { try (FileSystem fileSystem = FileSystems.newFileSystem(path, null)) { Path manifestPath = fileSystem.getPath("META-INF/MANIFEST.MF"); try (InputStream inputStream = Files.newInputStream(manifestPath); UnsyncByteArrayOutputStream outputStream = new UnsyncByteArrayOutputStream()) { Manifest manifest = new Manifest(inputStream); Attributes attributes = manifest.getMainAttributes(); String versionString = attributes.getValue("Bundle-Version"); Version version = new Version(versionString); version = new Version( version.getMajor(), version.getMinor(), version.getMicro() + 1, version.getQualifier()); versionString = version.toString(); attributes.putValue("Bundle-Version", versionString); if (overrides != null) { overrides.put( attributes.getValue("Bundle-SymbolicName"), versionString); } manifest.write(outputStream); Files.write( manifestPath, outputStream.toByteArray(), StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE); } } } private static final FileImpl _fileImpl = FileImpl.getInstance(); private static final Pattern _pattern = Pattern.compile( "(.*?)(-\\d+\\.\\d+\\.\\d+)(\\..+)?(\\.[jw]ar)"); }