KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > izforge > izpack > compressor > PackCompressorBase


1 /*
2  * $Id: PackCompressorBase.java 1708 2007-01-13 18:31:26Z jponge $
3  * IzPack - Copyright 2001-2007 Julien Ponge, All Rights Reserved.
4  *
5  * http://www.izforge.com/izpack/
6  * http://developer.berlios.de/projects/izpack/
7  *
8  * Copyright 2005 Klaus Bartz
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  */

22 package com.izforge.izpack.compressor;
23
24 import java.io.BufferedOutputStream JavaDoc;
25 import java.io.File JavaDoc;
26 import java.io.FileOutputStream JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.lang.reflect.Constructor JavaDoc;
30 import java.net.URL JavaDoc;
31 import java.net.URLClassLoader JavaDoc;
32
33 import com.izforge.izpack.compiler.Compiler;
34
35
36 /**
37  * IzPack will be able to support different compression methods for the
38  * packs included in the installation jar file.
39  * This abstract class implements the interface PackCompressor for
40  * the common needed methods.
41  *
42  * @author Klaus Bartz
43  */

44
45 public abstract class PackCompressorBase implements PackCompressor
46 {
47
48     protected String JavaDoc [] formatNames = null;
49     protected String JavaDoc [] containerPaths = null;
50     protected String JavaDoc decoderMapper = null;
51     /**
52      * Should contain all full qualified (use dots, not slashes)
53      * names of the class files. Regex will be suported in the
54      * manner of <code>String.match</code>. <br>
55      * Example:
56      * <pre>"org.apache.tools.bzip2.CBZip2InputStream.*"</pre>
57      * Do not forget the dot before the asterix.
58      * For an other example see class BZip2PackCompressor.
59      */

60     protected String JavaDoc [][] decoderClassNames = null;
61     protected String JavaDoc encoderClassName = null;
62     
63     protected Class JavaDoc [] paramsClasses = null;
64
65     private Compiler JavaDoc compiler;
66     private Constructor JavaDoc constructor;
67     private int level = -1;
68    /**
69      *
70      */

71     public PackCompressorBase()
72     {
73         super();
74     }
75
76     /* (non-Javadoc)
77      * @see com.izforge.izpack.compressor.PackCompressor#getContainerPath()
78      */

79     public String JavaDoc[] getContainerPaths()
80     {
81         return(containerPaths);
82     }
83
84     /* (non-Javadoc)
85      * @see com.izforge.izpack.compressor.PackCompressor#getEncoderClassName()
86      */

87     public String JavaDoc getEncoderClassName()
88     {
89         return(encoderClassName);
90     }
91     /* (non-Javadoc)
92      * @see com.izforge.izpack.compressor.PackCompressor#getDecoderClassNames()
93      */

94     public String JavaDoc[][] getDecoderClassNames()
95     {
96         return(decoderClassNames);
97     }
98
99     /* (non-Javadoc)
100      * @see com.izforge.izpack.compressor.PackCompressor#useStandardCompression()
101      */

102     public boolean useStandardCompression()
103     {
104         return( false );
105     }
106
107     /* (non-Javadoc)
108      * @see com.izforge.izpack.compressor.PackCompressor#getCompressionFormatSymbols()
109      */

110     public String JavaDoc[] getCompressionFormatSymbols()
111     {
112         return(formatNames);
113     }
114
115     /* (non-Javadoc)
116      * @see com.izforge.izpack.compressor.PackCompressor#getDecoderMapperName()
117      */

118     public String JavaDoc getDecoderMapperName()
119     {
120         return(decoderMapper);
121     }
122
123     /* (non-Javadoc)
124      * @see com.izforge.izpack.compressor.PackCompressor#setCompiler(com.izforge.izpack.compiler.Compiler)
125      */

126     public void setCompiler(Compiler JavaDoc compiler)
127     {
128         this.compiler = compiler;
129     }
130
131     /* (non-Javadoc)
132      * @see com.izforge.izpack.compressor.PackCompressor#setCompressionLevel(int)
133      */

134     public void setCompressionLevel(int level)
135     {
136         this.level = level;
137     }
138
139     /* (non-Javadoc)
140      * @see com.izforge.izpack.compressor.PackCompressor#getCompressionLevel()
141      */

142     public int getCompressionLevel()
143     {
144         return( level);
145     }
146
147     /* (non-Javadoc)
148      * @see com.izforge.izpack.compressor.PackCompressor#needsBufferedOutputStream()
149      */

150     public boolean needsBufferedOutputStream()
151     {
152         return(true);
153     }
154
155
156     /**
157      * Loads the given class from the previos setted container paths.
158      * @param className full qualified name of the class to be loaded
159      * @throws Exception
160      */

161     public void loadClass( String JavaDoc className) throws Exception JavaDoc
162     {
163         if( getEncoderClassName() == null)
164             return;
165         Class JavaDoc encoder = null;
166         if( getContainerPaths() == null )
167         { // May be class files are in the compiler.jar.
168
encoder = Class.forName(className);
169         }
170         if( encoder == null)
171         {
172             String JavaDoc [] rawPaths = getContainerPaths();
173             URL JavaDoc [] uRLs = new URL JavaDoc[rawPaths.length];
174             Object JavaDoc instance = null;
175             int i;
176             int j = 0;
177
178             for(i = 0; i < rawPaths.length; ++i)
179             {
180                 if( rawPaths[i] == null )
181                     continue;
182                 String JavaDoc jarPath = compiler.replaceProperties(rawPaths[i]);
183                 URL JavaDoc url = compiler.findIzPackResource(jarPath, "Pack compressor jar file");
184                 if (url != null)
185                 {
186                     uRLs[j++] = url;
187                     if (getClass().getResource("/" + jarPath) != null)
188                     { // Oops, standalone, URLClassLoader will not work ...
189
// Write the jar to a temp file.
190
InputStream JavaDoc in = null;
191                         FileOutputStream JavaDoc outFile = null;
192                         byte[] buffer = new byte[5120];
193                         File JavaDoc tf = null;
194                         try
195                         {
196                             tf = File.createTempFile("izpj", ".jar");
197                             tf.deleteOnExit();
198                             outFile = new FileOutputStream JavaDoc(tf);
199                             in = getClass().getResourceAsStream("/" + jarPath);
200                             long bytesCopied = 0;
201                             int bytesInBuffer;
202                             while ((bytesInBuffer = in.read(buffer)) != -1)
203                             {
204                                 outFile.write(buffer, 0, bytesInBuffer);
205                                 bytesCopied += bytesInBuffer;
206                             }
207                         }
208                         finally
209                         {
210                             if (in != null) in.close();
211                             if (outFile != null) outFile.close();
212                         }
213                         url = tf.toURL();
214         
215                     }
216                 }
217             }
218             if( j > 0 )
219             {
220                 if( j < uRLs.length)
221                 {
222                     URL JavaDoc [] nurl = new URL JavaDoc[j];
223                     for( i = 0; i < j; ++i)
224                         nurl[i] = uRLs[i];
225                     uRLs = nurl;
226                 }
227                 // Use the class loader of the interface as parent, else
228
// compile will fail at using it via an Ant task.
229
URLClassLoader JavaDoc ucl = new URLClassLoader JavaDoc(uRLs, PackCompressor.class
230                         .getClassLoader());
231                 encoder = ucl.loadClass(className);
232             }
233         }
234
235         if (encoder != null)
236         {
237             // Be aware, paramsClasses should be defined earlier! For
238
// default in the constructor of this class.
239
constructor = encoder.getDeclaredConstructor(paramsClasses);
240         }
241         else
242             compiler.parseError( "Cannot find defined compressor " + className);
243     }
244     
245     /**
246      * Returns a newly created instance of the output stream which should be
247      * used by this pack compressor. This method do not declare the
248      * return value as FilterOutputStream although there must be an constructor
249      * with a slave output stream as argument. This is done in this way because
250      * some encoding streams from third party are only implemented as
251      * "normal" output stream.
252      * @param slave output stream to be used as slave
253      * @return a newly created instance of the output stream which should be
254      * used by this pack compressor
255      * @throws Exception
256      */

257     protected OutputStream JavaDoc getOutputInstance(OutputStream JavaDoc slave)
258         throws Exception JavaDoc
259     {
260         if( needsBufferedOutputStream())
261         {
262             slave = new BufferedOutputStream JavaDoc( slave);
263         }
264         Object JavaDoc [] params = resolveConstructorParams( slave );
265         if( constructor == null )
266             loadClass(getEncoderClassName());
267         if( constructor == null )
268             return(null);
269         Object JavaDoc instance = null;
270         instance = constructor.newInstance( params);
271         if (!OutputStream JavaDoc.class.isInstance(instance))
272             compiler.parseError( "'" + getEncoderClassName() + "' must be derived from "
273                     + OutputStream JavaDoc.class.toString());
274         return((OutputStream JavaDoc) instance );
275         
276     }
277     
278     /**
279      * This method will be used to support different constructor signatures.
280      * The default is
281      * <pre>XXXOutputStream( OutputStream slave )</pre>
282      * if level is -1 or
283      * <pre>XXXOutputStream( OutputStream slave, int level )</pre>
284      * if level is other than -1.<br>
285      * If the signature of the used output stream will be other, overload
286      * this method in the derived pack compressor class.
287      * @param slave output stream to be used as slave
288      * @return the constructor params as Object [] to be used as construction
289      * of the constructor via reflection
290      * @throws Exception
291      */

292     protected Object JavaDoc[] resolveConstructorParams( OutputStream JavaDoc slave) throws Exception JavaDoc
293     {
294         if( level == -1 )
295         {
296             paramsClasses = new Class JavaDoc[1];
297             paramsClasses[0] = Class.forName("java.io.OutputStream");
298             Object JavaDoc[] params = { slave};
299             return( params );
300         }
301         paramsClasses = new Class JavaDoc[2];
302         paramsClasses[0] = Class.forName("java.io.OutputStream");
303         paramsClasses[1] = java.lang.Integer.TYPE;
304         Object JavaDoc[] params = { slave, new Integer JavaDoc(level)};
305         return( params );
306      }
307
308 }
309
Popular Tags