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 }