View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.start;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.io.PrintStream;
24  import java.net.MalformedURLException;
25  import java.net.URL;
26  import java.net.URLClassLoader;
27  import java.util.ArrayList;
28  import java.util.Iterator;
29  import java.util.List;
30  import java.util.StringTokenizer;
31  
32  /**
33   * Class to handle CLASSPATH construction
34   */
35  public class Classpath implements Iterable<File>
36  {
37      private static class Loader extends URLClassLoader
38      {
39          Loader(URL[] urls, ClassLoader parent)
40          {
41              super(urls,parent);
42          }
43  
44          @Override
45          public String toString()
46          {
47              return "startJarLoader@" + Long.toHexString(hashCode());
48          }
49      }
50  
51      private final List<File> elements = new ArrayList<File>();
52  
53      public Classpath()
54      {
55      }
56  
57      public Classpath(String initial)
58      {
59          addClasspath(initial);
60      }
61  
62      public boolean addClasspath(String s)
63      {
64          boolean added = false;
65          if (s != null)
66          {
67              StringTokenizer t = new StringTokenizer(s,File.pathSeparator);
68              while (t.hasMoreTokens())
69              {
70                  added |= addComponent(t.nextToken());
71              }
72          }
73          return added;
74      }
75  
76      public boolean addComponent(File path)
77      {
78          if ((path == null) || (!path.exists()))
79          {
80              // not a valid component
81              return false;
82          }
83  
84          try
85          {
86              File key = path.getCanonicalFile();
87              if (!elements.contains(key))
88              {
89                  elements.add(key);
90                  return true;
91              }
92          }
93          catch (IOException e)
94          {
95              StartLog.debug(e);
96          }
97  
98          return false;
99      }
100 
101     public boolean addComponent(String component)
102     {
103         if ((component == null) || (component.length() <= 0))
104         {
105             // nothing to add
106             return false;
107         }
108 
109         return addComponent(new File(component));
110     }
111 
112     public int count()
113     {
114         return elements.size();
115     }
116 
117     public void dump(PrintStream out)
118     {
119         int i = 0;
120         for (File element : elements)
121         {
122             out.printf("%2d: %s%n",i++,element.getAbsolutePath());
123         }
124     }
125 
126     public ClassLoader getClassLoader()
127     {
128         int cnt = elements.size();
129         URL[] urls = new URL[cnt];
130         for (int i = 0; i < cnt; i++)
131         {
132             try
133             {
134                 urls[i] = elements.get(i).toURI().toURL();
135                 StartLog.debug("URLClassLoader.url[%d] = %s",i,urls[i]);
136             }
137             catch (MalformedURLException e)
138             {
139                 StartLog.warn(e);
140             }
141         }
142         StartLog.debug("Loaded %d URLs into URLClassLoader",urls.length);
143 
144         ClassLoader parent = Thread.currentThread().getContextClassLoader();
145         if (parent == null)
146         {
147             parent = Classpath.class.getClassLoader();
148         }
149         if (parent == null)
150         {
151             parent = ClassLoader.getSystemClassLoader();
152         }
153         return new Loader(urls,parent);
154     }
155 
156     public List<File> getElements()
157     {
158         return elements;
159     }
160 
161     public boolean isEmpty()
162     {
163         return (elements == null) || (elements.isEmpty());
164     }
165 
166     @Override
167     public Iterator<File> iterator()
168     {
169         return elements.iterator();
170     }
171 
172     /**
173      * Overlay another classpath, copying its elements into place on this Classpath, while eliminating duplicate entries on the classpath.
174      * 
175      * @param other
176      *            the other classpath to overlay
177      */
178     public void overlay(Classpath other)
179     {
180         for (File otherElement : other.elements)
181         {
182             if (this.elements.contains(otherElement))
183             {
184                 // Skip duplicate entries
185                 continue;
186             }
187             this.elements.add(otherElement);
188         }
189     }
190 
191     @Override
192     public String toString()
193     {
194         StringBuffer cp = new StringBuffer(1024);
195         boolean needDelim = false;
196         for (File element : elements)
197         {
198             if (needDelim)
199             {
200                 cp.append(File.pathSeparatorChar);
201             }
202             cp.append(element.getAbsolutePath());
203             needDelim = true;
204         }
205         return cp.toString();
206     }
207 }