Package org.pentaho.test.platform.plugin.pluginmgr

Source Code of org.pentaho.test.platform.plugin.pluginmgr.PluginClassLoaderTest

/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program 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.
*
* Copyright (c) 2002-2013 Pentaho Corporation..  All rights reserved.
*/

package org.pentaho.test.platform.plugin.pluginmgr;

import org.junit.Before;
import org.junit.Test;
import org.pentaho.platform.plugin.services.pluginmgr.PluginClassLoader;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;

import static org.junit.Assert.*;

@SuppressWarnings( "nls" )
public class PluginClassLoaderTest {

  private PluginClassLoader pluginLoader;

  @Before
  public void init() {
    // now load a class
    pluginLoader = new PluginClassLoader( new File( "./test-res/PluginClassLoaderTest/" ),
      getClass().getClassLoader() );
  }

  @SuppressWarnings( "unchecked" )
  @Test
  public void testOverrideLoad() throws ClassNotFoundException, SecurityException, InstantiationException,
    IllegalAccessException {
    pluginLoader.setOverrideLoad( true );

    String className = "org.pentaho.test.platform.plugin.pluginmgr.ClassToOverride";

    Class clazz = Class.forName( className, true, getClass().getClassLoader() );
    Object o = clazz.newInstance();
    assertEquals( "I am the original class from the parent class loader", o.toString() );

    Class overridenClazz = Class.forName( className, true, pluginLoader );
    Object o2 = overridenClazz.newInstance();
    assertEquals( "I am the overridden class from the plugin class loader", o2.toString() );
  }

  private Object getContainerFromPrivateClassLoader() throws ClassNotFoundException, InstantiationException,
    IllegalAccessException {
    String className = "org.pentaho.test.platform.plugin.pluginmgr.ClassToOverrideContainer";
    Class<?> t = Class.forName( className, true, pluginLoader );
    return t.newInstance();
  }

  @Test
  public void testImplicitLoad() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    pluginLoader.setOverrideLoad( true );

    //
    // 1. Implicitly create an instance of ClassToOverride and check that it was loaded by the default loader.
    //
    ClassToOverride cto = new ClassToOverride();
    assertNotSame( PluginClassLoader.class.getName(), cto.getClass().getClassLoader().getClass().getName() );
    assertEquals( "failed to load original class", "I am the original class from the parent class loader", cto
        .toString() );

    // NOTE: implicit loading of a class (i.e. "new" or static method access) is always performed by the
    // classloader of the enclosing class (the "current" classloader), so if we set
    // Thread.currentThread().setContextClassLoader(pluginLoader) and then did a new ClassToOverride(),
    // the pluginLoader would *not* be asked to load ClassToOverride, rather the current classloader
    // will be asked to load it.

    //
    // 2. Ask a class that we are certain was loaded by the private loader to implicitly create an instance
    // of ClassToOverride and check that the class was loaded by the private loader
    //
    Object explicitlyLoadedContainer = getContainerFromPrivateClassLoader();
    assertEquals( PluginClassLoader.class.getName(), explicitlyLoadedContainer.getClass().getClassLoader().getClass()
        .getName() );
    assertEquals( "failed to load override class", "I am the overridden class from the plugin class loader",
        explicitlyLoadedContainer.toString() );
  }

  @Test
  public void testLoadClass() throws IOException, ClassNotFoundException {
    // now try getting it as a class
    Class<?> testClass = pluginLoader.loadClass( "org.pentaho.test.platform.engine.services.TestClassForClassloader" );
    assertNotNull( "class is null", testClass );
    assertEquals( "wrong class", "org.pentaho.test.platform.engine.services.TestClassForClassloader", testClass
        .getName() );
  }

  @Test
  public void testLoadClassAsResource() throws IOException, ClassNotFoundException {
    // test the byte array first
    InputStream in =
        pluginLoader.getResourceAsStream( "org/pentaho/test/platform/engine/services/TestClassForClassloader.class" );
    assertNotNull( "Could not find class TestClassForClassloader in jar file", in );

    byte[] b = toBytes( in );
    String classBytes = new String( b );
    assertTrue( "method is missing", classBytes
        .contains( "org/pentaho/test/platform/engine/services/TestClassForClassloader" ) );
  }

  private byte[] toBytes( InputStream in ) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    byte[] b = new byte[2048];
    int n = in.read( b );
    while ( n != -1 ) {
      out.write( b, 0, n );
      n = in.read( b );
    }
    return out.toByteArray();
  }

  @Test
  public void testLoadXml() throws IOException {
    InputStream in = pluginLoader.getResourceAsStream( "test1.xml" );
    assertNotNull( "input stream is null", in );

    byte[] b = toBytes( in );
    String xml = new String( b );
    assertTrue( "xml is wrong", xml.contains( "<test1>" ) );
  }

  @Test
  public void testLoadBadResource() throws IOException {
    InputStream in = pluginLoader.getResourceAsStream( "bogus.xml" );
    assertNull( "input stream should be null", in );
  }

  @Test
  public void testLoadBadClass() throws IOException {
    // now try getting it as a class
    try {
      pluginLoader.loadClass( "bogus" );
      assertFalse( "Exception expected", true );
    } catch ( ClassNotFoundException e ) {
      assertTrue( "Exception expected", true );
    }
  }

  @Test
  public void testLoadProperties_fromJar() throws IOException {
    InputStream in = pluginLoader.getResourceAsStream( "org/pentaho/test/platform/engine/services/test.properties" );
    assertNotNull( "input stream is null", in );

    byte[] b = toBytes( in );
    String classBytes = new String( b );
    assertTrue( "property is missing", classBytes.contains( "test_setting=test" ) );

  }

  @Test
  public void testLoadProperties_fromDir() throws IOException {
    InputStream in = pluginLoader.getResourceAsStream( "resources/plugin-classloader-test-inresourcesdir.properties" );
    assertNotNull( "input stream is null", in );

    byte[] b = toBytes( in );
    String classBytes = new String( b );
    assertTrue( "property is missing", classBytes.contains( "name=" ) );

  }

  @Test
  public void testFindXmlResource() throws IOException {
    URL url = pluginLoader.getResource( "test1.xml" );

    assertNotNull( "URL is null", url );

    InputStream in = url.openStream();
    assertNotNull( "input stream is null", in );

    byte[] b = toBytes( in );
    String xml = new String( b );
    assertTrue( "xml is wrong", xml.contains( "<test1>" ) );

  }

  @Test
  public void testFindClassResource() throws IOException {
    InputStream in =
        pluginLoader.getResourceAsStream( "org/pentaho/test/platform/engine/services/TestClassForClassloader.class" );

    assertNotNull( "input stream is null", in );

    byte[] b = toBytes( in );
    String xml = new String( b );
    assertTrue( "xml is wrong", xml.contains( "TestClassForClassloader" ) );

  }

  @Test
  public void testFindBadResource() throws IOException {
    URL url = pluginLoader.getResource( "bogus.xml" );

    assertNull( "URL should be null", url );

  }

  @Test
  public void testFindResources() throws IOException {
    Enumeration<URL> urls = pluginLoader.getResources( "test1.xml" );

    assertNotNull( "URLS is null", urls );

    int count = 0;
    while ( urls.hasMoreElements() ) {
      URL url = urls.nextElement();
      InputStream in = url.openStream();
      assertNotNull( "input stream is null", in );

      byte[] b = toBytes( in );
      String xml = new String( b );
      assertTrue( "xml is wrong", xml.contains( "<test1>" ) );
      count++;
    }

    assertEquals( "Wrong number of URLS", 1, count );
  }

  @Test
  public void testFindBadResources() throws IOException {
    Enumeration<URL> urls = pluginLoader.getResources( "bogus.xml" );

    assertNotNull( "URLS is null", urls );

    int count = 0;
    while ( urls.hasMoreElements() ) {
      count++;
    }

    assertEquals( "Wrong number of URLS", 0, count );
  }

  @Test
  public void testJarListedInClassLoader() throws ClassNotFoundException {

    boolean jarFound = false;
    for ( URL url : pluginLoader.getURLs() ) {
      if ( url.toString().contains( "test-jar.jar" ) ) {
        jarFound = true;
      }
    }

    assertTrue( "test-jar.jar not found in classloader", jarFound );

    // now load a class from the jar
    pluginLoader.loadClass( "org.pentaho.test.platform.engine.services.TestClassForClassloader" );
  }

  // @Test
  // public void testIsPluginClass() throws ClassNotFoundException {
  // Class testClass = loader.loadClass("org/pentaho/test/platform/engine/services/TestClassForClassloader");
  // assertTrue("Class should have been identified as a plugin class", loader.isPluginClass(testClass));
  //
  // assertFalse("Class should NOT have been identified as a plugin class", loader.isPluginClass(String.class));
  // }
}
TOP

Related Classes of org.pentaho.test.platform.plugin.pluginmgr.PluginClassLoaderTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.