/**
* 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.osgi.web.wab.generator.internal.processor;
import aQute.bnd.header.Attrs;
import aQute.bnd.header.Parameters;
import aQute.bnd.osgi.Domain;
import aQute.bnd.osgi.Jar;
import aQute.bnd.osgi.Resource;
import com.liferay.portal.kernel.deploy.auto.context.AutoDeploymentContext;
import com.liferay.portal.kernel.security.xml.SecureXMLFactoryProviderUtil;
import com.liferay.portal.kernel.util.FileUtil;
import com.liferay.portal.kernel.util.HttpUtil;
import com.liferay.portal.kernel.xml.SAXReaderUtil;
import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
import com.liferay.portal.security.xml.SecureXMLFactoryProviderImpl;
import com.liferay.portal.util.FileImpl;
import com.liferay.portal.util.HttpImpl;
import com.liferay.portal.util.PropsImpl;
import com.liferay.portal.xml.SAXReaderImpl;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* @author Raymond Augé
*/
public class WabProcessorTest {
@BeforeClass
public static void setUpClass() {
com.liferay.portal.kernel.util.PropsUtil.setProps(new PropsImpl());
FileUtil fileUtil = new FileUtil();
fileUtil.setFile(new FileImpl());
HttpUtil httpUtil = new HttpUtil();
httpUtil.setHttp(new HttpImpl());
SAXReaderUtil saxReaderUtil = new SAXReaderUtil();
SAXReaderImpl secureSAXReader = new SAXReaderImpl();
secureSAXReader.setSecure(true);
saxReaderUtil.setSAXReader(secureSAXReader);
SecureXMLFactoryProviderUtil secureXMLFactoryProviderUtil =
new SecureXMLFactoryProviderUtil();
secureXMLFactoryProviderUtil.setSecureXMLFactoryProvider(
new SecureXMLFactoryProviderImpl());
UnsecureSAXReaderUtil unsecureSAXReaderUtil =
new UnsecureSAXReaderUtil();
SAXReaderImpl unsecureSAXReader = new SAXReaderImpl();
unsecureSAXReaderUtil.setSAXReader(unsecureSAXReader);
}
@Test
public void testClassicThemeWab() throws Exception {
File file = getFile("classic-theme.autodeployed.war");
Assert.assertNotNull(file);
try (Jar jar = new Jar(file)) {
Assert.assertNull(jar.getBsn());
Map<String, Resource> resources = jar.getResources();
Assert.assertEquals(resources.toString(), 1244, resources.size());
}
Map<String, String[]> parameters = new HashMap<>();
parameters.put("Bundle-Version", new String[] {"7.0.0.8"});
parameters.put("Web-ContextPath", new String[] {"/classic-theme"});
WabProcessor wabProcessor = new TestWabProcessor(
getClassLoader(), file, parameters);
File processedFile = wabProcessor.getProcessedFile();
Assert.assertNotNull(processedFile);
try (Jar jar = new Jar(processedFile)) {
Map<String, Map<String, Resource>> directories =
jar.getDirectories();
Map<String, Resource> resources = jar.getResources();
// Check to see that the right number of resources are in the WAB.
Assert.assertEquals(resources.toString(), 1240, resources.size());
// Check if the basic metadata is correct.
Assert.assertEquals("classic-theme", jar.getBsn());
Assert.assertEquals("7.0.0.8", jar.getVersion());
// Assert that the Bundle-ClassPath is properly formed to our
// conventions.
Domain domain = Domain.domain(jar.getManifest());
Parameters bundleClassPath = domain.getBundleClassPath();
Assert.assertEquals(4, bundleClassPath.size());
Assert.assertTrue(
bundleClassPath.containsKey("ext/WEB-INF/classes"));
for (String bundleClassPathEntry : bundleClassPath.keySet()) {
if (bundleClassPathEntry.equals("ext/WEB-INF/classes")) {
Assert.assertNull(resources.get(bundleClassPathEntry));
}
else if (bundleClassPathEntry.equals("WEB-INF/classes")) {
Assert.assertNull(resources.get(bundleClassPathEntry));
Assert.assertTrue(
directories.containsKey(bundleClassPathEntry));
}
else {
// Check that all the libraries on the Bundle-ClassPath
// exist in the WAB.
Assert.assertNotNull(resources.get(bundleClassPathEntry));
}
}
Parameters importedPackages = domain.getImportPackage();
// Check basic servlet and jsp packages are imported
Assert.assertTrue(importedPackages.containsKey("javax.servlet"));
Assert.assertTrue(
importedPackages.containsKey("javax.servlet.http"));
// Check if packages declared in portal property
// module.framework.web.generator.default.servlet.packages are
// included.
Assert.assertTrue(
importedPackages.containsKey("com.liferay.portal.model"));
Assert.assertTrue(
importedPackages.containsKey("com.liferay.portal.service"));
Assert.assertTrue(
importedPackages.containsKey(
"com.liferay.portal.servlet.filters.aggregate"));
Assert.assertTrue(
importedPackages.containsKey(
"com.liferay.portal.osgi.web.servlet.jsp.compiler"));
Assert.assertTrue(
importedPackages.containsKey(
"com.liferay.portal.spring.context"));
Assert.assertTrue(
importedPackages.containsKey("com.liferay.portal.util"));
Assert.assertTrue(
importedPackages.containsKey("com.liferay.portlet"));
Assert.assertTrue(importedPackages.containsKey("com.sun.el"));
Assert.assertTrue(
importedPackages.containsKey(
"org.apache.commons.chain.generic"));
Assert.assertTrue(
importedPackages.containsKey("org.apache.naming.java"));
// Check if packages only referenced in web.xml are imported.
Assert.assertTrue(
importedPackages.containsKey(
"com.liferay.portal.kernel.servlet.filters.invoker"));
Assert.assertTrue(
importedPackages.containsKey("com.liferay.portal.webserver"));
}
}
@Test
public void testSampleStrutsWab() throws Exception {
File file = getFile("sample-struts-portlet.autodeployed.war");
Assert.assertNotNull(file);
try (Jar jar = new Jar(file)) {
Assert.assertNull(jar.getBsn());
Map<String, Resource> resources = jar.getResources();
Assert.assertEquals(resources.toString(), 217, resources.size());
}
Map<String, String[]> parameters = new HashMap<>();
parameters.put("Bundle-Version", new String[] {"7.0.0.3"});
parameters.put(
"Web-ContextPath", new String[] {"/sample-struts-portlet"});
WabProcessor wabProcessor = new TestWabProcessor(
getClassLoader(), file, parameters);
File processedFile = wabProcessor.getProcessedFile();
Assert.assertNotNull(processedFile);
try (Jar jar = new Jar(processedFile)) {
Map<String, Map<String, Resource>> directories =
jar.getDirectories();
Map<String, Resource> resources = jar.getResources();
// Check to see that the right number of resources are in the WAB.
Assert.assertEquals(resources.toString(), 207, resources.size());
// Check if the basic metadata is correct.
Assert.assertEquals("sample-struts-portlet", jar.getBsn());
Assert.assertEquals("7.0.0.3", jar.getVersion());
// Assert that the Bundle-ClassPath is properly formed to our
// conventions.
Domain domain = Domain.domain(jar.getManifest());
Parameters bundleClassPath = domain.getBundleClassPath();
Assert.assertEquals(16, bundleClassPath.size());
Assert.assertTrue(
bundleClassPath.containsKey("ext/WEB-INF/classes"));
for (String bundleClassPathEntry : bundleClassPath.keySet()) {
if (bundleClassPathEntry.equals("ext/WEB-INF/classes")) {
Assert.assertNull(resources.get(bundleClassPathEntry));
}
else if (bundleClassPathEntry.equals("WEB-INF/classes")) {
Assert.assertNull(resources.get(bundleClassPathEntry));
Assert.assertTrue(
directories.containsKey(bundleClassPathEntry));
}
else {
// Check that all the libraries on the Bundle-ClassPath
// exist in the WAB.
Assert.assertNotNull(resources.get(bundleClassPathEntry));
}
}
// Check that a library which was declared in
// portal-dependency-jars but which is provided by the portal's
// system bundle IS NOT in the WAB.
Assert.assertNull(
resources.get("WEB-INF/lib/commons-beanutils.jar"));
Assert.assertNull(resources.get("WEB-INF/lib/commons-lang.jar"));
// Check that a library which was declared in
// portal-dependency-jars but which is NOT provided by the portal's
// system bundle IS in the WAB.
Assert.assertNotNull(resources.get("WEB-INF/lib/jfreechart.jar"));
Assert.assertNotNull(
resources.get("WEB-INF/lib/portals-bridges.jar"));
Assert.assertNotNull(resources.get("WEB-INF/lib/struts-core.jar"));
// Check that JSPs were parsed to add requirements for modular
// taglibs.
Parameters requiredCapabilities = domain.getRequireCapability();
Attrs osgiExtenderAttrs = requiredCapabilities.get("osgi.extender");
Assert.assertNotNull(osgiExtenderAttrs);
Assert.assertEquals(
"(&(osgi.extender=jsp.taglib)" +
"(uri=http://java.sun.com/portlet_2_0))",
osgiExtenderAttrs.get("filter:"));
Parameters importedPackages = domain.getImportPackage();
// Check basic servlet and jsp packages are imported
Assert.assertTrue(importedPackages.containsKey("javax.servlet"));
Assert.assertTrue(
importedPackages.containsKey("javax.servlet.http"));
// Since there are JSPs check that basic JSP packages are imported.
Assert.assertTrue(
importedPackages.containsKey("javax.servlet.jsp"));
Assert.assertTrue(
importedPackages.containsKey("javax.servlet.jsp.tagext"));
// Check if packages declared in portal property
// module.framework.web.generator.default.servlet.packages are
// included.
Assert.assertTrue(
importedPackages.containsKey("com.liferay.portal.model"));
Assert.assertTrue(
importedPackages.containsKey("com.liferay.portal.service"));
Assert.assertTrue(
importedPackages.containsKey(
"com.liferay.portal.servlet.filters.aggregate"));
Assert.assertTrue(
importedPackages.containsKey(
"com.liferay.portal.osgi.web.servlet.jsp.compiler"));
Assert.assertTrue(
importedPackages.containsKey(
"com.liferay.portal.spring.context"));
Assert.assertTrue(
importedPackages.containsKey("com.liferay.portal.util"));
Assert.assertTrue(
importedPackages.containsKey("com.liferay.portlet"));
Assert.assertTrue(importedPackages.containsKey("com.sun.el"));
Assert.assertTrue(
importedPackages.containsKey(
"org.apache.commons.chain.generic"));
Assert.assertTrue(
importedPackages.containsKey("org.apache.naming.java"));
// Check if packages imported by code are included.
Assert.assertTrue(
importedPackages.containsKey(
"com.liferay.portal.kernel.resiliency.spi.agent." +
"annotation"));
Assert.assertTrue(
importedPackages.containsKey("com.liferay.portal.kernel.util"));
// Check if packages used in the code but available on the
// Bundle-ClassPath are not imported.
Assert.assertFalse(
importedPackages.containsKey("org.apache.struts.action"));
Assert.assertFalse(importedPackages.containsKey("org.jfree.chart"));
// Check if packages only referenced in web.xml are imported.
Assert.assertTrue(
importedPackages.containsKey(
"com.liferay.portal.kernel.servlet.filters.invoker"));
Assert.assertTrue(
importedPackages.containsKey("com.liferay.portal.webserver"));
}
}
protected ClassLoader getClassLoader() {
return getClass().getClassLoader();
}
protected File getFile(String fileName) throws URISyntaxException {
ClassLoader classLoader = getClassLoader();
URL url = classLoader.getResource(fileName);
if (!"file".equals(url.getProtocol())) {
return null;
}
Path path = Paths.get(url.toURI());
return path.toFile();
}
protected class TestWabProcessor extends WabProcessor {
public TestWabProcessor(
ClassLoader classLoader, File file,
Map<String, String[]> parameters) {
super(classLoader, file, parameters);
_file = file;
}
@Override
protected void executeAutoDeployers(
AutoDeploymentContext autoDeploymentContext) {
try {
File deployDir = autoDeploymentContext.getDeployDir();
File parent = deployDir.getParentFile();
Files.walk(
parent.toPath()).sorted(Comparator.reverseOrder()).map(
Path::toFile).forEach(File::delete);
parent.mkdirs();
File newFile = new File(parent, _file.getName());
Files.copy(
_file.toPath(), newFile.toPath(),
StandardCopyOption.REPLACE_EXISTING);
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
private final File _file;
}
}