<< back ### PD4ML: Custom Resource Loaders In most of the situations PD4ML is able to resolve relative or absolute resource references (to images, to CSS etc) and load them. However there are special cases, when the default mechanisms are not sufficient. For example: The resources are stored in an unusual place, i.e. in a database. The resources are referenced by an "exotic" or non-standard protocol. For instance, Weblogic and WebSphere SSL implementations are not derived from the standard JDK SSL classes PD4ML relies on, so it causes ClassCastException. As a workaround PD4ML allows you to create your own resource loader, which takes an URL as a parameter, and should return the loaded resource as an array of bytes.
    import java.io.BufferedInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.URL;
    import java.net.URLConnection;

    import org.zefer.cache.ResourceProvider;

    public class CustomFileResourceProvider extends ResourceProvider {

    	public byte[] getResourceAsBytes(String resource, boolean debugOn) throws IOException {
    		ByteArrayOutputStream fos = new ByteArrayOutputStream();
    		byte buffer[] = new byte[2048];

    		InputStream is = null;

    		resource = "http://pd4ml.com/i/" + resource;

    		URL src = new URL(resource);
    		URLConnection urlConnect = src.openConnection();
    		try {
    			urlConnect.connect();
    		} catch (Throwable e) {
    			return new byte[0];
    		}
    		is = urlConnect.getInputStream();
    		BufferedInputStream bis = new BufferedInputStream(is);

    		int read;
    		do {
    			read = is.read(buffer, 0, buffer.length);
    			if (read > 0) { // something to put down
    				fos.write(buffer, 0, read);
    			}
    		} while (read > -1);

    		fos.close();
    		bis.close();
    		is.close();

    		return fos.toByteArray();
    	}
    }
In order to enable the loader, you may either pass to PD4ML the class name with an environment variable (add the following to JVM command line): -Dpd4ml.extra.resource.loaders=CustomFileResourceProvider or via API call:
    HashMap map = new HashMap();
    map.put( "pd4ml.extra.resource.loaders", "CustomFileResourceProvider" );
    pd4ml.setDynamicParams(map);
It may also be a coma-separated list of multiple resource loaders. Note: a custom resource loader can be called twice for each resource reference: first time it assumes the resource URL is a relative path, so it sets resource parameter to an URL, resolved according to a document base. If the first attempt has been responded with null, it is called with the original string from SRC attribute of <img> tag, for example. If the second time the resource loader responded with null, PD4ML tries to load the reference resource the regular way. Custom resource loaders topic discussion is here.