001/* 002 * Copyright (C) 2014 Jörg Prante 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.xbib.elasticsearch.plugin.jdbc.classloader.jar; 017 018import org.xbib.elasticsearch.plugin.jdbc.classloader.AbstractResourceHandle; 019import org.xbib.elasticsearch.plugin.jdbc.classloader.AbstractURLResourceLocation; 020import org.xbib.elasticsearch.plugin.jdbc.classloader.ResourceHandle; 021 022import java.io.ByteArrayInputStream; 023import java.io.ByteArrayOutputStream; 024import java.io.File; 025import java.io.FileInputStream; 026import java.io.IOException; 027import java.io.InputStream; 028import java.net.MalformedURLException; 029import java.net.URL; 030import java.util.jar.JarEntry; 031import java.util.jar.JarFile; 032import java.util.jar.JarInputStream; 033import java.util.jar.Manifest; 034import java.util.zip.ZipException; 035 036public class JarResourceLocation extends AbstractURLResourceLocation { 037 038 private JarFile jarFile; 039 040 private byte content[]; 041 042 public JarResourceLocation(URL codeSource, File cacheFile) throws IOException { 043 super(codeSource); 044 try { 045 jarFile = new JarFile(cacheFile); 046 } catch (ZipException ze) { 047 // We get this exception on windows when the 048 // path to the jar file gets too long (Bug ID: 6374379) 049 InputStream is = null; 050 try { 051 is = new FileInputStream(cacheFile); 052 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 053 byte[] buffer = new byte[2048]; 054 int bytesRead; 055 while ((bytesRead = is.read(buffer)) != -1) { 056 baos.write(buffer, 0, bytesRead); 057 } 058 this.content = baos.toByteArray(); 059 } finally { 060 if (is != null) { 061 is.close(); 062 } 063 } 064 } 065 } 066 067 public ResourceHandle getResourceHandle(String resourceName) { 068 if (jarFile != null) { 069 JarEntry jarEntry = jarFile.getJarEntry(resourceName); 070 if (jarEntry != null) { 071 try { 072 return new JarResourceHandle(jarFile, jarEntry, getCodeSource()); 073 } catch (MalformedURLException e) { 074 e.printStackTrace(); 075 } 076 } 077 } else { 078 try { 079 final JarInputStream is = new JarInputStream(new ByteArrayInputStream(this.content)); 080 JarEntry jarEntry; 081 while ((jarEntry = is.getNextJarEntry()) != null) { 082 if (jarEntry.getName().equals(resourceName)) { 083 try { 084 return new JarEntryResourceHandle(jarEntry, is); 085 } catch (Exception e) { 086 e.printStackTrace(); 087 } 088 } 089 } 090 } catch (IOException e) { 091 e.printStackTrace(); 092 } 093 } 094 return null; 095 } 096 097 public Manifest getManifest() throws IOException { 098 if (jarFile != null) { 099 return jarFile.getManifest(); 100 } else { 101 try { 102 JarInputStream is = new JarInputStream(new ByteArrayInputStream(this.content)); 103 return is.getManifest(); 104 } catch (IOException e) { 105 e.printStackTrace(); 106 } 107 } 108 return null; 109 } 110 111 @Override 112 public void close() { 113 if (jarFile != null) { 114 try { 115 jarFile.close(); 116 } catch (Exception ignored) { 117 } 118 } 119 } 120 121 private class JarEntryResourceHandle extends AbstractResourceHandle { 122 123 private final JarEntry jarEntry2; 124 private final JarInputStream is; 125 126 public JarEntryResourceHandle(JarEntry jarEntry2, JarInputStream is) { 127 this.jarEntry2 = jarEntry2; 128 this.is = is; 129 } 130 131 public String getName() { 132 return jarEntry2.getName(); 133 } 134 135 public URL getUrl() { 136 try { 137 return new URL("jar", "", -1, getCodeSource() + "!/" + jarEntry2.getName()); 138 } catch (MalformedURLException e) { 139 throw new RuntimeException(e); 140 } 141 } 142 143 public boolean isDirectory() { 144 return jarEntry2.isDirectory(); 145 } 146 147 public URL getCodeSourceUrl() { 148 return getCodeSource(); 149 } 150 151 public InputStream getInputStream() throws IOException { 152 return is; 153 } 154 155 public int getContentLength() { 156 return (int) jarEntry2.getSize(); 157 } 158 } 159}