View Javadoc

1   /*
2    * Copyright 2001,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.commons.jjar;
18  
19  import java.lang.Package;
20  
21  import java.util.ArrayList;
22  import java.util.Iterator;
23  import java.util.Collection;
24  import java.util.Map;
25  import java.util.List;
26  import java.util.StringTokenizer;
27  import java.util.Enumeration;
28  
29  import java.util.jar.JarFile;
30  import java.util.jar.Manifest;
31  import java.util.jar.Attributes;
32  import java.util.jar.JarInputStream;
33  import java.util.jar.JarOutputStream;
34  import java.util.jar.JarEntry;
35  
36  import java.io.File;
37  import java.io.FileOutputStream;
38  import java.io.BufferedInputStream;
39  import java.io.BufferedOutputStream;
40  import java.io.InputStream;
41  import java.io.ByteArrayOutputStream;
42  
43  import java.net.JarURLConnection;
44  import java.net.URLConnection;
45  import java.net.URL;
46  
47  
48  /**
49   *  classpath support for JJAR.  This is currently a jumble - will
50   *  clean up.
51   *
52   *  @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
53   *  @version $Id: ClasspathUtil.java 155454 2005-02-26 13:23:34Z dirkv $ 
54   */
55  public class ClasspathUtil
56  {
57      /**
58       *  current default repository
59       */
60  
61      public static String getDefaultRepository()
62      {
63          return "http://jakarta.apache.org/jjar/";
64      }
65  
66      /**
67       *  lists the jars currently in the classpath
68       */
69      public static void listJars( String path )
70      {
71         List jars = getJarList( path );
72  
73         Iterator i = jars.iterator();
74         
75         while( i.hasNext() )
76         {
77             String jar =  (String) i.next();
78             System.out.println(" inspecting :  " + jar );
79         }
80  
81         return;
82      }
83      
84      /**
85       *  checks to see if the classpath <code>path</code> contains
86       *  the package / version
87       */
88      public static boolean containsVersionedJar( String path, String pkg, String version)
89      {
90          List jars = getJarList( path );
91  
92         /*
93          *  now, with this set of jars, see if we can find those that match
94          *  the package name
95          */
96  
97          Iterator i = jars.iterator();
98   
99          while( i.hasNext() )
100         {
101             String jar =  (String) i.next();
102 
103             try
104             {
105                 URL url = new URL("jar:file:" + jar + "!/");
106                 JarURLConnection conn  = (JarURLConnection) url.openConnection(); 
107 
108                 if (packageMatch( conn, pkg, version ) )
109                 {
110                     // System.out.println( jar + " : pkg = " + pkg + " ver = " + version );
111 
112                     return true;
113                 }
114             }
115             catch( Exception e )
116             {
117                 //System.out.println("Exception (continuing) : " + e );
118             }
119         }
120         
121         return false;
122     }
123 
124     /**
125      *  returns a JJARPackage( info ) for a given jar
126      */
127     public static JJARPackage getPackage( String jarname )
128         throws Exception
129     {
130         URL url = new URL("jar:file:" + jarname + "!/");
131         JarURLConnection conn  = (JarURLConnection) url.openConnection(); 
132         
133         return getPackage( conn );
134     }
135 
136     public static JJARPackage getPackage( JarURLConnection jarConn )
137         throws Exception
138     {
139         if (jarConn == null)
140             return null;
141 
142         Manifest mfst = jarConn.getManifest();
143         
144         if (mfst == null)
145         {
146             return null;
147         }
148         
149         /*
150          * get the attributes we care about
151          */
152 
153         Attributes att = mfst.getMainAttributes();
154 
155         String jarpkg = att.getValue( Attributes.Name.IMPLEMENTATION_TITLE );
156         String jarver = att.getValue( Attributes.Name.IMPLEMENTATION_VERSION );
157 
158         if (jarpkg == null || jarver == null)
159         {
160             /*
161              * unusable
162              */
163             
164             return null;
165         }
166         
167         return new JJARPackage( jarpkg, jarver );
168     }
169        
170     /**
171      *  determines if two packages are equal
172      */
173     public static boolean packageMatch( JarURLConnection jarConn, String pkg, String version )
174         throws Exception
175     {
176         JJARPackage jjarp = getPackage( jarConn );
177 
178         if ( jjarp == null)
179             return false;
180 
181         /*
182          *  compare
183          */
184         
185         return jjarp.equals( pkg, version );
186     } 
187 
188 
189     /**
190      *  returns a list of jars in the specified claspath.
191      *  will check the system classpath by default
192      */
193     public static List getJarList( String path )
194     {
195         if (path == null)
196         {
197             path = "java.class.path";
198         }
199 
200         String classpath = System.getProperty( path );
201         String pathSep = System.getProperty("path.separator");
202 
203         /*
204          *  take the classpath, and look for jars
205          */
206 
207         StringTokenizer st = new StringTokenizer( classpath, pathSep );
208 
209         ArrayList jars = new ArrayList();
210 
211         while( st.hasMoreTokens() )
212         {
213             String foo = st.nextToken();
214             
215             if ( foo.indexOf("jar") != -1 )
216                 jars.add(foo);
217         }
218 
219         return jars;
220     }    
221 
222     public static void main( String args[] )
223     {
224         /*
225          *  see if the default classpath has the jar we need
226          */
227         if ( ClasspathUtil.containsVersionedJar( null, "commons-beanutils", "0.1") )
228             System.out.println("Found commons-beanutils v0.1");
229         else
230         {
231             /*
232              * didn't find it...
233              */
234 
235             try
236             {
237                 /*
238                  *  so go to the repository
239                  */
240 
241                 URL url = new URL("jar:file:/home/gmj/jakarta/jakarta-commons/beanutils/dist/commons-beanutils.jar!/");
242                 JarURLConnection conn  = (JarURLConnection) url.openConnection(); 
243 
244                 /*
245                  * ensure that it's right
246                  */
247 
248                 if (!packageMatch( conn, "commons-beanutils", "0.1" ))
249                 {
250                     System.out.println("repository doesn't have it");
251                     return;
252                 }
253 
254                 System.out.println("jar in repository correct. Fetching");
255 
256                 String jar = "commons-beanutils-0.1.jar";
257 
258                 url = new URL("file:/home/gmj/jakarta/jakarta-commons/beanutils/dist/commons-beanutils.jar");
259                 URLConnection uconn  = (URLConnection) url.openConnection(); 
260 
261                 Transport.fetchJar( uconn, jar );
262 
263                 /*
264                  *  add to classpath and verify
265                  */
266                 
267                 String classpath = System.getProperty( "java.class.path" );
268                 String pathSep = System.getProperty("path.separator");
269 
270                 classpath = classpath + pathSep + jar;
271 
272                 System.setProperty("java.class.path", classpath);
273 
274                 if ( ClasspathUtil.containsVersionedJar( null, "commons-beanutils", "0.1") )
275                     System.out.println("Found commons-beanutils v0.1");
276                 
277             }
278             catch( Exception e )
279             {
280                 System.out.println("exception " + e );
281             }
282         }
283         
284     }
285 
286     /**
287      *  doesn't work.  don't use
288      */
289     public static boolean markJar( String jarname, String packagename, String version )
290         throws Exception
291     {
292         JarFile jf = new JarFile( jarname );
293 
294         Manifest mfst = jf.getManifest();
295         
296         if (mfst == null)
297         {
298             return false;
299         }
300         
301         /*
302          * set the attributes we care about
303          */
304 
305         Attributes att = mfst.getMainAttributes();
306 
307         Object a = att.put( Attributes.Name.IMPLEMENTATION_TITLE, packagename );
308         Object b = att.put( Attributes.Name.IMPLEMENTATION_VERSION, version );
309 
310         System.out.println(" Object a " + a );
311         System.out.println(" Object b " + b );
312 
313         JarOutputStream jos = new JarOutputStream( new FileOutputStream( new File( jarname + "-jjar")));
314         byte[] buffer = new byte[1024]; 
315         int bytesRead; 
316 
317         for( Enumeration e = jf.entries(); e.hasMoreElements(); )
318         {
319             JarEntry entry = (JarEntry) e.nextElement(); 
320 
321             if( entry.getName().equals("META-INF/MANIFEST.MF"))
322             {
323                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
324 
325                 mfst.write( baos );
326 
327                 JarEntry ee = new JarEntry( entry );
328 
329                 ee.setSize(baos.size() );
330 
331                 jos.putNextEntry(ee );
332                 mfst.write( jos );
333                 continue;
334             }
335 
336             System.out.println(" Name : " + entry.getName() );
337 
338             InputStream entryStream = jf.getInputStream( entry); 
339 
340             jos.putNextEntry(entry );
341 
342             while ((bytesRead = entryStream.read(buffer)) != -1) 
343             { 
344                 jos.write(buffer, 0, bytesRead);
345             }
346         }
347 
348         jos.close();
349         jf.close();
350 
351         return true;
352     }   
353 }
354 
355 
356 
357 
358 
359 
360 
361