View Javadoc

1   // ========================================================================
2   // Copyright (c) 2002-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // ========================================================================
13  
14  package org.eclipse.jetty.start;
15  
16  import java.io.File;
17  import java.io.IOException;
18  import java.io.UnsupportedEncodingException;
19  import java.net.MalformedURLException;
20  import java.net.URL;
21  import java.net.URLClassLoader;
22  import java.util.Arrays;
23  import java.util.StringTokenizer;
24  import java.util.Vector;
25  
26  
27  /**
28   * Class to handle CLASSPATH construction
29   * 
30   */
31  public class Classpath {
32  
33      Vector _elements = new Vector();    
34  
35      public Classpath()
36      {}    
37  
38      public Classpath(String initial)
39      {
40          addClasspath(initial);
41      }
42      
43      public File[] getElements()
44      {
45          return (File[])_elements.toArray(new File[_elements.size()]);
46      }
47          
48      public boolean addComponent(String component)
49      {
50          if ((component != null)&&(component.length()>0)) {
51              try {
52                  File f = new File(component);
53                  if (f.exists())
54                  {
55                      File key = f.getCanonicalFile();
56                      if (!_elements.contains(key))
57                      {
58                          _elements.add(key);
59                          return true;
60                      }
61                  }
62              } catch (IOException e) {}
63          }
64          return false;
65      }
66      
67      public boolean addComponent(File component)
68      {
69          if (component != null) {
70              try {
71                  if (component.exists()) {
72                      File key = component.getCanonicalFile();
73                      if (!_elements.contains(key)) {
74                          _elements.add(key);
75                          return true;
76                      }
77                  }
78              } catch (IOException e) {}
79          }
80          return false;
81      }
82  
83      public boolean addClasspath(String s)
84      {
85          boolean added=false;
86          if (s != null)
87          {
88              StringTokenizer t = new StringTokenizer(s, File.pathSeparator);
89              while (t.hasMoreTokens())
90              {
91                  added|=addComponent(t.nextToken());
92              }
93          }
94          return added;
95      }    
96      
97      public String toString()
98      {
99          StringBuffer cp = new StringBuffer(1024);
100         int cnt = _elements.size();
101         if (cnt >= 1) {
102             cp.append( ((File)(_elements.elementAt(0))).getPath() );
103         }
104         for (int i=1; i < cnt; i++) {
105             cp.append(File.pathSeparatorChar);
106             cp.append( ((File)(_elements.elementAt(i))).getPath() );
107         }
108         return cp.toString();
109     }
110     
111     public ClassLoader getClassLoader() {
112         int cnt = _elements.size();
113         URL[] urls = new URL[cnt];
114         for (int i=0; i < cnt; i++) {
115             try {
116                 String u=((File)(_elements.elementAt(i))).toURL().toString();
117                 urls[i] = new URL(encodeFileURL(u));
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     public static String encodeFileURL(String path)
148     {
149         byte[] bytes;
150         try 
151         { 
152             bytes=path.getBytes("utf-8");
153         } 
154         catch (UnsupportedEncodingException e) 
155         {
156             bytes=path.getBytes();
157         }
158         
159         StringBuffer buf = new StringBuffer(bytes.length*2);
160         buf.append("file:");
161         
162         synchronized(buf)
163         {
164             for (int i=5;i<bytes.length;i++)
165             {
166                 byte b=bytes[i]; 
167                 switch(b)
168                 {
169                   case '%':
170                       buf.append("%25");
171                       continue;
172                   case ' ':
173                       buf.append("%20");
174                       continue;
175                   case '/':
176                   case '.':
177                   case '-':
178                   case '_':
179                       buf.append((char)b);
180                       continue;
181                   default:
182                       // let's be over conservative here!
183                       if (Character.isJavaIdentifierPart((char)b))
184                       {
185                           if(b>='a' && b<='z' || b>='A' && b<='Z' || b>='0' && b<='9')
186                           {
187                               buf.append((char)b);
188                               continue;
189                           }
190                       }
191                       buf.append('%');
192                       buf.append(Integer.toHexString((0xf0&(int)b)>>4));
193                       buf.append(Integer.toHexString((0x0f&(int)b)));
194                       continue;
195                 }
196             }
197         }
198 
199         return buf.toString();
200     }
201 }