View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2015 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          static
40          {
41              registerAsParallelCapable();
42          }
43  
44          Loader(URL[] urls, ClassLoader parent)
45          {
46              super(urls,parent);
47          }
48  
49          @Override
50          public String toString()
51          {
52              return "startJarLoader@" + Long.toHexString(hashCode());
53          }
54      }
55  
56      private final List<File> elements = new ArrayList<File>();
57  
58      public Classpath()
59      {
60      }
61  
62      public Classpath(String initial)
63      {
64          addClasspath(initial);
65      }
66  
67      public boolean addClasspath(String s)
68      {
69          boolean added = false;
70          if (s != null)
71          {
72              StringTokenizer t = new StringTokenizer(s,File.pathSeparator);
73              while (t.hasMoreTokens())
74              {
75                  added |= addComponent(t.nextToken());
76              }
77          }
78          return added;
79      }
80  
81      public boolean addComponent(File path)
82      {
83          StartLog.debug("Adding classpath component: %s",path);
84          if ((path == null) || (!path.exists()))
85          {
86              // not a valid component
87              return false;
88          }
89  
90          try
91          {
92              File key = path.getCanonicalFile();
93              if (!elements.contains(key))
94              {
95                  elements.add(key);
96                  return true;
97              }
98          }
99          catch (IOException e)
100         {
101             StartLog.debug(e);
102         }
103 
104         return false;
105     }
106 
107     public boolean addComponent(String component)
108     {
109         if ((component == null) || (component.length() <= 0))
110         {
111             // nothing to add
112             return false;
113         }
114 
115         return addComponent(new File(component));
116     }
117 
118     public int count()
119     {
120         return elements.size();
121     }
122 
123     public void dump(PrintStream out)
124     {
125         int i = 0;
126         for (File element : elements)
127         {
128             out.printf("%2d: %s%n",i++,element.getAbsolutePath());
129         }
130     }
131 
132     public ClassLoader getClassLoader()
133     {
134         int cnt = elements.size();
135         URL[] urls = new URL[cnt];
136         for (int i = 0; i < cnt; i++)
137         {
138             try
139             {
140                 urls[i] = elements.get(i).toURI().toURL();
141                 StartLog.debug("URLClassLoader.url[%d] = %s",i,urls[i]);
142             }
143             catch (MalformedURLException e)
144             {
145                 StartLog.warn(e);
146             }
147         }
148         StartLog.debug("Loaded %d URLs into URLClassLoader",urls.length);
149 
150         ClassLoader parent = Thread.currentThread().getContextClassLoader();
151         if (parent == null)
152         {
153             parent = Classpath.class.getClassLoader();
154         }
155         if (parent == null)
156         {
157             parent = ClassLoader.getSystemClassLoader();
158         }
159         return new Loader(urls,parent);
160     }
161 
162     public List<File> getElements()
163     {
164         return elements;
165     }
166 
167     public boolean isEmpty()
168     {
169         return (elements == null) || (elements.isEmpty());
170     }
171 
172     @Override
173     public Iterator<File> iterator()
174     {
175         return elements.iterator();
176     }
177 
178     /**
179      * Overlay another classpath, copying its elements into place on this Classpath, while eliminating duplicate entries on the classpath.
180      * 
181      * @param other
182      *            the other classpath to overlay
183      */
184     public void overlay(Classpath other)
185     {
186         for (File otherElement : other.elements)
187         {
188             if (this.elements.contains(otherElement))
189             {
190                 // Skip duplicate entries
191                 continue;
192             }
193             this.elements.add(otherElement);
194         }
195     }
196 
197     @Override
198     public String toString()
199     {
200         StringBuffer cp = new StringBuffer(1024);
201         boolean needDelim = false;
202         for (File element : elements)
203         {
204             if (needDelim)
205             {
206                 cp.append(File.pathSeparatorChar);
207             }
208             cp.append(element.getAbsolutePath());
209             needDelim = true;
210         }
211         return cp.toString();
212     }
213 }