001         package com.croftsoft.core.lang.classloader;
002    
003         import java.awt.*;
004         import java.io.*;
005         import java.lang.reflect.*;
006         import java.net.*;
007         import java.util.*;
008    
009         /*********************************************************************
010         * <P>
011         * Upgrade this source code when the switch is made from Java 1.1 to
012         * Java 1.2.
013         * <P>
014         * <B>
015         * References
016         * </B>
017         * Scott Oaks, <U>Java Security</U>, O'Reilly, 1998.
018         * <P>
019         * @version
020         *   1998-09-06
021         * @author
022         *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
023         *********************************************************************/
024    
025         public class  NetClassLoader extends CustomClassLoader
026         //////////////////////////////////////////////////////////////////////
027         //////////////////////////////////////////////////////////////////////
028         {
029    
030         protected URL  codebaseURL;
031    
032         //////////////////////////////////////////////////////////////////////
033         //////////////////////////////////////////////////////////////////////
034    
035         /*********************************************************************
036         * Loads a remote class and launches its main() method.
037         *
038         * @param
039         *   Command-line arguments:
040         *   <OL>
041         *   <LI> The URL for the codebase.
042         *   <LI> The name of the class with the "main(args)" method.
043         *   <LI> Subsequent arguments to be passed to the invoked main method.
044         *   </OL>
045         *   Example
046         *********************************************************************/
047         public static void  main ( String [ ]  args )
048           throws Exception
049         //////////////////////////////////////////////////////////////////////
050         {
051           String [ ]  shiftedArgs = new String [ args.length - 2 ];
052           for ( int  i = 2; i < args.length; i++ )
053           {
054             shiftedArgs [ i - 2 ] = args [ i ];
055           }
056    
057           launchMain ( args [ 0 ], args [ 1 ], shiftedArgs );
058         }
059    
060         /*********************************************************************
061         * Loads a remote class and launches its main() method.
062         *********************************************************************/
063         public static void  launchMain (
064           String      codebaseURLName,
065           String      mainClassName,
066           String [ ]  args )
067           throws ClassNotFoundException,
068                  IllegalAccessException,
069                  MalformedURLException
070         //////////////////////////////////////////////////////////////////////
071         {
072           URL  codebaseURL = new URL ( codebaseURLName );
073           ClassLoader  classLoader = new NetClassLoader ( codebaseURL );
074           Class  c = classLoader.loadClass ( mainClassName );
075           invokeMain ( c, args );
076         }
077    
078         public static void  invokeMain ( Class  c, String [ ]  args )
079           throws IllegalAccessException
080         //////////////////////////////////////////////////////////////////////
081         {
082           Method  method;
083    
084           try
085           {
086             method = c.getMethod ( "main",
087               new Class [ ] { String [ ].class } );
088           }
089           catch ( NoSuchMethodException  ex )
090           {
091             System.err.println ( "No main() method in class \""
092               + c.getName ( ) + "\"." );
093             return;
094           }
095    
096           try
097           {
098             method.invoke ( null, new Object [ ] { args } );
099           }
100           catch ( InvocationTargetException  ex )
101           {
102             Throwable  t = ex.getTargetException ( );
103             System.err.println (
104               "\"main()\" method exited with exception \"" + t + "\"." );
105             t.printStackTrace ( );
106           }
107         }
108    
109         /*********************************************************************
110         * Ex:  "http://www.mysticmayhem.com/lib/"
111         *********************************************************************/
112         public  NetClassLoader ( URL  codebaseURL )
113         //////////////////////////////////////////////////////////////////////
114         {
115           this.codebaseURL = codebaseURL;
116         }
117    
118         protected byte [ ]  loadClassData ( String  name )
119         //////////////////////////////////////////////////////////////////////
120         {
121           try
122           {
123             String  pathName = name.replace ( '.', '/' ) + ".class";
124             BufferedInputStream  in = new BufferedInputStream (
125               getResourceAsStream ( pathName ) );
126             if ( in == null ) return null;
127             ByteArrayOutputStream  out = new ByteArrayOutputStream ( );
128             int  i;
129             while ( ( i = in.read ( ) ) > -1 ) out.write ( i );
130             in.close ( );
131             return out.toByteArray ( );
132           }
133           catch ( Exception  ex ) { ex.printStackTrace ( ); return null; }
134         }
135    
136         /*********************************************************************
137         *********************************************************************/
138         public URL  getResource ( String  name )
139         //////////////////////////////////////////////////////////////////////
140         {
141           try
142           {
143             return new URL ( codebaseURL, name );
144           }
145           catch ( Exception  ex ) { ex.printStackTrace ( ); return null; }
146         }
147    
148         /*********************************************************************
149         * Loads a stream from the URL given by getResource(name).
150         * Does not use a cache.
151         *********************************************************************/
152         public InputStream  getResourceAsStream ( String  name )
153         //////////////////////////////////////////////////////////////////////
154         {
155           try
156           {
157             URL  url = getResource ( name );
158    System.out.println ( "Loading \"" + url + "\"..." );
159             URLConnection  urlConnection = url.openConnection ( );
160             if ( urlConnection instanceof HttpURLConnection )
161             {
162               HttpURLConnection  httpURLConnection
163                 = ( HttpURLConnection ) urlConnection;
164               httpURLConnection.setFollowRedirects ( true );
165               httpURLConnection.setRequestMethod ( "GET" );
166               int  responseCode = httpURLConnection.getResponseCode ( );
167    System.out.println (
168               httpURLConnection.getResponseMessage ( )
169      + ", " + httpURLConnection.getContentLength ( ) + " bytes"
170      + ", " + new Date ( httpURLConnection.getDate ( ) )
171      + ", " + new Date ( httpURLConnection.getLastModified ( ) ) );
172               if ( responseCode != HttpURLConnection.HTTP_OK )
173               {
174                 return null;
175               }
176             }
177             return urlConnection.getInputStream ( );
178           }
179           catch ( Exception  ex ) { ex.printStackTrace ( ); return null; }
180         }
181    
182         /*********************************************************************
183         * Creates the image by calling getResourceAsStream(imageName).
184         *********************************************************************/
185         public Image  createImage ( String  imageName )
186           throws IOException
187         //////////////////////////////////////////////////////////////////////
188         {
189           InputStream  inputStream = getResourceAsStream ( imageName );
190           BufferedInputStream  in = new BufferedInputStream ( inputStream );
191           ByteArrayOutputStream  out = new ByteArrayOutputStream ( );
192           int  i;
193           while ( ( i = in.read ( ) ) > -1 ) out.write ( i );
194           byte [ ]  imageData = out.toByteArray ( );
195           out.close ( );
196           in.close ( );
197           return Toolkit.getDefaultToolkit ( ).createImage ( imageData );
198         }
199    
200         //////////////////////////////////////////////////////////////////////
201         //////////////////////////////////////////////////////////////////////
202         }