KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > virtual > VFSUtils


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2006, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.virtual;
23
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.io.UnsupportedEncodingException JavaDoc;
27 import java.net.URI JavaDoc;
28 import java.net.URISyntaxException JavaDoc;
29 import java.net.URL JavaDoc;
30 import java.util.ArrayList JavaDoc;
31 import java.util.Collection JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.Properties JavaDoc;
36 import java.util.StringTokenizer JavaDoc;
37 import java.util.jar.Attributes JavaDoc;
38 import java.util.jar.JarFile JavaDoc;
39 import java.util.jar.Manifest JavaDoc;
40
41 import org.jboss.logging.Logger;
42 import org.jboss.util.StringPropertyReplacer;
43 import org.jboss.virtual.spi.LinkInfo;
44
45 /**
46  * VFS Utilities
47  *
48  * @author <a HREF="adrian@jboss.com">Adrian Brock</a>
49  * @version $Revision: 1.1 $
50  */

51 public class VFSUtils
52 {
53    /** The log */
54    private static final Logger log = Logger.getLogger(VFSUtils.class);
55    /** */
56    public static final String JavaDoc VFS_LINK_PREFIX = ".vfslink";
57    /** */
58    public static final String JavaDoc VFS_LINK_NAME = "vfs.link.name";
59    public static final String JavaDoc VFS_LINK_TARGET = "vfs.link.target";
60
61    /**
62     * Get the paths string for a collection of virtual files
63     *
64     * @param paths the paths
65     * @return the string
66     * @throws IllegalArgumentException for null paths
67     */

68    public static String JavaDoc getPathsString(Collection JavaDoc<VirtualFile> paths)
69    {
70       StringBuilder JavaDoc buffer = new StringBuilder JavaDoc();
71       boolean first = true;
72       for (VirtualFile path : paths)
73       {
74          if (path == null)
75             throw new IllegalArgumentException JavaDoc("Null path in " + paths);
76          if (first == false)
77             buffer.append(':');
78          else
79             first = false;
80          buffer.append(path.getPathName());
81       }
82       
83       if (first == true)
84          buffer.append("<empty>");
85       
86       return buffer.toString();
87    }
88    
89    /**
90     * Add manifest paths
91     *
92     * @param file the file
93     * @param paths the paths to add to
94     * @throws IOException if there is an error reading the manifest or the
95     * virtual file is closed
96     * @throws IllegalStateException if the file has no parent
97     * @throws IllegalArgumentException for a null file or paths
98     */

99    public static void addManifestLocations(VirtualFile file, List JavaDoc<VirtualFile> paths) throws IOException JavaDoc
100    {
101       if (file == null)
102          throw new IllegalArgumentException JavaDoc("Null file");
103       if (paths == null)
104          throw new IllegalArgumentException JavaDoc("Null paths");
105       
106       Manifest JavaDoc manifest = getManifest(file);
107       if (manifest == null)
108          return;
109
110       Attributes JavaDoc mainAttributes = manifest.getMainAttributes();
111       String JavaDoc classPath = mainAttributes.getValue(Attributes.Name.CLASS_PATH);
112       
113       if (classPath == null)
114       {
115          if (log.isTraceEnabled())
116             log.trace("Manifest has no Class-Path for " + file.getPathName());
117          return;
118       }
119       
120       VirtualFile parent = file.getParent();
121       if (parent == null)
122          throw new IllegalStateException JavaDoc(file + " has no parent.");
123
124       URL JavaDoc parentURL = null;
125       URL JavaDoc vfsRootURL = null;
126       int rootPathLength = 0;
127       try
128       {
129          parentURL = parent.toURL();
130          vfsRootURL = file.getVFS().getRoot().toURL();
131          rootPathLength = vfsRootURL.getPath().length();
132       }
133       catch(URISyntaxException JavaDoc e)
134       {
135          IOException JavaDoc ioe = new IOException JavaDoc("Failed to get parent URL");
136          ioe.initCause(e);
137       }
138
139       StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(classPath);
140       while (tokenizer.hasMoreTokens())
141       {
142          String JavaDoc path = tokenizer.nextToken();
143
144          try
145          {
146             URL JavaDoc libURL = new URL JavaDoc(parentURL, path);
147             String JavaDoc libPath = libURL.getPath();
148             // TODO, this occurs for inner jars. Doubtful that such a mf cp is valid
149
if( rootPathLength > libPath.length() )
150                throw new IOException JavaDoc("Invalid rootPath: "+vfsRootURL+", libPath: "+libPath);
151             String JavaDoc vfsLibPath = libPath.substring(rootPathLength);
152             VirtualFile vf = file.getVFS().findChild(vfsLibPath);
153             paths.add(vf);
154          }
155          catch (IOException JavaDoc e)
156          {
157             log.debug("Manifest Class-Path entry " + path + " ignored for " + file.getPathName() + " reason=" + e);
158          }
159       }
160    }
161
162    /**
163     * Get a manifest from a virtual file,
164     * assuming the virtual file is the root of an archive
165     *
166     * @param archive the root the archive
167     * @return the manifest or null if not found
168     * @throws IOException if there is an error reading the manifest or the
169     * virtual file is closed
170     * @throws IllegalArgumentException for a null archive
171     */

172    public static Manifest JavaDoc getManifest(VirtualFile archive) throws IOException JavaDoc
173    {
174       if (archive == null)
175          throw new IllegalArgumentException JavaDoc("Null archive");
176       
177       VirtualFile manifest;
178       try
179       {
180          manifest = archive.findChild(JarFile.MANIFEST_NAME);
181       }
182       catch (IOException JavaDoc ignored)
183       {
184          log.debug("Can't find manifest for " + archive.getPathName());
185          return null;
186       }
187
188       InputStream JavaDoc stream = manifest.openStream();
189       try
190       {
191          return new Manifest JavaDoc(stream);
192       }
193       finally
194       {
195          try
196          {
197             stream.close();
198          }
199          catch (IOException JavaDoc ignored)
200          {
201          }
202       }
203    }
204    
205    /**
206     * Get a manifest from a virtual file system,
207     * assuming the root of the VFS is the root of an archive
208     *
209     * @param archive the vfs
210     * @return the manifest or null if not found
211     * @throws IOException if there is an error reading the manifest
212     * @throws IllegalArgumentException for a null archive
213     */

214    public static Manifest JavaDoc getManifest(VFS archive) throws IOException JavaDoc
215    {
216       VirtualFile root = archive.getRoot();
217       return getManifest(root);
218    }
219    
220    /**
221     * Fix a name (removes any trailing slash)
222     *
223     * @param name the name to fix
224     * @return the fixed name
225     * @throws IllegalArgumentException for a null name
226     */

227    public static String JavaDoc fixName(String JavaDoc name)
228    {
229       if (name == null)
230          throw new IllegalArgumentException JavaDoc("Null name");
231       
232       int length = name.length();
233       if (length <= 1)
234          return name;
235       if (name.charAt(length-1) == '/')
236          return name.substring(0, length-1);
237       return name;
238    }
239
240    /**
241     *
242     * @param uri
243     * @return name from uri's path
244     */

245    public static String JavaDoc getName(URI JavaDoc uri)
246    {
247       String JavaDoc name = uri.getPath();
248       if( name != null )
249       {
250          // TODO: Not correct for certain uris like jar:...!/
251
int lastSlash = name.lastIndexOf('/');
252          if( lastSlash > 0 )
253             name = name.substring(lastSlash+1);
254       }
255       return name;
256    }
257
258    /**
259     * Take a URL.getQuery string and parse it into name=value pairs
260     *
261     * @param query Possibly empty/null url query string
262     * @return String[] for the name/value pairs in the query. May be empty but never null.
263     */

264    public static Map JavaDoc<String JavaDoc, String JavaDoc> parseURLQuery(String JavaDoc query)
265    {
266        HashMap JavaDoc<String JavaDoc, String JavaDoc> pairsMap = new HashMap JavaDoc<String JavaDoc, String JavaDoc>();
267       if( query != null )
268       {
269        StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(query, "=&");
270        while( tokenizer.hasMoreTokens() )
271        {
272            String JavaDoc name = tokenizer.nextToken();
273            String JavaDoc value = tokenizer.nextToken();
274            pairsMap.put(name, value);
275        }
276       }
277        return pairsMap;
278    }
279
280    /**
281     * Does a vf name contain the VFS link prefix
282     * @param name - the name portion of a virtual file
283     * @return true if the name starts with VFS_LINK_PREFIX, false otherwise
284     */

285    public static boolean isLink(String JavaDoc name)
286    {
287       return name.indexOf(VFS_LINK_PREFIX) >= 0;
288    }
289
290    /**
291     * Read the link information from the stream based on the type as determined
292     * from the name suffix.
293     *
294     * @param is - input stream to the link file contents
295     * @param name - the name of the virtual file representing the link
296     * @param props the propertes
297     * @return a list of the links read from the stream
298     * @throws IOException on failure to read/parse the stream
299     * @throws URISyntaxException for an error parsing a URI
300     */

301    public static List JavaDoc<LinkInfo> readLinkInfo(InputStream JavaDoc is, String JavaDoc name, Properties JavaDoc props)
302       throws IOException JavaDoc, URISyntaxException JavaDoc
303    {
304       ArrayList JavaDoc<LinkInfo> info = new ArrayList JavaDoc<LinkInfo>();
305       if( name.endsWith(".properties") )
306          parseLinkProperties(is, info, props);
307       else
308          throw new UnsupportedEncodingException JavaDoc("Unknown link format: "+name);
309       return info;
310    }
311
312    /**
313     * Parse a properties link file
314     *
315     * @param is - input stream to the link file contents
316     * @param info the link infos
317     * @param props the propertes
318     * @throws IOException on failure to read/parse the stream
319     * @throws URISyntaxException for an error parsing a URI
320     */

321    public static void parseLinkProperties(InputStream JavaDoc is, List JavaDoc<LinkInfo> info, Properties JavaDoc props)
322       throws IOException JavaDoc, URISyntaxException JavaDoc
323    {
324       props.load(is);
325       // Iterate over the property tuples
326
for(int n = 0; ; n ++)
327       {
328          String JavaDoc nameKey = VFS_LINK_NAME + "." + n;
329          String JavaDoc name = props.getProperty(nameKey);
330          String JavaDoc uriKey = VFS_LINK_TARGET + "." + n;
331          String JavaDoc uri = props.getProperty(uriKey);
332          // End when the value is null since a link may not have a name
333
if (uri == null)
334          {
335             break;
336          }
337          // Replace any system property references
338
uri = StringPropertyReplacer.replaceProperties(uri);
339          LinkInfo link = new LinkInfo(name, new URI JavaDoc(uri));
340          info.add(link);
341       }
342    }
343
344    /**
345     * Deal with urls that may include spaces.
346     *
347     * @param url
348     * @return uri
349     */

350    public static URI JavaDoc toURI(URL JavaDoc url)
351       throws URISyntaxException JavaDoc
352    {
353       String JavaDoc urispec = url.toExternalForm();
354       // Escape any spaces
355
urispec = urispec.replaceAll(" ", "%20");
356       URI JavaDoc uri = new URI JavaDoc(urispec);
357       return uri;
358    }
359 }
360
Popular Tags