001package io.ebean.enhance.entity;
002
003import io.ebean.enhance.common.ClassBytesReader;
004import io.ebean.enhance.common.InputStreamTransform;
005import io.ebean.enhance.common.UrlHelper;
006
007import java.io.IOException;
008import java.io.InputStream;
009import java.net.URL;
010import java.net.URLClassLoader;
011
012/**
013 * Implementation of ClassBytesReader based on URLClassLoader.
014 */
015public class ClassPathClassBytesReader implements ClassBytesReader {
016
017
018  private final URL[] urls;
019
020  public ClassPathClassBytesReader(URL[] urls) {
021    this.urls = urls == null ? new URL[0]: urls;
022  }
023
024  @Override
025  public byte[] getClassBytes(String className, ClassLoader classLoader) {
026
027    try (URLClassLoader cl = new URLClassLoader(urls, classLoader)) {
028
029      InputStream is = null;
030      try {
031
032        String resource = className.replace('.', '/') + ".class";
033
034        // read the class bytes, and define the class
035        URL url = cl.getResource(resource);
036        if (url == null) {
037          return null;
038        }
039
040        is = UrlHelper.openNoCache(url);
041        return InputStreamTransform.readBytes(is);
042
043      } catch (IOException e){
044        throw new RuntimeException("IOException reading bytes for "+className, e);
045
046      } finally {
047        if (is != null){
048          try {
049            is.close();
050          } catch (IOException e) {
051            throw new RuntimeException("Error closing InputStream for "+className, e);
052          }
053        }
054      }
055    } catch (IOException e) {
056      throw new RuntimeException("Error closing URLClassLoader for "+className, e);
057    }
058  }
059
060}