View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 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.osgi.boot.warurl;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.net.JarURLConnection;
24  import java.net.URL;
25  import java.net.URLConnection;
26  import java.util.jar.Manifest;
27  
28  import org.eclipse.jetty.osgi.boot.warurl.internal.WarBundleManifestGenerator;
29  import org.eclipse.jetty.osgi.boot.warurl.internal.WarURLConnection;
30  import org.eclipse.jetty.util.URIUtil;
31  import org.eclipse.jetty.util.resource.Resource;
32  import org.osgi.service.url.AbstractURLStreamHandlerService;
33  
34  /**
35   * RFC-66: support for the "war" protocol We are reusing the parsing of the
36   * query string from jetty. If we wanted to not depend on jetty at all we could
37   * duplicate that method here
38   */
39  public class WarUrlStreamHandler extends AbstractURLStreamHandlerService
40  {
41  
42      /**
43       * @param url The url with a war scheme
44       */
45      @Override
46      public URLConnection openConnection(URL url) throws IOException
47      {
48          // remove the war scheme.
49          URL actual = new URL(url.toString().substring("war:".length()));
50  
51          // let's do some basic tests: see if this is a folder or not.
52          // if it is a folder. we will try to support it.
53          if (actual.getProtocol().equals("file"))
54          {
55              File file = new File(URIUtil.encodePath(actual.getPath()));
56              if (file.exists())
57              {
58                  if (file.isDirectory())
59                  {
60                      // TODO (not mandatory for rfc66 though)
61                  }
62              }
63          }
64  
65          // if (actual.toString().startsWith("file:/") && ! actual.to)
66          URLConnection ori = (URLConnection) actual.openConnection();
67          ori.setDefaultUseCaches(Resource.getDefaultUseCaches());
68          JarURLConnection jarOri = null;
69          try
70          {
71              if (ori instanceof JarURLConnection)
72              {
73                  jarOri = (JarURLConnection) ori;
74              }
75              else
76              {
77                  jarOri = (JarURLConnection) new URL("jar:" + actual.toString() + "!/").openConnection();
78                  jarOri.setDefaultUseCaches(Resource.getDefaultUseCaches());
79              }
80              Manifest mf = WarBundleManifestGenerator.createBundleManifest(jarOri.getManifest(), url, jarOri.getJarFile());
81              try
82              {
83                  jarOri.getJarFile().close();
84                  jarOri = null;
85              }
86              catch (Throwable t)
87              {
88              }
89              return new WarURLConnection(actual, mf);
90          }
91          finally
92          {
93              if (jarOri != null) try
94              {
95                  jarOri.getJarFile().close();
96              }
97              catch (Throwable t)
98              {
99              }
100         }
101 
102     }
103 
104 }