1 17 18 package org.sape.carbon.services.config.jar; 19 20 import java.io.File ; 21 import java.io.IOException ; 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 import java.util.HashSet ; 25 import java.util.Iterator ; 26 import java.util.Set ; 27 import java.util.jar.JarEntry ; 28 29 import org.sape.carbon.core.config.InvalidConfigurationException; 30 import org.sape.carbon.core.config.format.ConfigurationFormatException; 31 import org.sape.carbon.core.config.format.DefaultConfigurationFormatService; 32 import org.sape.carbon.core.config.node.AbstractFolder; 33 import org.sape.carbon.core.config.node.ConfigurationDocument; 34 import org.sape.carbon.core.config.node.Node; 35 import org.sape.carbon.core.config.node.NodeCreationException; 36 import org.sape.carbon.core.config.node.NodeFactory; 37 import org.sape.carbon.core.config.node.NodeIOException; 38 import org.sape.carbon.core.config.node.NodeNotFoundException; 39 import org.sape.carbon.core.config.node.NodeRemovalException; 40 import org.sape.carbon.core.config.node.file.FileNodeFilter; 41 import org.sape.carbon.core.config.node.link.LinkNodeConfiguration; 42 import org.sape.carbon.core.config.node.link.LinkNodeFactory; 43 import org.sape.carbon.core.exception.IllegalStateException; 44 import org.sape.carbon.core.exception.InvalidParameterException; 45 import org.sape.carbon.core.util.jar.EnhancedJarFile; 46 import org.sape.carbon.core.util.thread.ReadWriteLock; 47 48 import org.apache.commons.logging.Log; 49 import org.apache.commons.logging.LogFactory; 50 51 59 public class JarFolder extends AbstractFolder { 60 61 64 private Log log = LogFactory.getLog(this.getClass()); 65 66 67 private File jarFile; 68 69 70 private String jarEntryName; 71 72 73 private EnhancedJarFile currentOpenJar = null; 74 78 private boolean jarOpenForRead; 79 80 81 private final ReadWriteLock readWriteLock; 82 83 87 private FileNodeFilter fileFilter = new FileNodeFilter(); 88 89 90 public static final String JAR_DELIMETER = "/"; 91 92 93 private static final Collection EXCLUDE_NODE_NAMES; 94 95 96 private static final String META_INF_DIR = "META-INF"; 97 98 99 private static final String CVS_DIR = "CVS"; 100 101 static { 102 EXCLUDE_NODE_NAMES = new ArrayList (); 103 EXCLUDE_NODE_NAMES.add(META_INF_DIR); 104 EXCLUDE_NODE_NAMES.add(CVS_DIR); 105 } 106 107 120 public JarFolder( 121 Node parent, 122 String name, 123 NodeFactory subFolderFactory, 124 NodeFactory configurationDocumentFactory, 125 NodeFactory linkNodeFactory, 126 ReadWriteLock readWriteLock, 127 File jarFile, 128 String jarEntryName) { 129 130 super( 131 parent, 132 name, 133 subFolderFactory, 134 configurationDocumentFactory, 135 linkNodeFactory); 136 137 if (jarFile != null) { 139 this.jarFile = jarFile; 140 } else { 141 throw new InvalidParameterException( 142 this.getClass(), 143 "The [" 144 + getAbsoluteName() 145 + "] JarFolder node jarFile reference cannot be null"); 146 } 147 148 if (!jarFile.exists() || jarFile.isDirectory()) { 149 throw new InvalidParameterException( 150 this.getClass(), 151 "jarFile does not exist or is a directory"); 152 } 153 154 if (readWriteLock != null) { 155 this.readWriteLock = readWriteLock; 156 } else { 157 throw new InvalidParameterException( 158 this.getClass(), 159 "The [" 160 + getAbsoluteName() 161 + "] JarFolder node readWriteLock reference " 162 + "cannot be null"); 163 } 164 165 this.jarEntryName = (jarEntryName == null ? "" : jarEntryName); 166 } 167 168 174 protected Node loadChild(String nodeName) 175 throws NodeNotFoundException { 176 177 EnhancedJarFile jar = null; 178 try { 179 jar = openJar(true); 180 String baseName = this.jarEntryName + nodeName; 181 182 Node child = null; 183 184 if (!JarFolder.EXCLUDE_NODE_NAMES.contains( 186 nodeName.toUpperCase())) { 187 188 189 JarEntry childEntry = (JarEntry ) 190 jar.getEntry(baseName + EnhancedJarFile.JAR_DELIMETER); 191 if (childEntry != null && childEntry.isDirectory()) { 194 child = loadSubFolder(nodeName); 195 } 196 197 childEntry = 198 (JarEntry ) jar.getEntry( 199 baseName + this.fileFilter.CONFIG_DOC_NODE_EXTENSION); 200 if (childEntry != null && !childEntry.isDirectory()) { 203 child = loadConfigurationDocument(nodeName); 204 } 205 206 childEntry = 207 (JarEntry ) jar.getEntry( 208 baseName + this.fileFilter.LINK_NODE_EXTENSION); 209 if (childEntry != null && !childEntry.isDirectory()) { 212 child = loadChildLinkNode(nodeName); 214 } 215 } 216 217 if (child == null) { 218 throw new NodeNotFoundException( 219 this.getClass(), 220 this.getAbsoluteName() + Node.DELIMITER + nodeName); 221 } 222 223 return child; 224 225 } catch (NodeCreationException nce) { 226 throw new NodeNotFoundException( 227 this.getClass(), 228 nodeName, 229 nce); 230 231 } catch (IOException ioe) { 232 throw new InvalidParameterException( 233 this.getClass(), 234 "Caught IOException accessing jar file: [" 235 + this.jarFile.getAbsolutePath() 236 + "]", 237 ioe); 238 239 } finally { 240 try { 242 if (jar != null) { 243 closeJar(); 244 } 245 } catch (IOException ioe) { 246 } 248 } 249 } 250 251 259 protected Set getAllChildNames() { 260 synchronized (getReadOrAlterNodeLock()) { 261 EnhancedJarFile jar = null; 262 try { 263 jar = openJar(true); 264 Iterator entries = 265 jar.listSubEntries(this.jarEntryName).iterator(); 266 267 Set childNames = new HashSet (); 268 269 while (entries.hasNext()) { 270 JarEntry nextEntry = (JarEntry ) entries.next(); 271 272 String childName = null; 273 String entryName = nextEntry.getName(); 274 275 if (nextEntry.isDirectory()) { 276 childName = 277 entryName.substring( 278 this.jarEntryName.length(), 279 entryName.lastIndexOf( 280 EnhancedJarFile.JAR_DELIMETER)); 281 282 } else if (entryName.endsWith( 283 this.fileFilter.CONFIG_DOC_NODE_EXTENSION)) { 284 285 childName = 286 entryName.substring( 287 this.jarEntryName.length(), 288 entryName.lastIndexOf( 289 this.fileFilter.CONFIG_DOC_NODE_EXTENSION)); 290 291 } else if (entryName.endsWith( 292 this.fileFilter.LINK_NODE_EXTENSION)) { 293 294 childName = 295 entryName.substring( 296 this.jarEntryName.length(), 297 entryName.lastIndexOf( 298 this.fileFilter.LINK_NODE_EXTENSION)); 299 } 300 301 if (childName != null 302 && !JarFolder.EXCLUDE_NODE_NAMES.contains( 303 childName.toUpperCase())) { 304 305 childNames.add(childName); 306 } 307 } 308 309 return childNames; 310 311 } catch (IOException ioe) { 312 throw new IllegalStateException ( 313 this.getClass(), 314 "Could not open jar file", 315 ioe); 316 317 } finally { 318 try { 320 if (jar != null) { 321 closeJar(); 322 } 323 } catch (IOException ioe) { 324 } 326 } 327 } 328 } 329 330 336 protected void destroyBackingData() throws NodeRemovalException { 337 } 338 339 342 protected boolean backingDataExists() { 343 return (this.jarFile.exists() && !this.jarFile.isDirectory()); 344 } 345 346 352 File getInternalJarFile() { 353 return this.jarFile; 354 } 355 356 362 String getInternalJarEntryName() { 363 return this.jarEntryName; 364 } 365 366 374 ReadWriteLock getReadWriteLock() { 375 return this.readWriteLock; 376 } 377 378 385 private Node loadSubFolder(String nodeName) 386 throws NodeCreationException { 387 return getSubFolderFactory().getInstance(this, nodeName); 388 } 389 390 398 private Node loadConfigurationDocument(String nodeName) 399 throws NodeCreationException { 400 401 return getConfigurationDocumentFactory().getInstance(this, nodeName); 402 } 403 404 412 private Node loadChildLinkNode(String nodeName) 413 throws NodeCreationException { 414 415 try { 416 417 ConfigurationDocument linkConfiguraitonDoc = 418 new JarConfigurationDocument( 419 this, 420 nodeName, 421 new DefaultConfigurationFormatService(), 422 this.readWriteLock, 423 this.jarFile, 424 this.jarEntryName 425 + nodeName 426 + this.fileFilter.LINK_NODE_EXTENSION); 427 428 LinkNodeConfiguration config = 429 (LinkNodeConfiguration) 430 linkConfiguraitonDoc.readConfiguration(); 431 432 if (config.getLinkNodeFactoryClass() == null) { 433 throw new InvalidConfigurationException( 434 this.getClass(), 435 config.getConfigurationName(), 436 "LinkNodeFactoryClass", 437 "Cannot be null"); 438 } 439 440 LinkNodeFactory factory = 441 (LinkNodeFactory) 442 config.getLinkNodeFactoryClass().newInstance(); 443 444 return factory.getInstance(this, nodeName, linkConfiguraitonDoc); 445 446 } catch (ConfigurationFormatException e) { 447 throw new NodeCreationException( 448 this.getClass(), 449 this, 450 nodeName, 451 "exception occured", 452 e); 453 } catch (NodeIOException e) { 454 throw new NodeCreationException( 455 this.getClass(), 456 this, 457 nodeName, 458 "exception occured", 459 e); 460 } catch (InstantiationException e) { 461 throw new NodeCreationException( 462 this.getClass(), 463 this, 464 nodeName, 465 "exception occured", 466 e); 467 } catch (IllegalAccessException e) { 468 throw new NodeCreationException( 469 this.getClass(), 470 this, 471 nodeName, 472 "exception occured", 473 e); 474 } 475 } 476 477 486 private EnhancedJarFile openJar(boolean forRead) throws IOException { 487 488 if (this.currentOpenJar != null) { 489 if (log.isWarnEnabled()) { 492 log.warn("Jar file [" + currentOpenJar.getName() 493 + "] has not been closed"); 494 } 495 496 } else { 497 try { 499 if (forRead) { 500 getReadWriteLock().readLock().acquire(); 501 this.jarOpenForRead = true; 502 } else { 503 getReadWriteLock().writeLock().acquire(); 504 this.jarOpenForRead = false; 505 } 506 } catch (InterruptedException ie) { 507 Thread.currentThread().interrupt(); 508 throw new IllegalStateException ( 509 this.getClass(), 510 "Caught interupt exception before acquiring jar monitor", 511 ie); 512 } 513 this.currentOpenJar = new EnhancedJarFile(this.jarFile); 515 } 516 517 return this.currentOpenJar; 518 } 519 520 526 private void closeJar() throws IOException { 527 if (this.currentOpenJar != null) { 528 529 try { 532 this.currentOpenJar.close(); 533 } catch (IOException ioe) { 534 throw ioe; 535 } finally { 536 this.currentOpenJar = null; 537 538 if (this.jarOpenForRead) { 539 getReadWriteLock().readLock().release(); 540 } else { 541 getReadWriteLock().writeLock().release(); 542 } 543 } 544 } 545 } 546 } | Popular Tags |