View Javadoc

1   // ========================================================================
2   // Copyright 2002-2005 Mort Bay Consulting Pty. Ltd.
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   // http://www.apache.org/licenses/LICENSE-2.0
8   // Unless required by applicable law or agreed to in writing, software
9   // distributed under the License is distributed on an "AS IS" BASIS,
10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  // See the License for the specific language governing permissions and
12  // limitations under the License.
13  // ========================================================================
14  
15  package org.mortbay.start;
16  
17  import java.io.File;
18  import java.io.IOException;
19  import java.io.UnsupportedEncodingException;
20  import java.net.MalformedURLException;
21  import java.net.URI;
22  import java.net.URISyntaxException;
23  import java.net.URL;
24  import java.net.URLClassLoader;
25  import java.util.Arrays;
26  import java.util.StringTokenizer;
27  import java.util.Vector;
28  
29  
30  /**
31   * Class to handle CLASSPATH construction
32   * @author Jan Hlavaty
33   */
34  public class Classpath {
35  
36      Vector _elements = new Vector();    
37  
38      public Classpath()
39      {}    
40  
41      public Classpath(String initial)
42      {
43          addClasspath(initial);
44      }
45          
46      public boolean addComponent(String component)
47      {
48          if ((component != null)&&(component.length()>0)) {
49              try {
50                  File f = new File(component);
51                  if (f.exists())
52                  {
53                      File key = f.getCanonicalFile();
54                      if (!_elements.contains(key))
55                      {
56                          _elements.add(key);
57                          return true;
58                      }
59                  }
60              } catch (IOException e) {}
61          }
62          return false;
63      }
64      
65      public boolean addComponent(File component)
66      {
67          if (component != null) {
68              try {
69                  if (component.exists()) {
70                      File key = component.getCanonicalFile();
71                      if (!_elements.contains(key)) {
72                          _elements.add(key);
73                          return true;
74                      }
75                  }
76              } catch (IOException e) {}
77          }
78          return false;
79      }
80  
81      public boolean addClasspath(String s)
82      {
83          boolean added=false;
84          if (s != null)
85          {
86              StringTokenizer t = new StringTokenizer(s, File.pathSeparator);
87              while (t.hasMoreTokens())
88              {
89                  added|=addComponent(t.nextToken());
90              }
91          }
92          return added;
93      }    
94      
95      public String toString()
96      {
97          StringBuffer cp = new StringBuffer(1024);
98          int cnt = _elements.size();
99          if (cnt >= 1) {
100             cp.append( ((File)(_elements.elementAt(0))).getPath() );
101         }
102         for (int i=1; i < cnt; i++) {
103             cp.append(File.pathSeparatorChar);
104             cp.append( ((File)(_elements.elementAt(i))).getPath() );
105         }
106         return cp.toString();
107     }
108     
109     public ClassLoader getClassLoader() {
110         int cnt = _elements.size();
111         URL[] urls = new URL[cnt];
112         for (int i=0; i < cnt; i++) {
113             try {
114             	String u=((File)(_elements.elementAt(i))).toURL().toString();
115             	u=encodeFileURL(u);
116                 urls[i] = new URL(u);
117                
118             } catch (MalformedURLException e) {}
119         }
120         
121         ClassLoader parent = Thread.currentThread().getContextClassLoader();
122         if (parent == null) {
123             parent = Classpath.class.getClassLoader();
124         }
125         if (parent == null) {
126             parent = ClassLoader.getSystemClassLoader();
127         }
128         return new Loader(urls, parent);
129     }
130 
131     private class Loader extends URLClassLoader
132     {
133         String name;
134         
135         Loader(URL[] urls, ClassLoader parent)
136         {
137             super(urls, parent);
138             name = "StartLoader"+Arrays.asList(urls);
139         }
140 
141         public String toString()
142         {
143             return name;
144         }
145     }
146     
147     
148     public static String encodeFileURL(String path)
149     {
150 		byte[] bytes;
151     	try 
152     	{ 
153     		bytes=path.getBytes("utf-8");
154 		} 
155     	catch (UnsupportedEncodingException e) 
156     	{
157     		bytes=path.getBytes();
158 		}
159     	
160     	StringBuffer buf = new StringBuffer(bytes.length*2);
161         buf.append("file:");
162         
163         synchronized(buf)
164         {
165             for (int i=5;i<bytes.length;i++)
166             {
167                 byte b=bytes[i]; 
168                 switch(b)
169                 {
170                   case '%':
171                       buf.append("%25");
172                       continue;
173                   case ' ':
174                       buf.append("%20");
175                       continue;
176                   case '/':
177                   case '.':
178                   case '-':
179                   case '_':
180                       buf.append((char)b);
181                       continue;
182                   default:
183                       // let's be over conservative here!
184                       if (Character.isJavaIdentifierPart((char)b))
185                       {
186                           if(b>='a' && b<='z' || b>='A' && b<='Z' || b>='0' && b<='9')
187                           {
188                               buf.append((char)b);
189                               continue;
190                           }
191                       }
192                       buf.append('%');
193                       buf.append(Integer.toHexString((0xf0&(int)b)>>4));
194                       buf.append(Integer.toHexString((0x0f&(int)b)));
195                       continue;
196                 }
197             }
198         }
199 
200         return buf.toString();
201     }
202 }