/** * Returns a newly created instance of the output stream which should be used by this pack * compressor. This method do not declare the return value as FilterOutputStream although there * must be an constructor with a slave output stream as argument. This is done in this way because * some encoding streams from third party are only implemented as "normal" output stream. * * @param slave output stream to be used as slave * @return a newly created instance of the output stream which should be used by this pack * compressor * @throws Exception */ protected OutputStream getOutputInstance(OutputStream slave) throws Exception { if (needsBufferedOutputStream()) { slave = new BufferedOutputStream(slave); } Object[] params = resolveConstructorParams(slave); if (constructor == null) { loadClass(getEncoderClassName()); } if (constructor == null) { return (null); } Object instance = null; instance = constructor.newInstance(params); if (!OutputStream.class.isInstance(instance)) { compiler.parseError( "'" + getEncoderClassName() + "' must be derived from " + OutputStream.class.toString()); } return ((OutputStream) instance); }
/** * Loads the given class from the previos setted container paths. * * @param className full qualified name of the class to be loaded * @throws Exception */ public void loadClass(String className) throws Exception { if (getEncoderClassName() == null) { return; } Class<Object> encoder = null; if (getContainerPaths() == null) { // May be class files are in the compiler.jar. encoder = (Class<Object>) Class.forName(className); } if (encoder == null) { String[] rawPaths = getContainerPaths(); URL[] uRLs = new URL[rawPaths.length]; Object instance = null; int i; int j = 0; for (i = 0; i < rawPaths.length; ++i) { if (rawPaths[i] == null) { continue; } String jarPath = compiler.replaceProperties(rawPaths[i]); URL url = compiler.findIzPackResource(jarPath, "Pack compressor jar file"); if (url != null) { uRLs[j++] = url; if (getClass().getResource("/" + jarPath) != null) { // Oops, standalone, URLClassLoader will not work ... // Write the jar to a temp file. InputStream in = null; FileOutputStream outFile = null; byte[] buffer = new byte[5120]; File tf = null; try { tf = File.createTempFile("izpj", ".jar"); tf.deleteOnExit(); outFile = new FileOutputStream(tf); in = getClass().getResourceAsStream("/" + jarPath); long bytesCopied = 0; int bytesInBuffer; while ((bytesInBuffer = in.read(buffer)) != -1) { outFile.write(buffer, 0, bytesInBuffer); bytesCopied += bytesInBuffer; } } finally { if (in != null) { in.close(); } if (outFile != null) { outFile.close(); } } url = tf.toURL(); } } } if (j > 0) { if (j < uRLs.length) { URL[] nurl = new URL[j]; for (i = 0; i < j; ++i) { nurl[i] = uRLs[i]; } uRLs = nurl; } // Use the class loader of the interface as parent, else // compile will fail at using it via an Ant task. URLClassLoader ucl = new URLClassLoader(uRLs, PackCompressor.class.getClassLoader()); encoder = (Class<Object>) ucl.loadClass(className); } } if (encoder != null) { // Be aware, paramsClasses should be defined earlier! For // default in the constructor of this class. constructor = encoder.getDeclaredConstructor(paramsClasses); } else { compiler.parseError("Cannot find defined compressor " + className); } }