001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.test.rule.callback;
016    
017    import aQute.bnd.osgi.Builder;
018    import aQute.bnd.osgi.Jar;
019    
020    import com.liferay.portal.kernel.exception.PortalException;
021    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
022    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
023    import com.liferay.portal.kernel.test.rule.callback.BaseTestCallback;
024    import com.liferay.portal.module.framework.ModuleFrameworkUtilAdapter;
025    
026    import java.io.File;
027    import java.io.InputStream;
028    
029    import java.net.URL;
030    
031    import java.util.Properties;
032    
033    import org.junit.runner.Description;
034    
035    /**
036     * @author Raymond Aug??
037     */
038    public class SyntheticBundleTestCallback extends BaseTestCallback<Long, Long> {
039    
040            public SyntheticBundleTestCallback(String bundlePackageName) {
041                    _bundlePackageName = bundlePackageName;
042            }
043    
044            @Override
045            public void afterClass(Description description, Long bundleId)
046                    throws PortalException {
047    
048                    if (bundleId == null) {
049                            return;
050                    }
051    
052                    ModuleFrameworkUtilAdapter.stopBundle(bundleId);
053    
054                    ModuleFrameworkUtilAdapter.uninstallBundle(bundleId);
055            }
056    
057            @Override
058            public Long beforeClass(Description description) throws Exception {
059                    Class<?> testClass = description.getTestClass();
060    
061                    InputStream inputStream = createBundle(testClass);
062    
063                    Long bundleId = ModuleFrameworkUtilAdapter.addBundle(
064                            testClass.getName(), inputStream);
065    
066                    ModuleFrameworkUtilAdapter.startBundle(bundleId);
067    
068                    return bundleId;
069            }
070    
071            protected InputStream createBundle(Class<?> clazz) throws Exception {
072                    URL url = clazz.getResource("");
073    
074                    String protocol = url.getProtocol();
075    
076                    if (!protocol.equals("file")) {
077                            throw new IllegalStateException(
078                                    "Test classes are not on the file system");
079                    }
080    
081                    String basePath = url.getPath();
082    
083                    Package pkg = clazz.getPackage();
084    
085                    String packageName = pkg.getName();
086    
087                    int index = basePath.indexOf(packageName.replace('.', '/') + '/');
088    
089                    basePath = basePath.substring(0, index);
090    
091                    File baseDir = new File(basePath);
092    
093                    try (Builder builder = new Builder();
094                                    InputStream inputStream = clazz.getResourceAsStream(
095                                            _bundlePackageName.replace('.', '/') + "/bnd.bnd")) {
096    
097                            builder.setBundleSymbolicName(clazz.getName());
098                            builder.setBase(baseDir);
099                            builder.setClasspath(new File[] {baseDir});
100                            builder.setProperty(
101                                    "bundle.package", packageName + "." + _bundlePackageName);
102    
103                            Properties properties = builder.getProperties();
104    
105                            properties.load(inputStream);
106    
107                            try (Jar jar = builder.build()) {
108                                    UnsyncByteArrayOutputStream outputStream =
109                                            new UnsyncByteArrayOutputStream();
110    
111                                    jar.write(outputStream);
112    
113                                    return new UnsyncByteArrayInputStream(
114                                            outputStream.unsafeGetByteArray(), 0, outputStream.size());
115                            }
116                    }
117            }
118    
119            private final String _bundlePackageName;
120    
121    }