1 28 29 package com.caucho.jca; 30 31 import com.caucho.config.Config; 32 import com.caucho.config.ConfigException; 33 import com.caucho.jca.cfg.AdminObjectConfig; 34 import com.caucho.jca.cfg.ConnectionDefinition; 35 import com.caucho.jca.cfg.ConnectorConfig; 36 import com.caucho.jca.cfg.MessageListenerConfig; 37 import com.caucho.jca.cfg.ResourceAdapterConfig; 38 import com.caucho.loader.DynamicClassLoader; 39 import com.caucho.loader.EnvironmentBean; 40 import com.caucho.log.Log; 41 import com.caucho.util.L10N; 42 import com.caucho.vfs.Jar; 43 import com.caucho.vfs.Path; 44 import com.caucho.vfs.ReadStream; 45 import com.caucho.vfs.WriteStream; 46 47 import javax.annotation.PostConstruct; 48 import java.io.IOException ; 49 import java.io.ObjectInputStream ; 50 import java.io.ObjectOutputStream ; 51 import java.util.logging.Level ; 52 import java.util.logging.Logger ; 53 import java.util.zip.ZipEntry ; 54 import java.util.zip.ZipInputStream ; 55 56 59 public class ResourceArchive implements EnvironmentBean { 60 static final L10N L = new L10N(ResourceArchive.class); 61 static final Logger log = Log.open(ResourceArchive.class); 62 63 private ClassLoader _loader; 64 65 private Path _rootDir; 66 67 private Path _rarPath; 68 69 private ConnectorConfig _config; 70 71 74 ResourceArchive() 75 { 76 _loader = Thread.currentThread().getContextClassLoader(); 77 } 78 79 82 public void setRootDirectory(Path rootDir) 83 { 84 _rootDir = rootDir; 85 } 86 87 90 public Path getRootDirectory() 91 { 92 return _rootDir; 93 } 94 95 98 public ClassLoader getClassLoader() 99 { 100 return _loader; 101 } 102 103 106 public void setRarPath(Path rarPath) 107 { 108 _rarPath = rarPath; 109 } 110 111 114 public String getDisplayName() 115 { 116 return _config.getDisplayName(); 117 } 118 119 122 public ResourceAdapterConfig getResourceAdapter() 123 { 124 return _config.getResourceAdapter(); 125 } 126 127 130 public String getTransactionSupport() 131 { 132 if (getResourceAdapter() != null) 133 return getResourceAdapter().getTransactionSupport(); 134 else 135 return null; 136 } 137 138 141 public ConnectionDefinition getConnectionDefinition(String type) 142 { 143 ResourceAdapterConfig raConfig = _config.getResourceAdapter(); 144 145 if (raConfig != null) 146 return raConfig.getConnectionDefinition(type); 147 else 148 return null; 149 } 150 151 154 public MessageListenerConfig getMessageListener(String type) 155 { 156 ResourceAdapterConfig raConfig = _config.getResourceAdapter(); 157 158 if (raConfig != null) 159 return raConfig.getMessageListener(type); 160 else 161 return null; 162 } 163 164 167 public AdminObjectConfig getAdminObject(String type) 168 { 169 ResourceAdapterConfig raConfig = _config.getResourceAdapter(); 170 171 if (raConfig != null) 172 return raConfig.getAdminObject(type); 173 else 174 return null; 175 } 176 177 180 @PostConstruct 181 public void init() 182 throws ConfigException 183 { 184 try { 185 expandRar(); 186 187 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 188 for (; loader != null; loader = loader.getParent()) { 189 if (loader instanceof DynamicClassLoader) 190 break; 191 } 192 193 if (loader == null) 194 throw new ConfigException(L.l("loader issues with resource adapter")); 195 196 addJars((DynamicClassLoader) loader, _rootDir); 197 198 Path raXml = _rootDir.lookup("META-INF/ra.xml"); 199 200 if (! raXml.canRead()) 201 throw new ConfigException(L.l("missing ra.xml for rar {0}. .rar files require a META-INF/ra.xml file.", 202 _rarPath)); 203 204 _config = new ConnectorConfig(); 205 206 new Config().configure(_config, raXml, "com/caucho/jca/jca.rnc"); 207 } catch (ConfigException e) { 208 throw e; 209 } catch (Exception e) { 210 throw new ConfigException(e); 211 } 212 213 log.info("ResourceArchive[" + _config.getDisplayName() + "] loaded"); 214 } 215 216 219 private void addJars(DynamicClassLoader loader, Path path) 220 throws IOException 221 { 222 if (path.getPath().endsWith(".jar")) { 223 loader.addJar(path); 224 } 225 else if (path.isDirectory()) { 226 String []list = path.list(); 227 228 for (int i = 0; i < list.length; i++) 229 addJars(loader, path.lookup(list[i])); 230 } 231 } 232 233 240 private void expandRar() 241 throws IOException 242 { 243 Path rar = _rarPath; 244 245 if (! rar.canRead()) 246 return; 247 248 try { 249 _rootDir.mkdirs(); 250 } catch (Throwable e) { 251 } 252 253 Path expandDir = _rootDir; 254 Path tempDir = _rootDir.getParent().lookup(".temp"); 255 Path dependPath = _rootDir.lookup("META-INF/resin-rar.timestamp"); 256 257 if (dependPath.canRead()) { 259 ReadStream is = null; 260 ObjectInputStream ois = null; 261 try { 262 is = dependPath.openRead(); 263 ois = new ObjectInputStream (is); 264 265 long lastModified = ois.readLong(); 266 long length = ois.readLong(); 267 268 if (lastModified == rar.getLastModified() && 269 length == rar.getLength()) 270 return; 271 } catch (IOException e) { 272 } finally { 273 try { 274 if (ois != null) 275 ois.close(); 276 } catch (IOException e) { 277 } 278 279 if (is != null) 280 is.close(); 281 } 282 } 283 284 try { 285 if (log.isLoggable(Level.INFO)) 286 log.info("expanding rar " + rar + " to " + tempDir); 287 288 289 if (! tempDir.equals(expandDir)) { 290 tempDir.removeAll(); 291 } 292 tempDir.mkdirs(); 293 294 ReadStream rs = rar.openRead(); 295 ZipInputStream zis = new ZipInputStream (rs); 296 297 try { 298 ZipEntry entry; 299 300 byte []buffer = new byte[1024]; 301 302 while ((entry = zis.getNextEntry()) != null) { 303 String name = entry.getName(); 304 Path path = tempDir.lookup(name); 305 306 if (entry.isDirectory()) 307 path.mkdirs(); 308 else { 309 long length = entry.getSize(); 310 long lastModified = entry.getTime(); 311 path.getParent().mkdirs(); 312 313 WriteStream os = path.openWrite(); 314 try { 315 int len; 316 while ((len = zis.read(buffer, 0, buffer.length)) > 0) 317 os.write(buffer, 0, len); 318 } catch (IOException e) { 319 log.log(Level.FINE, e.toString(), e); 320 } finally { 321 os.close(); 322 } 323 324 if (lastModified > 0) 325 path.setLastModified(lastModified); 326 } 327 } 328 } finally { 329 try { 330 zis.close(); 331 } catch (IOException e) { 332 } 333 334 rs.close(); 335 } 336 337 if (! tempDir.equals(expandDir)) { 338 if (log.isLoggable(Level.INFO)) 339 log.info("moving rar " + rar + " to " + expandDir); 340 341 try { 344 Jar.clearJarCache(); 345 removeAll(expandDir); 346 } catch (Throwable e) { 347 Jar.clearJarCache(); 348 removeAll(expandDir); 349 } 350 351 moveAll(tempDir, expandDir); 352 removeAll(tempDir); 353 } 354 } catch (IOException e) { 355 log.log(Level.WARNING, e.toString(), e); 356 return; 358 } 359 360 try { 361 dependPath.getParent().mkdirs(); 362 WriteStream os = dependPath.openWrite(); 363 ObjectOutputStream oos = new ObjectOutputStream (os); 364 365 oos.writeLong(rar.getLastModified()); 366 oos.writeLong(rar.getLength()); 367 oos.close(); 368 os.close(); 369 } catch (Throwable e) { 370 log.log(Level.WARNING, e.toString(), e); 371 } 372 } 373 374 380 private static void removeAll(Path path) 381 { 382 try { 383 if (path.isDirectory()) { 384 String []list = path.list(); 385 for (int i = 0; list != null && i < list.length; i++) { 386 removeAll(path.lookup(list[i])); 387 } 388 } 389 390 path.remove(); 391 } catch (Throwable e) { 392 log.log(Level.WARNING, e.toString(), e); 393 } 394 } 395 396 402 private static void moveAll(Path source, Path target) 403 { 404 try { 405 if (source.isDirectory()) { 406 try { 407 target.mkdirs(); 408 } catch (IOException e) { 409 } 410 411 String []list = source.list(); 412 for (int i = 0; list != null && i < list.length; i++) { 413 moveAll(source.lookup(list[i]), target.lookup(list[i])); 414 } 415 } 416 else 417 source.renameTo(target); 418 } catch (IOException e) { 419 log.log(Level.WARNING, e.toString(), e); 420 } 421 } 422 } 423 | Popular Tags |