View Javadoc

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