[jboss-cvs] JBossAS SVN: r74620 - in projects/vfs/tags: 2.0.0.Beta17 and 4 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Jun 16 10:28:54 EDT 2008
Author: alesj
Date: 2008-06-16 10:28:54 -0400 (Mon, 16 Jun 2008)
New Revision: 74620
Added:
projects/vfs/tags/2.0.0.Beta17/
projects/vfs/tags/2.0.0.Beta17/pom.xml
projects/vfs/tags/2.0.0.Beta17/release-pom.xml
projects/vfs/tags/2.0.0.Beta17/src/main/java/org/jboss/virtual/VFSUtils.java
projects/vfs/tags/2.0.0.Beta17/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java
projects/vfs/tags/2.0.0.Beta17/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java
projects/vfs/tags/2.0.0.Beta17/src/test/java/org/jboss/test/virtual/test/VFSUtilTestCase.java
projects/vfs/tags/2.0.0.Beta17/src/test/resources/vfs/test/badmf.jar
Removed:
projects/vfs/tags/2.0.0.Beta17/pom.xml
projects/vfs/tags/2.0.0.Beta17/src/main/java/org/jboss/virtual/VFSUtils.java
projects/vfs/tags/2.0.0.Beta17/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java
projects/vfs/tags/2.0.0.Beta17/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java
Log:
[maven-release-plugin] copy for tag 2.0.0.Beta17
Copied: projects/vfs/tags/2.0.0.Beta17 (from rev 74595, projects/vfs/trunk)
Deleted: projects/vfs/tags/2.0.0.Beta17/pom.xml
===================================================================
--- projects/vfs/trunk/pom.xml 2008-06-16 06:57:54 UTC (rev 74595)
+++ projects/vfs/tags/2.0.0.Beta17/pom.xml 2008-06-16 14:28:54 UTC (rev 74620)
@@ -1,121 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <parent>
- <groupId>org.jboss</groupId>
- <artifactId>jboss-parent</artifactId>
- <version>4-beta-2</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.jboss</groupId>
- <artifactId>jboss-vfs</artifactId>
- <packaging>jar</packaging>
- <version>2.0.0-SNAPSHOT</version>
- <name>JBoss VFS</name>
- <url>http://www.jboss.org</url>
- <description>A VFS library</description>
- <scm>
- <connection>scm:svn:http://anonsvn.jboss.org/repos/jbossas/projects/vfs/trunk</connection>
- <developerConnection>scm:svn:https://svn.jboss.org/repos/jbossas/projects/vfs/trunk</developerConnection>
- <url>https://svn.jboss.org/repos/jbossas/projects/vfs/trunk</url>
- </scm>
- <licenses>
- <license>
- <name>lgpl</name>
- <url>http://repository.jboss.org/licenses/lgpl.txt</url>
- </license>
- </licenses>
- <organization>
- <name>JBoss, A division of Red Hat, Inc</name>
- <url>http://www.jboss.org</url>
- </organization>
-
- <properties>
- <version.jboss.common.core>2.2.5.GA</version.jboss.common.core>
- <version.jboss.logging>2.0.5.GA</version.jboss.logging>
- <version.jboss.test>1.1.0.GA</version.jboss.test>
- <version.junit>4.4</version.junit>
- </properties>
-
- <build>
- <sourceDirectory>src/main/java</sourceDirectory>
- <testSourceDirectory>src/test/java</testSourceDirectory>
- <finalName>${artifactId}</finalName>
- <testResources>
- <testResource>
- <directory>src/test/resources</directory>
- </testResource>
- </testResources>
- <plugins>
-
- <!-- define how we want compilation to take place
- here, we accept most of the defaults but say that we want the
- optimization flag set, and define the source and target to be 1.5,
- these setting will be inherited by child projects -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>2.0</version>
- <configuration>
- <debug>true</debug>
- <source>1.5</source>
- <target>1.5</target>
- </configuration>
- </plugin>
- <!-- define that we wish to create src jars -->
- <plugin>
- <artifactId>maven-source-plugin</artifactId>
- <inherited>true</inherited>
- <executions>
- <execution>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.3.1</version>
- <configuration>
- <forkMode>always</forkMode> <!-- required to correctly run the PojoServer tests -->
- <useSystemClassLoader>true</useSystemClassLoader>
- <redirectTestOutputToFile>true</redirectTestOutputToFile>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-release-plugin</artifactId>
- <version>2.0-beta-7</version>
- <configuration>
- <tagBase>https://svn.jboss.org/repos/jbossas/projects/vfs/tags</tagBase>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.jboss</groupId>
- <artifactId>jboss-common-core</artifactId>
- <version>${version.jboss.common.core}</version>
- </dependency>
- <dependency>
- <groupId>org.jboss.logging</groupId>
- <artifactId>jboss-logging-spi</artifactId>
- <version>${version.jboss.logging}</version>
- </dependency>
- <dependency>
- <groupId>org.jboss.test</groupId>
- <artifactId>jboss-test</artifactId>
- <version>${version.jboss.test}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>${version.junit}</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-</project>
Copied: projects/vfs/tags/2.0.0.Beta17/pom.xml (from rev 74619, projects/vfs/trunk/pom.xml)
===================================================================
--- projects/vfs/tags/2.0.0.Beta17/pom.xml (rev 0)
+++ projects/vfs/tags/2.0.0.Beta17/pom.xml 2008-06-16 14:28:54 UTC (rev 74620)
@@ -0,0 +1,121 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.jboss</groupId>
+ <artifactId>jboss-parent</artifactId>
+ <version>4-beta-2</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.jboss</groupId>
+ <artifactId>jboss-vfs</artifactId>
+ <packaging>jar</packaging>
+ <version>2.0.0.Beta17</version>
+ <name>JBoss VFS</name>
+ <url>http://www.jboss.org</url>
+ <description>A VFS library</description>
+ <scm>
+ <connection>scm:svn:http://anonsvn.jboss.org/repos/jbossas/projects/vfs/tags/2.0.0.Beta17</connection>
+ <developerConnection>scm:svn:https://svn.jboss.org/repos/jbossas/projects/vfs/tags/2.0.0.Beta17</developerConnection>
+ <url>https://svn.jboss.org/repos/jbossas/projects/vfs/tags/2.0.0.Beta17</url>
+ </scm>
+ <licenses>
+ <license>
+ <name>lgpl</name>
+ <url>http://repository.jboss.org/licenses/lgpl.txt</url>
+ </license>
+ </licenses>
+ <organization>
+ <name>JBoss, A division of Red Hat, Inc</name>
+ <url>http://www.jboss.org</url>
+ </organization>
+
+ <properties>
+ <version.jboss.common.core>2.2.5.GA</version.jboss.common.core>
+ <version.jboss.logging>2.0.5.GA</version.jboss.logging>
+ <version.jboss.test>1.1.0.GA</version.jboss.test>
+ <version.junit>4.4</version.junit>
+ </properties>
+
+ <build>
+ <sourceDirectory>src/main/java</sourceDirectory>
+ <testSourceDirectory>src/test/java</testSourceDirectory>
+ <finalName>${artifactId}</finalName>
+ <testResources>
+ <testResource>
+ <directory>src/test/resources</directory>
+ </testResource>
+ </testResources>
+ <plugins>
+
+ <!-- define how we want compilation to take place
+ here, we accept most of the defaults but say that we want the
+ optimization flag set, and define the source and target to be 1.5,
+ these setting will be inherited by child projects -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0</version>
+ <configuration>
+ <debug>true</debug>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <!-- define that we wish to create src jars -->
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <inherited>true</inherited>
+ <executions>
+ <execution>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.3.1</version>
+ <configuration>
+ <forkMode>always</forkMode> <!-- required to correctly run the PojoServer tests -->
+ <useSystemClassLoader>true</useSystemClassLoader>
+ <redirectTestOutputToFile>true</redirectTestOutputToFile>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <version>2.0-beta-7</version>
+ <configuration>
+ <tagBase>https://svn.jboss.org/repos/jbossas/projects/vfs/tags</tagBase>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss</groupId>
+ <artifactId>jboss-common-core</artifactId>
+ <version>${version.jboss.common.core}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging-spi</artifactId>
+ <version>${version.jboss.logging}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.test</groupId>
+ <artifactId>jboss-test</artifactId>
+ <version>${version.jboss.test}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${version.junit}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
Copied: projects/vfs/tags/2.0.0.Beta17/release-pom.xml (from rev 74619, projects/vfs/trunk/release-pom.xml)
===================================================================
--- projects/vfs/tags/2.0.0.Beta17/release-pom.xml (rev 0)
+++ projects/vfs/tags/2.0.0.Beta17/release-pom.xml 2008-06-16 14:28:54 UTC (rev 74620)
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.jboss</groupId>
+ <artifactId>jboss-vfs</artifactId>
+ <name>JBoss VFS</name>
+ <version>2.0.0.Beta17</version>
+ <description>A VFS library</description>
+ <url>http://www.jboss.org</url>
+ <issueManagement>
+ <system>jira</system>
+ <url>http://jira.jboss.com/</url>
+ </issueManagement>
+ <licenses>
+ <license>
+ <name>lgpl</name>
+ <url>http://repository.jboss.org/licenses/lgpl.txt</url>
+ </license>
+ </licenses>
+ <scm>
+ <connection>https://svn.jboss.org/repos/jbossas/projects/vfs/tags/2.0.0.Beta17</connection>
+ <developerConnection>https://svn.jboss.org/repos/jbossas/projects/vfs/tags/2.0.0.Beta17</developerConnection>
+ <url>https://svn.jboss.org/repos/jbossas/projects/vfs/tags/2.0.0.Beta17</url>
+ </scm>
+ <organization>
+ <name>JBoss, A division of Red Hat, Inc</name>
+ <url>http://www.jboss.org</url>
+ </organization>
+ <build>
+ <sourceDirectory>src/main/java</sourceDirectory>
+ <scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
+ <testSourceDirectory>src/test/java</testSourceDirectory>
+ <outputDirectory>target/classes</outputDirectory>
+ <testOutputDirectory>target/test-classes</testOutputDirectory>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <testResources>
+ <testResource>
+ <directory>src/test/resources</directory>
+ </testResource>
+ </testResources>
+ <directory>target</directory>
+ <finalName>jboss-vfs</finalName>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0</version>
+ <configuration>
+ <debug>true</debug>
+ <source>1.5</source>
+ <target>1.5</target>
+ <showDeprecation>true</showDeprecation>
+ <showWarnings>true</showWarnings>
+ <optimize>true</optimize>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.0.3</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ <execution>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ <inherited>true</inherited>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.3.1</version>
+ <configuration>
+ <forkMode>always</forkMode>
+ <useSystemClassLoader>true</useSystemClassLoader>
+ <redirectTestOutputToFile>true</redirectTestOutputToFile>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-release-plugin</artifactId>
+ <version>2.0-beta-7</version>
+ <configuration>
+ <tagBase>https://svn.jboss.org/repos/jbossas/projects/vfs/tags</tagBase>
+ <generateReleasePoms>true</generateReleasePoms>
+ <useReleaseProfile>false</useReleaseProfile>
+ <arguments>-Prelease</arguments>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <repositories>
+ <repository>
+ <snapshots />
+ <id>snapshots.jboss.org</id>
+ <url>http://snapshots.jboss.org/maven2</url>
+ </repository>
+ <repository>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ <id>repository.jboss.org</id>
+ <url>http://repository.jboss.org/maven2</url>
+ </repository>
+ <repository>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ <id>central</id>
+ <name>Maven Repository Switchboard</name>
+ <url>http://repo1.maven.org/maven2</url>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ <id>repository.jboss.org</id>
+ <url>http://repository.jboss.org/maven2</url>
+ </pluginRepository>
+ <pluginRepository>
+ <snapshots />
+ <id>snapshots.jboss.org</id>
+ <url>http://snapshots.jboss.org/maven2</url>
+ </pluginRepository>
+ <pluginRepository>
+ <releases>
+ <updatePolicy>never</updatePolicy>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ <id>central</id>
+ <name>Maven Plugin Repository</name>
+ <url>http://repo1.maven.org/maven2</url>
+ </pluginRepository>
+ </pluginRepositories>
+ <dependencies>
+ <dependency>
+ <groupId>apache-log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.14</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>jboss.profiler.jvmti</groupId>
+ <artifactId>jboss-profiler-jvmti</artifactId>
+ <version>1.0.0.CR5</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.4</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.7.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-junit</artifactId>
+ <version>1.7.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-launcher</artifactId>
+ <version>1.7.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss</groupId>
+ <artifactId>jboss-common-core</artifactId>
+ <version>2.2.5.GA</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.jbossas</groupId>
+ <artifactId>jboss-server-manager</artifactId>
+ <version>0.1.0.GA</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging-log4j</artifactId>
+ <version>2.0.5.GA</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging-spi</artifactId>
+ <version>2.0.5.GA</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.test</groupId>
+ <artifactId>jboss-test</artifactId>
+ <version>1.1.0.GA</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <reporting>
+ <outputDirectory>target/site</outputDirectory>
+ <plugins>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.2</version>
+ <configuration>
+ <links>
+ <link>http://java.sun.com/j2se/1.5.0/docs/api</link>
+ </links>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-project-info-reports-plugin</artifactId>
+ <version>2.0.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ <version>2.3</version>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>report-only</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>taglist-maven-plugin</artifactId>
+ <version>2.0</version>
+ </plugin>
+ </plugins>
+ </reporting>
+ <distributionManagement>
+ <repository>
+ <id>repository.jboss.org</id>
+ <url>file:///projects/repository/maven2</url>
+ </repository>
+ <snapshotRepository>
+ <id>snapshots.jboss.org</id>
+ <name>JBoss Snapshot Repository</name>
+ <url>dav:https://snapshots.jboss.org/maven2</url>
+ </snapshotRepository>
+ </distributionManagement>
+ <properties>
+ <maven.repository.root>/projects/repository/maven2</maven.repository.root>
+ <version.junit>4.4</version.junit>
+ <jboss.repository.root>/projects/repository/jboss</jboss.repository.root>
+ <version.jboss.logging>2.0.5.GA</version.jboss.logging>
+ <version.jboss.test>1.1.0.GA</version.jboss.test>
+ <version.jboss.common.core>2.2.5.GA</version.jboss.common.core>
+ </properties>
+</project>
\ No newline at end of file
Deleted: projects/vfs/tags/2.0.0.Beta17/src/main/java/org/jboss/virtual/VFSUtils.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/VFSUtils.java 2008-06-16 06:57:54 UTC (rev 74595)
+++ projects/vfs/tags/2.0.0.Beta17/src/main/java/org/jboss/virtual/VFSUtils.java 2008-06-16 14:28:54 UTC (rev 74620)
@@ -1,610 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.virtual;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.StringTokenizer;
-import java.util.jar.Attributes;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-
-import org.jboss.logging.Logger;
-import org.jboss.util.StringPropertyReplacer;
-import org.jboss.util.collection.CollectionsFactory;
-import org.jboss.virtual.plugins.copy.CopyMechanism;
-import org.jboss.virtual.plugins.copy.ExplodedCopyMechanism;
-import org.jboss.virtual.plugins.copy.TempCopyMechanism;
-import org.jboss.virtual.plugins.copy.UnpackCopyMechanism;
-import org.jboss.virtual.spi.LinkInfo;
-import org.jboss.virtual.spi.VFSContext;
-import org.jboss.virtual.spi.VirtualFileHandler;
-
-/**
- * VFS Utilities
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @author <a href="ales.justin at jboss.com">Ales Justin</a>
- * @version $Revision: 1.1 $
- */
-public class VFSUtils
-{
- /** The log */
- private static final Logger log = Logger.getLogger(VFSUtils.class);
- /** The link */
- public static final String VFS_LINK_PREFIX = ".vfslink";
- /** The link name */
- public static final String VFS_LINK_NAME = "vfs.link.name";
- /** The link target */
- public static final String VFS_LINK_TARGET = "vfs.link.target";
-
- /**
- * The system no force copy key / query
- */
- public static final String FORCE_COPY_KEY = "jboss.vfs.forceCopy";
- public static final String USE_COPY_QUERY = "useCopyJarHandler";
-
- /**
- * Key used to force fallback from vfszip (default) to vfsjar
- */
- public static final String FORCE_VFS_JAR_KEY = "jboss.vfs.forceVfsJar";
-
- /**
- * Key used to turn off reaper mode in vfszip - forcing synchronous (slower) handling of files
- */
- public static final String FORCE_NO_REAPER_KEY = "jboss.vfs.forceNoReaper";
- public static final String NO_REAPER_QUERY = "noReaper";
-
- /**
- * Key used to force case sensitive path checking in vfsfile
- */
- public static final String FORCE_CASE_SENSITIVE_KEY = "jboss.vfs.forceCaseSensitive";
- public static final String CASE_SENSITIVE_QUERY = "caseSensitive";
-
- /**
- * Key used to turn on memory optimizations - less cache use at the expense of performance
- */
- public static final String OPTIMIZE_FOR_MEMORY_KEY = "jboss.vfs.optimizeForMemory";
-
- /**
- * Get the paths string for a collection of virtual files
- *
- * @param paths the paths
- * @return the string
- * @throws IllegalArgumentException for null paths
- */
- public static String getPathsString(Collection<VirtualFile> paths)
- {
- if (paths == null)
- throw new IllegalArgumentException("Null paths");
-
- StringBuilder buffer = new StringBuilder();
- boolean first = true;
- for (VirtualFile path : paths)
- {
- if (path == null)
- throw new IllegalArgumentException("Null path in " + paths);
- if (first == false)
- buffer.append(':');
- else
- first = false;
- buffer.append(path.getPathName());
- }
-
- if (first == true)
- buffer.append("<empty>");
-
- return buffer.toString();
- }
-
- /**
- * Add manifest paths
- *
- * @param file the file
- * @param paths the paths to add to
- * @throws IOException if there is an error reading the manifest or the
- * virtual file is closed
- * @throws IllegalStateException if the file has no parent
- * @throws IllegalArgumentException for a null file or paths
- */
- public static void addManifestLocations(VirtualFile file, List<VirtualFile> paths) throws IOException
- {
- if (file == null)
- throw new IllegalArgumentException("Null file");
- if (paths == null)
- throw new IllegalArgumentException("Null paths");
-
- Manifest manifest = getManifest(file);
- if (manifest == null)
- return;
-
- Attributes mainAttributes = manifest.getMainAttributes();
- String classPath = mainAttributes.getValue(Attributes.Name.CLASS_PATH);
-
- if (classPath == null)
- {
- if (log.isTraceEnabled())
- log.trace("Manifest has no Class-Path for " + file.getPathName());
- return;
- }
-
- VirtualFile parent = file.getParent();
- if (parent == null)
- throw new IllegalStateException(file + " has no parent.");
-
- URL parentURL;
- URL vfsRootURL;
- int rootPathLength;
- try
- {
- parentURL = parent.toURL();
- vfsRootURL = file.getVFS().getRoot().toURL();
- rootPathLength = vfsRootURL.getPath().length();
- }
- catch(URISyntaxException e)
- {
- IOException ioe = new IOException("Failed to get parent URL for " + file);
- ioe.initCause(e);
- throw ioe;
- }
-
- StringTokenizer tokenizer = new StringTokenizer(classPath);
- while (tokenizer.hasMoreTokens())
- {
- String path = tokenizer.nextToken();
- try
- {
- String parentPath = parentURL.toString();
- if(parentPath.endsWith("/") == false)
- parentPath += "/";
- URL libURL = new URL(parentPath + path);
- String libPath = libURL.getPath();
- // TODO, this occurs for inner jars. Doubtful that such a mf cp is valid
- if( rootPathLength > libPath.length() )
- throw new IOException("Invalid rootPath: "+vfsRootURL+", libPath: "+libPath);
-
- String vfsLibPath = libPath.substring(rootPathLength);
- VirtualFile vf = file.getVFS().getChild(vfsLibPath);
- if(vf != null)
- {
- if(paths.contains(vf) == false)
- {
- paths.add(vf);
- // Recursively process the jar
- addManifestLocations(vf, paths);
- }
- }
- }
- catch (IOException e)
- {
- log.debug("Manifest Class-Path entry " + path + " ignored for " + file.getPathName() + " reason=" + e);
- }
- }
- }
-
- /**
- * Get a manifest from a virtual file,
- * assuming the virtual file is the root of an archive
- *
- * @param archive the root the archive
- * @return the manifest or null if not found
- * @throws IOException if there is an error reading the manifest or the
- * virtual file is closed
- * @throws IllegalArgumentException for a null archive
- */
- public static Manifest getManifest(VirtualFile archive) throws IOException
- {
- if (archive == null)
- throw new IllegalArgumentException("Null archive");
-
- VirtualFile manifest = archive.getChild(JarFile.MANIFEST_NAME);
- if (manifest == null)
- {
- if (log.isTraceEnabled())
- log.trace("Can't find manifest for " + archive.getPathName());
- return null;
- }
- return readManifest(manifest);
- }
-
- /**
- * Read the manifest from given manifest VirtualFile.
- *
- * @param manifest the VF to read from
- * @return JAR's manifest
- * @throws IOException if problems while opening VF stream occur
- */
- public static Manifest readManifest(VirtualFile manifest) throws IOException
- {
- if (manifest == null)
- throw new IllegalArgumentException("Null manifest file");
-
- InputStream stream = manifest.openStream();
- try
- {
- return new Manifest(stream);
- }
- finally
- {
- try
- {
- stream.close();
- }
- catch (IOException ignored)
- {
- }
- }
- }
-
- /**
- * Get a manifest from a virtual file system,
- * assuming the root of the VFS is the root of an archive
- *
- * @param archive the vfs
- * @return the manifest or null if not found
- * @throws IOException if there is an error reading the manifest
- * @throws IllegalArgumentException for a null archive
- */
- public static Manifest getManifest(VFS archive) throws IOException
- {
- if (archive == null)
- throw new IllegalArgumentException("Null vfs archive");
-
- VirtualFile root = archive.getRoot();
- return getManifest(root);
- }
-
- /**
- * Fix a name (removes any trailing slash)
- *
- * @param name the name to fix
- * @return the fixed name
- * @throws IllegalArgumentException for a null name
- */
- public static String fixName(String name)
- {
- if (name == null)
- throw new IllegalArgumentException("Null name");
-
- int length = name.length();
- if (length <= 1)
- return name;
- if (name.charAt(length-1) == '/')
- return name.substring(0, length-1);
- return name;
- }
-
- /**
- * Get the name.
- *
- * @param uri the uri
- * @return name from uri's path
- */
- public static String getName(URI uri)
- {
- if (uri == null)
- throw new IllegalArgumentException("Null uri");
-
- String name = uri.getPath();
- if( name != null )
- {
- // TODO: Not correct for certain uris like jar:...!/
- int lastSlash = name.lastIndexOf('/');
- if( lastSlash > 0 )
- name = name.substring(lastSlash+1);
- }
- return name;
- }
-
- /**
- * Take a URL.getQuery string and parse it into name=value pairs
- *
- * @param query Possibly empty/null url query string
- * @return String[] for the name/value pairs in the query. May be empty but never null.
- */
- public static Map<String, String> parseURLQuery(String query)
- {
- Map<String, String> pairsMap = CollectionsFactory.createLazyMap();
- if(query != null)
- {
- StringTokenizer tokenizer = new StringTokenizer(query, "=&");
- while(tokenizer.hasMoreTokens())
- {
- String name = tokenizer.nextToken();
- String value = tokenizer.nextToken();
- pairsMap.put(name, value);
- }
- }
- return pairsMap;
- }
-
- /**
- * Does a vf name contain the VFS link prefix
- * @param name - the name portion of a virtual file
- * @return true if the name starts with VFS_LINK_PREFIX, false otherwise
- */
- public static boolean isLink(String name)
- {
- if (name == null)
- throw new IllegalArgumentException("Null name");
-
- return name.indexOf(VFS_LINK_PREFIX) >= 0;
- }
-
- /**
- * Read the link information from the stream based on the type as determined
- * from the name suffix.
- *
- * @param is - input stream to the link file contents
- * @param name - the name of the virtual file representing the link
- * @param props the propertes
- * @return a list of the links read from the stream
- * @throws IOException on failure to read/parse the stream
- * @throws URISyntaxException for an error parsing a URI
- */
- public static List<LinkInfo> readLinkInfo(InputStream is, String name, Properties props)
- throws IOException, URISyntaxException
- {
- if (name == null)
- throw new IllegalArgumentException("Null name");
-
- if(name.endsWith(".properties"))
- {
- List<LinkInfo> info = new ArrayList<LinkInfo>();
- parseLinkProperties(is, info, props);
- return info;
- }
- else
- throw new UnsupportedEncodingException("Unknown link format: " + name);
- }
-
- /**
- * Parse a properties link file
- *
- * @param is - input stream to the link file contents
- * @param info the link infos
- * @param props the propertes
- * @throws IOException on failure to read/parse the stream
- * @throws URISyntaxException for an error parsing a URI
- */
- public static void parseLinkProperties(InputStream is, List<LinkInfo> info, Properties props)
- throws IOException, URISyntaxException
- {
- if (is == null)
- throw new IllegalArgumentException("Null input stream");
- if (info == null)
- throw new IllegalArgumentException("Null info");
- if (props == null)
- throw new IllegalArgumentException("Null properties");
-
- props.load(is);
- // Iterate over the property tuples
- for(int n = 0; ; n ++)
- {
- String nameKey = VFS_LINK_NAME + "." + n;
- String name = props.getProperty(nameKey);
- String uriKey = VFS_LINK_TARGET + "." + n;
- String uri = props.getProperty(uriKey);
- // End when the value is null since a link may not have a name
- if (uri == null)
- {
- break;
- }
- // Replace any system property references
- uri = StringPropertyReplacer.replaceProperties(uri);
- LinkInfo link = new LinkInfo(name, new URI(uri));
- info.add(link);
- }
- }
-
- /**
- * Deal with urls that may include spaces.
- *
- * @param url the url
- * @return uri the uri
- * @throws URISyntaxException for any error
- */
- public static URI toURI(URL url) throws URISyntaxException
- {
- if (url == null)
- throw new IllegalArgumentException("Null url");
-
- String urispec = url.toExternalForm();
- // Escape any spaces
- urispec = urispec.replaceAll(" ", "%20");
- return new URI(urispec);
- }
-
- /**
- * Get the options for this file.
- *
- * @param file the file
- * @return options map
- */
- private static Map<String, String> getOptions(VirtualFile file)
- {
- if (file == null)
- throw new IllegalArgumentException("Null file");
-
- VirtualFileHandler handler = file.getHandler();
- VFSContext context = handler.getVFSContext();
- return context.getOptions();
- }
-
- /**
- * Get the option.
- *
- * @param file the file
- * @param key the option key
- * @return key's option
- */
- public static String getOption(VirtualFile file, String key)
- {
- Map<String, String> options = getOptions(file);
- return options != null ? options.get(key) : null;
- }
-
- /**
- * Enable copy for file param.
- *
- * @param file the file
- */
- public static void enableCopy(VirtualFile file)
- {
- Map<String, String> options = getOptions(file);
- if (options == null)
- throw new IllegalArgumentException("Cannot enable copy on null options: " + file);
-
- options.put(USE_COPY_QUERY, Boolean.TRUE.toString());
- }
-
- /**
- * Disable copy for file param.
- *
- * @param file the file
- */
- public static void disableCopy(VirtualFile file)
- {
- Map<String, String> options = getOptions(file);
- if (options == null)
- throw new IllegalArgumentException("Cannot disable copy on null options: " + file);
-
- options.remove(USE_COPY_QUERY);
- }
-
- /**
- * Unpack the nested artifact under file param.
- *
- * @param file the file to unpack
- * @return unpacked file
- * @throws IOException for any io error
- * @throws URISyntaxException for any uri error
- */
- public static VirtualFile unpack(VirtualFile file) throws IOException, URISyntaxException
- {
- return copy(file, UnpackCopyMechanism.INSTANCE);
- }
-
- /**
- * Force explode.
- * Explode archives or nested entries.
- *
- * @param file the file to explode
- * @return exploded file
- * @throws IOException for any io error
- * @throws URISyntaxException for any uri error
- */
- public static VirtualFile explode(VirtualFile file) throws IOException, URISyntaxException
- {
- return copy(file, ExplodedCopyMechanism.INSTANCE);
- }
-
- /**
- * Create temp.
- *
- * @param file the file to temp
- * @return temp file
- * @throws IOException for any io error
- * @throws URISyntaxException for any uri error
- */
- public static VirtualFile temp(VirtualFile file) throws IOException, URISyntaxException
- {
- return copy(file, TempCopyMechanism.INSTANCE);
- }
-
- /**
- * Create temp.
- *
- * @param file the file to unpack/explode
- * @param mechanism the copy mechanism
- * @return temp file
- * @throws IOException for any io error
- * @throws URISyntaxException for any uri error
- */
- protected static VirtualFile copy(VirtualFile file, CopyMechanism mechanism) throws IOException, URISyntaxException
- {
- if (file == null)
- throw new IllegalArgumentException("Null file");
- if (mechanism == null)
- throw new IllegalArgumentException("Null copy mechanism");
-
- return mechanism.copy(file, file.getHandler());
- }
-
- /**
- * Is file handle nested.
- *
- * @param file the file handle to check
- * @return true if file/dir is nested otherwise false
- * @throws IOException for any error
- */
- public static boolean isNestedFile(VirtualFile file) throws IOException
- {
- if (file == null)
- throw new IllegalArgumentException("Null file");
-
- VirtualFileHandler handler = file.getHandler();
- return handler.isNested();
- }
-
- /**
- * Get spec compatilbe url from virtual file.
- *
- * @param file the virtual file
- * @return spec compatible url
- * @throws IOException for any error
- * @throws URISyntaxException for any uri syntax error
- */
- public static URL getCompatibleURL(VirtualFile file) throws IOException, URISyntaxException
- {
- if (file == null)
- throw new IllegalArgumentException("Null file");
-
- URL url = file.toURL();
- if (url == null)
- throw new IllegalArgumentException("Null url: " + file);
-
- // is not nested, so direct VFS URL is not an option
- if (isNestedFile(file) == false)
- {
- String urlString = url.toExternalForm();
- if (urlString.startsWith("vfs"))
- {
- // treat vfszip as file
- if (urlString.startsWith("vfszip"))
- url = new URL("file" + urlString.substring(6));
- else
- url = new URL(urlString.substring(3)); // (vfs)file and (vfs)jar are ok
- }
- }
- return url;
- }
-}
Copied: projects/vfs/tags/2.0.0.Beta17/src/main/java/org/jboss/virtual/VFSUtils.java (from rev 74599, projects/vfs/trunk/src/main/java/org/jboss/virtual/VFSUtils.java)
===================================================================
--- projects/vfs/tags/2.0.0.Beta17/src/main/java/org/jboss/virtual/VFSUtils.java (rev 0)
+++ projects/vfs/tags/2.0.0.Beta17/src/main/java/org/jboss/virtual/VFSUtils.java 2008-06-16 14:28:54 UTC (rev 74620)
@@ -0,0 +1,615 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.virtual;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.jboss.logging.Logger;
+import org.jboss.util.StringPropertyReplacer;
+import org.jboss.util.collection.CollectionsFactory;
+import org.jboss.virtual.plugins.copy.CopyMechanism;
+import org.jboss.virtual.plugins.copy.ExplodedCopyMechanism;
+import org.jboss.virtual.plugins.copy.TempCopyMechanism;
+import org.jboss.virtual.plugins.copy.UnpackCopyMechanism;
+import org.jboss.virtual.spi.LinkInfo;
+import org.jboss.virtual.spi.VFSContext;
+import org.jboss.virtual.spi.VirtualFileHandler;
+
+/**
+ * VFS Utilities
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ * @version $Revision: 1.1 $
+ */
+public class VFSUtils
+{
+ /** The log */
+ private static final Logger log = Logger.getLogger(VFSUtils.class);
+ /** The link */
+ public static final String VFS_LINK_PREFIX = ".vfslink";
+ /** The link name */
+ public static final String VFS_LINK_NAME = "vfs.link.name";
+ /** The link target */
+ public static final String VFS_LINK_TARGET = "vfs.link.target";
+
+ /**
+ * The system no force copy key / query
+ */
+ public static final String FORCE_COPY_KEY = "jboss.vfs.forceCopy";
+ public static final String USE_COPY_QUERY = "useCopyJarHandler";
+
+ /**
+ * Key used to force fallback from vfszip (default) to vfsjar
+ */
+ public static final String FORCE_VFS_JAR_KEY = "jboss.vfs.forceVfsJar";
+
+ /**
+ * Key used to turn off reaper mode in vfszip - forcing synchronous (slower) handling of files
+ */
+ public static final String FORCE_NO_REAPER_KEY = "jboss.vfs.forceNoReaper";
+ public static final String NO_REAPER_QUERY = "noReaper";
+
+ /**
+ * Key used to force case sensitive path checking in vfsfile
+ */
+ public static final String FORCE_CASE_SENSITIVE_KEY = "jboss.vfs.forceCaseSensitive";
+ public static final String CASE_SENSITIVE_QUERY = "caseSensitive";
+
+ /**
+ * Key used to turn on memory optimizations - less cache use at the expense of performance
+ */
+ public static final String OPTIMIZE_FOR_MEMORY_KEY = "jboss.vfs.optimizeForMemory";
+
+ /**
+ * Get the paths string for a collection of virtual files
+ *
+ * @param paths the paths
+ * @return the string
+ * @throws IllegalArgumentException for null paths
+ */
+ public static String getPathsString(Collection<VirtualFile> paths)
+ {
+ if (paths == null)
+ throw new IllegalArgumentException("Null paths");
+
+ StringBuilder buffer = new StringBuilder();
+ boolean first = true;
+ for (VirtualFile path : paths)
+ {
+ if (path == null)
+ throw new IllegalArgumentException("Null path in " + paths);
+ if (first == false)
+ buffer.append(':');
+ else
+ first = false;
+ buffer.append(path.getPathName());
+ }
+
+ if (first == true)
+ buffer.append("<empty>");
+
+ return buffer.toString();
+ }
+
+ /**
+ * Add manifest paths
+ *
+ * @param file the file
+ * @param paths the paths to add to
+ * @throws IOException if there is an error reading the manifest or the
+ * virtual file is closed
+ * @throws IllegalStateException if the file has no parent
+ * @throws IllegalArgumentException for a null file or paths
+ */
+ public static void addManifestLocations(VirtualFile file, List<VirtualFile> paths) throws IOException
+ {
+ if (file == null)
+ throw new IllegalArgumentException("Null file");
+ if (paths == null)
+ throw new IllegalArgumentException("Null paths");
+
+ Manifest manifest = getManifest(file);
+ if (manifest == null)
+ return;
+
+ Attributes mainAttributes = manifest.getMainAttributes();
+ String classPath = mainAttributes.getValue(Attributes.Name.CLASS_PATH);
+
+ if (classPath == null)
+ {
+ if (log.isTraceEnabled())
+ log.trace("Manifest has no Class-Path for " + file.getPathName());
+ return;
+ }
+
+ VirtualFile parent = file.getParent();
+ if (parent == null)
+ {
+ log.debug(file + " has no parent.");
+ return;
+ }
+
+ URL parentURL;
+ URL vfsRootURL;
+ int rootPathLength;
+ try
+ {
+ parentURL = parent.toURL();
+ vfsRootURL = file.getVFS().getRoot().toURL();
+ rootPathLength = vfsRootURL.getPath().length();
+ }
+ catch(URISyntaxException e)
+ {
+ log.debug("Failed to get parent URL for " + file + ", reason=" + e);
+ return;
+ }
+
+ String parentPath = parentURL.toString();
+ if(parentPath.endsWith("/") == false)
+ parentPath += "/";
+
+ StringTokenizer tokenizer = new StringTokenizer(classPath);
+ while (tokenizer.hasMoreTokens())
+ {
+ String path = tokenizer.nextToken();
+ try
+ {
+ URL libURL = new URL(parentPath + path);
+ String libPath = libURL.getPath();
+ if(rootPathLength > libPath.length())
+ {
+ log.debug("Invalid rootPath: " + vfsRootURL + ", libPath: " + libPath);
+ continue;
+ }
+
+ String vfsLibPath = libPath.substring(rootPathLength);
+ VirtualFile vf = file.getVFS().getChild(vfsLibPath);
+ if(vf != null)
+ {
+ if(paths.contains(vf) == false)
+ {
+ paths.add(vf);
+ // Recursively process the jar
+ addManifestLocations(vf, paths);
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ log.debug("Manifest Class-Path entry " + path + " ignored for " + file.getPathName() + " reason=" + e);
+ }
+ }
+ }
+
+ /**
+ * Get a manifest from a virtual file,
+ * assuming the virtual file is the root of an archive
+ *
+ * @param archive the root the archive
+ * @return the manifest or null if not found
+ * @throws IOException if there is an error reading the manifest or the
+ * virtual file is closed
+ * @throws IllegalArgumentException for a null archive
+ */
+ public static Manifest getManifest(VirtualFile archive) throws IOException
+ {
+ if (archive == null)
+ throw new IllegalArgumentException("Null archive");
+
+ VirtualFile manifest = archive.getChild(JarFile.MANIFEST_NAME);
+ if (manifest == null)
+ {
+ if (log.isTraceEnabled())
+ log.trace("Can't find manifest for " + archive.getPathName());
+ return null;
+ }
+ return readManifest(manifest);
+ }
+
+ /**
+ * Read the manifest from given manifest VirtualFile.
+ *
+ * @param manifest the VF to read from
+ * @return JAR's manifest
+ * @throws IOException if problems while opening VF stream occur
+ */
+ public static Manifest readManifest(VirtualFile manifest) throws IOException
+ {
+ if (manifest == null)
+ throw new IllegalArgumentException("Null manifest file");
+
+ InputStream stream = manifest.openStream();
+ try
+ {
+ return new Manifest(stream);
+ }
+ finally
+ {
+ try
+ {
+ stream.close();
+ }
+ catch (IOException ignored)
+ {
+ }
+ }
+ }
+
+ /**
+ * Get a manifest from a virtual file system,
+ * assuming the root of the VFS is the root of an archive
+ *
+ * @param archive the vfs
+ * @return the manifest or null if not found
+ * @throws IOException if there is an error reading the manifest
+ * @throws IllegalArgumentException for a null archive
+ */
+ public static Manifest getManifest(VFS archive) throws IOException
+ {
+ if (archive == null)
+ throw new IllegalArgumentException("Null vfs archive");
+
+ VirtualFile root = archive.getRoot();
+ return getManifest(root);
+ }
+
+ /**
+ * Fix a name (removes any trailing slash)
+ *
+ * @param name the name to fix
+ * @return the fixed name
+ * @throws IllegalArgumentException for a null name
+ */
+ public static String fixName(String name)
+ {
+ if (name == null)
+ throw new IllegalArgumentException("Null name");
+
+ int length = name.length();
+ if (length <= 1)
+ return name;
+ if (name.charAt(length-1) == '/')
+ return name.substring(0, length-1);
+ return name;
+ }
+
+ /**
+ * Get the name.
+ *
+ * @param uri the uri
+ * @return name from uri's path
+ */
+ public static String getName(URI uri)
+ {
+ if (uri == null)
+ throw new IllegalArgumentException("Null uri");
+
+ String name = uri.getPath();
+ if( name != null )
+ {
+ // TODO: Not correct for certain uris like jar:...!/
+ int lastSlash = name.lastIndexOf('/');
+ if( lastSlash > 0 )
+ name = name.substring(lastSlash+1);
+ }
+ return name;
+ }
+
+ /**
+ * Take a URL.getQuery string and parse it into name=value pairs
+ *
+ * @param query Possibly empty/null url query string
+ * @return String[] for the name/value pairs in the query. May be empty but never null.
+ */
+ public static Map<String, String> parseURLQuery(String query)
+ {
+ Map<String, String> pairsMap = CollectionsFactory.createLazyMap();
+ if(query != null)
+ {
+ StringTokenizer tokenizer = new StringTokenizer(query, "=&");
+ while(tokenizer.hasMoreTokens())
+ {
+ String name = tokenizer.nextToken();
+ String value = tokenizer.nextToken();
+ pairsMap.put(name, value);
+ }
+ }
+ return pairsMap;
+ }
+
+ /**
+ * Does a vf name contain the VFS link prefix
+ * @param name - the name portion of a virtual file
+ * @return true if the name starts with VFS_LINK_PREFIX, false otherwise
+ */
+ public static boolean isLink(String name)
+ {
+ if (name == null)
+ throw new IllegalArgumentException("Null name");
+
+ return name.indexOf(VFS_LINK_PREFIX) >= 0;
+ }
+
+ /**
+ * Read the link information from the stream based on the type as determined
+ * from the name suffix.
+ *
+ * @param is - input stream to the link file contents
+ * @param name - the name of the virtual file representing the link
+ * @param props the propertes
+ * @return a list of the links read from the stream
+ * @throws IOException on failure to read/parse the stream
+ * @throws URISyntaxException for an error parsing a URI
+ */
+ public static List<LinkInfo> readLinkInfo(InputStream is, String name, Properties props)
+ throws IOException, URISyntaxException
+ {
+ if (name == null)
+ throw new IllegalArgumentException("Null name");
+
+ if(name.endsWith(".properties"))
+ {
+ List<LinkInfo> info = new ArrayList<LinkInfo>();
+ parseLinkProperties(is, info, props);
+ return info;
+ }
+ else
+ throw new UnsupportedEncodingException("Unknown link format: " + name);
+ }
+
+ /**
+ * Parse a properties link file
+ *
+ * @param is - input stream to the link file contents
+ * @param info the link infos
+ * @param props the propertes
+ * @throws IOException on failure to read/parse the stream
+ * @throws URISyntaxException for an error parsing a URI
+ */
+ public static void parseLinkProperties(InputStream is, List<LinkInfo> info, Properties props)
+ throws IOException, URISyntaxException
+ {
+ if (is == null)
+ throw new IllegalArgumentException("Null input stream");
+ if (info == null)
+ throw new IllegalArgumentException("Null info");
+ if (props == null)
+ throw new IllegalArgumentException("Null properties");
+
+ props.load(is);
+ // Iterate over the property tuples
+ for(int n = 0; ; n ++)
+ {
+ String nameKey = VFS_LINK_NAME + "." + n;
+ String name = props.getProperty(nameKey);
+ String uriKey = VFS_LINK_TARGET + "." + n;
+ String uri = props.getProperty(uriKey);
+ // End when the value is null since a link may not have a name
+ if (uri == null)
+ {
+ break;
+ }
+ // Replace any system property references
+ uri = StringPropertyReplacer.replaceProperties(uri);
+ LinkInfo link = new LinkInfo(name, new URI(uri));
+ info.add(link);
+ }
+ }
+
+ /**
+ * Deal with urls that may include spaces.
+ *
+ * @param url the url
+ * @return uri the uri
+ * @throws URISyntaxException for any error
+ */
+ public static URI toURI(URL url) throws URISyntaxException
+ {
+ if (url == null)
+ throw new IllegalArgumentException("Null url");
+
+ String urispec = url.toExternalForm();
+ // Escape any spaces
+ urispec = urispec.replaceAll(" ", "%20");
+ return new URI(urispec);
+ }
+
+ /**
+ * Get the options for this file.
+ *
+ * @param file the file
+ * @return options map
+ */
+ private static Map<String, String> getOptions(VirtualFile file)
+ {
+ if (file == null)
+ throw new IllegalArgumentException("Null file");
+
+ VirtualFileHandler handler = file.getHandler();
+ VFSContext context = handler.getVFSContext();
+ return context.getOptions();
+ }
+
+ /**
+ * Get the option.
+ *
+ * @param file the file
+ * @param key the option key
+ * @return key's option
+ */
+ public static String getOption(VirtualFile file, String key)
+ {
+ Map<String, String> options = getOptions(file);
+ return options != null ? options.get(key) : null;
+ }
+
+ /**
+ * Enable copy for file param.
+ *
+ * @param file the file
+ */
+ public static void enableCopy(VirtualFile file)
+ {
+ Map<String, String> options = getOptions(file);
+ if (options == null)
+ throw new IllegalArgumentException("Cannot enable copy on null options: " + file);
+
+ options.put(USE_COPY_QUERY, Boolean.TRUE.toString());
+ }
+
+ /**
+ * Disable copy for file param.
+ *
+ * @param file the file
+ */
+ public static void disableCopy(VirtualFile file)
+ {
+ Map<String, String> options = getOptions(file);
+ if (options == null)
+ throw new IllegalArgumentException("Cannot disable copy on null options: " + file);
+
+ options.remove(USE_COPY_QUERY);
+ }
+
+ /**
+ * Unpack the nested artifact under file param.
+ *
+ * @param file the file to unpack
+ * @return unpacked file
+ * @throws IOException for any io error
+ * @throws URISyntaxException for any uri error
+ */
+ public static VirtualFile unpack(VirtualFile file) throws IOException, URISyntaxException
+ {
+ return copy(file, UnpackCopyMechanism.INSTANCE);
+ }
+
+ /**
+ * Force explode.
+ * Explode archives or nested entries.
+ *
+ * @param file the file to explode
+ * @return exploded file
+ * @throws IOException for any io error
+ * @throws URISyntaxException for any uri error
+ */
+ public static VirtualFile explode(VirtualFile file) throws IOException, URISyntaxException
+ {
+ return copy(file, ExplodedCopyMechanism.INSTANCE);
+ }
+
+ /**
+ * Create temp.
+ *
+ * @param file the file to temp
+ * @return temp file
+ * @throws IOException for any io error
+ * @throws URISyntaxException for any uri error
+ */
+ public static VirtualFile temp(VirtualFile file) throws IOException, URISyntaxException
+ {
+ return copy(file, TempCopyMechanism.INSTANCE);
+ }
+
+ /**
+ * Create temp.
+ *
+ * @param file the file to unpack/explode
+ * @param mechanism the copy mechanism
+ * @return temp file
+ * @throws IOException for any io error
+ * @throws URISyntaxException for any uri error
+ */
+ protected static VirtualFile copy(VirtualFile file, CopyMechanism mechanism) throws IOException, URISyntaxException
+ {
+ if (file == null)
+ throw new IllegalArgumentException("Null file");
+ if (mechanism == null)
+ throw new IllegalArgumentException("Null copy mechanism");
+
+ return mechanism.copy(file, file.getHandler());
+ }
+
+ /**
+ * Is file handle nested.
+ *
+ * @param file the file handle to check
+ * @return true if file/dir is nested otherwise false
+ * @throws IOException for any error
+ */
+ public static boolean isNestedFile(VirtualFile file) throws IOException
+ {
+ if (file == null)
+ throw new IllegalArgumentException("Null file");
+
+ VirtualFileHandler handler = file.getHandler();
+ return handler.isNested();
+ }
+
+ /**
+ * Get spec compatilbe url from virtual file.
+ *
+ * @param file the virtual file
+ * @return spec compatible url
+ * @throws IOException for any error
+ * @throws URISyntaxException for any uri syntax error
+ */
+ public static URL getCompatibleURL(VirtualFile file) throws IOException, URISyntaxException
+ {
+ if (file == null)
+ throw new IllegalArgumentException("Null file");
+
+ URL url = file.toURL();
+ if (url == null)
+ throw new IllegalArgumentException("Null url: " + file);
+
+ // is not nested, so direct VFS URL is not an option
+ if (isNestedFile(file) == false)
+ {
+ String urlString = url.toExternalForm();
+ if (urlString.startsWith("vfs"))
+ {
+ // treat vfszip as file
+ if (urlString.startsWith("vfszip"))
+ url = new URL("file" + urlString.substring(6));
+ else
+ url = new URL(urlString.substring(3)); // (vfs)file and (vfs)jar are ok
+ }
+ }
+ return url;
+ }
+}
Deleted: projects/vfs/tags/2.0.0.Beta17/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java 2008-06-16 06:57:54 UTC (rev 74595)
+++ projects/vfs/tags/2.0.0.Beta17/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java 2008-06-16 14:28:54 UTC (rev 74620)
@@ -1,1191 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.virtual.plugins.context.zip;
-
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-import org.jboss.logging.Logger;
-import org.jboss.virtual.VFSUtils;
-import org.jboss.virtual.plugins.context.AbstractVFSContext;
-import org.jboss.virtual.plugins.context.AbstractVirtualFileHandler;
-import org.jboss.virtual.plugins.context.DelegatingHandler;
-import org.jboss.virtual.plugins.context.jar.JarUtils;
-import org.jboss.virtual.plugins.copy.AbstractCopyMechanism;
-import org.jboss.virtual.spi.VirtualFileHandler;
-
-/**
- * <tt>ZipEntryContext</tt> implements a {@link org.jboss.virtual.spi.VFSContext}
- * that exposes a zip archive as a virtual file system.
- *
- * Zip archive can be in a form of a file or a stream.
- *
- * Nested archives are processed through this same class.
- * By default nested archives are cached in memory and mounted as new
- * instances of <tt>ZipEntryContext</tt> with <tt>ZipStreamWrapper</tt> as a source.
- * If system property <em>jboss.vfs.forceCopy=true</em> is specified,
- * or URL query parameter <em>forceCopy=true</em> is present,
- * nested archives are extracted into a temp directory before being
- * mounted as new instances of <tt>ZipEntryContext</tt>.
- *
- * In-memory nested archives may consume a lot of memory. To reduce memory footprint
- * at the expense of performance, system property <em>jboss.vfs.optimizeForMemory=true<em>
- * can be set.
- *
- * This context implementation has two modes of releasing file locks.
- * <em>Asynchronous</em> mode is the default one since it is better performant.
- * To switch this to <em>synchronous</em> mode a system property
- * <em>jboss.vfs.forceNoReaper=true</em> can be specified or URL query parameter
- * <em>noReaper=true</em> can be included in context URL.
- *
- * This context implementation is a replacement for
- * {@link org.jboss.virtual.plugins.context.jar.JarContext}.
- *
- * @author <a href="strukelj at parsek.net">Marko Strukelj</a>
- * @version $Revision: 1.0 $
- */
-public class ZipEntryContext extends AbstractVFSContext
-{
- /** Logger */
- private static final Logger log = Logger.getLogger(ZipEntryContext.class);
-
- /** Global setting for nested archive processing mode: copy or no-copy (default) */
- private static boolean forceCopy;
-
- static
- {
- deleteTmpDirContents();
-
- forceCopy = AccessController.doPrivileged(new CheckForceCopy());
-
- if (forceCopy)
- log.info("VFS force nested jars copy-mode is enabled.");
- }
-
- /** Abstracted access to zip archive - either ZipFileWrapper or ZipStreamWrapper */
- private ZipWrapper zipSource;
-
- /** Entry path representing a context root - archive root is not necessarily a context root */
- private String rootEntryPath = "";
-
- /** AutoClean signals if zip archive should be deleted after closing the context - true for nested archives */
- private boolean autoClean = false;
-
- /** Registry of everything that zipSource contains */
- private Map<String, EntryInfo> entries = new ConcurrentHashMap<String, EntryInfo>();
-
- /**
- * Create a new ZipEntryContext
- *
- * @param rootURL - file or jar:file url
- * @throws URISyntaxException for any URI error
- * @throws java.io.IOException for any error
- */
- public ZipEntryContext(URL rootURL) throws URISyntaxException, IOException
- {
- this(rootURL, false);
- }
-
- /**
- * Create a new ZipEntryContext
- *
- * @param rootURL - file or jar:file url
- * @param autoClean - true if file represented by rootURL should be deleted after this context is closed
- * @throws URISyntaxException for any URI error
- * @throws java.io.IOException for any error
- */
- public ZipEntryContext(URL rootURL, boolean autoClean) throws URISyntaxException, IOException
- {
- super(VFSUtils.toURI(fixUrl(rootURL)));
- this.autoClean = autoClean;
- init(rootURL, null, null);
- }
-
- /**
- * Create a new ZipEntryContext to be mounted into another context
- *
- * @param rootURL - url representing this context within another context
- * @param peer - file handler in another context through which this context is being mounted
- * @param localRootUrl - file or jar:file url
- * @throws URISyntaxException for any URI error
- * @throws java.io.IOException for any error
- */
- public ZipEntryContext(URL rootURL, VirtualFileHandler peer, URL localRootUrl) throws URISyntaxException, IOException
- {
- this(rootURL, peer, localRootUrl, false);
- }
-
- /**
- * Create a new ZipEntryContext to be mounted into another context
- *
- * @param rootURL - url representing this context within another context
- * @param peer - file handler in another context through which this context is being mounted
- * @param localRootUrl - file or jar:file url
- * @param autoClean - true if file represented by localRootURL should be deleted after this context is closed
- * @throws URISyntaxException for any URI error
- * @throws java.io.IOException for any error
- */
- public ZipEntryContext(URL rootURL, VirtualFileHandler peer, URL localRootUrl, boolean autoClean) throws URISyntaxException, IOException
- {
- super(VFSUtils.toURI(fixUrl(rootURL)));
- this.autoClean = autoClean;
- init(localRootUrl, peer, null);
- }
-
- /**
- * Create a new ZipEntryContext to be mounted into another context
- *
- * @param rootURL - url representing this context within another context
- * @param peer - file handler in another context through which this context is being mounted
- * @param zipWrapper - abstracted zip archive source
- * @param autoClean - true if file represented by localRootURL should be deleted after this context is closed
- * @throws URISyntaxException for any URI error
- * @throws java.io.IOException for any error
- */
- public ZipEntryContext(URL rootURL, VirtualFileHandler peer, ZipWrapper zipWrapper, boolean autoClean) throws URISyntaxException, IOException
- {
- super(VFSUtils.toURI(fixUrl(rootURL)));
- this.autoClean = autoClean;
- init(null, peer, zipWrapper);
- }
-
- /**
- * Extra initialization in addition to what's inside constructors
- *
- * @param localRootURL the local url
- * @param peer the peer
- * @param zipWrapper zip wrapper
- * @throws URISyntaxException for any URI error
- * @throws java.io.IOException for any error
- */
- private void init(URL localRootURL, VirtualFileHandler peer, ZipWrapper zipWrapper) throws IOException, URISyntaxException
- {
- if (zipWrapper == null)
- {
- if (localRootURL == null)
- throw new IllegalArgumentException("No ZipWrapper specified and localRootURL is null");
-
- // initialize rootEntryPath and get archive file path
- String rootPath = initRootAndPath(localRootURL);
- zipSource = createZipSource(rootPath);
- }
- else
- {
- zipSource = zipWrapper;
- }
-
- setRootPeer(peer);
-
- String name = getRootURI().toString();
- int toPos = name.length();
-
- // cut off any ending slash
- if(name.length() != 0 && name.charAt(name.length()-1) == '/')
- toPos --;
-
- // name is last path component
- int namePos = name.lastIndexOf("/", toPos-1);
- name = name.substring(namePos+1, toPos);
-
- // cut off any ending exclamation
- if(name.length() != 0 && name.charAt(name.length()-1) == '!')
- name = name.substring(0, name.length()-1);
-
- // init initial root EntryInfo that will be overwritten
- // if zip entry exists for rootEntryPath
- entries.put("", new EntryInfo(new ZipEntryHandler(this, null, name, true), null));
-
- initEntries();
- }
-
- /**
- * Create zip source.
- *
- * @param rootPath the root path
- * @return zip entry wrapper
- * @throws IOException for any error
- */
- protected ZipWrapper createZipSource(String rootPath) throws IOException
- {
- File file = null;
- String relative = null;
- File fp = new File(rootPath);
- if (fp.exists())
- {
- file = fp;
- }
- else
- {
- File curr = fp;
- relative = fp.getName();
- while ((curr = curr.getParentFile()) != null)
- {
- if (curr.exists())
- {
- file = curr;
- break;
- }
- else
- {
- relative = curr.getName() + "/" + relative;
- }
- }
- }
-
- if (file == null)
- throw new IOException("VFS file does not exist: " + rootPath);
-
- if (relative != null)
- {
- return findEntry(new FileInputStream(file), relative);
- }
- else
- {
- boolean noReaper = Boolean.valueOf(getOptions().get(VFSUtils.NO_REAPER_QUERY));
- return new ZipFileWrapper(file, autoClean, noReaper);
- }
- }
-
- /**
- * Find exact entry.
- * Use recursion on relative path.
- *
- * @param is the input stream
- * @param relative relative path
- * @return zip wrapper instance
- * @throws IOException for any error
- */
- protected static ZipWrapper findEntry(InputStream is, String relative) throws IOException
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ZipEntryContext.copyStreamAndClose(is, baos);
- ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-
- // first we need to find best/longest name
- ZipInputStream zis = new ZipInputStream(bais);
- ZipEntry entry;
- String longestNameMatch = null;
- while((entry = zis.getNextEntry()) != null)
- {
- String entryName = entry.getName();
- if (relative.startsWith(entryName))
- {
- if (entryName.equals(relative))
- {
- InputStream stream = new SizeLimitedInputStream(zis, entry.getSize());
- // directories and non archives
- if (entry.isDirectory() || JarUtils.isArchive(entryName) == false)
- {
- return new ZipEntryWrapper(stream, entryName, System.currentTimeMillis());
- }
- else
- return new ZipStreamWrapper(stream, entryName, System.currentTimeMillis());
- }
-
- if (longestNameMatch == null || longestNameMatch.length() < entryName.length())
- {
- longestNameMatch = entryName;
- }
- }
- }
- if (longestNameMatch == null)
- throw new IllegalArgumentException("Cannot find entry: " + is + ", " + relative);
-
- // do recursion on relative
- bais.reset();
- zis = new ZipInputStream(bais);
- while((entry = zis.getNextEntry()) != null)
- {
- String entryName = entry.getName();
- if (entryName.equals(longestNameMatch))
- {
- relative = relative.substring(longestNameMatch.length() + 1);
- return findEntry(new SizeLimitedInputStream(zis, entry.getSize()), relative);
- }
- }
- throw new IllegalArgumentException("No such entry: " + is + ", " + relative);
- }
-
- /**
- * Returns archive file name - if this is a top-level ZipEntryContext.
- * Otherwise it returns the last component of URL.
- *
- * @return name
- */
- public String getName()
- {
- VirtualFileHandler peer = getRootPeer();
- if (peer != null)
- return peer.getName();
- else
- return zipSource.getName();
- }
-
- /**
- * Iterate through zip archive entries, compose a tree structure of archive's content
- *
- * @throws URISyntaxException for any URI error
- * @throws java.io.IOException for any error
- */
- private synchronized void initEntries() throws IOException, URISyntaxException
- {
- // we're using a two phase approach - we first select the relevant ones
- // then we order these by name and only then we process them
- // this way we ensure that parent entries are processed before child entries
-
- Map<String, ZipEntry> relevant = new HashMap<String, ZipEntry>();
- zipSource.acquire();
- try
- {
- Enumeration<? extends ZipEntry> zipEntries = zipSource.entries();
- // zoom-in on entries under rootEntryPath - ignoring the rest
- while(zipEntries.hasMoreElements())
- {
- ZipEntry ent = zipEntries.nextElement();
- if(ent.getName().startsWith(rootEntryPath))
- {
- relevant.put(ent.getName(), ent);
- }
- }
-
- Map<String, ZipEntry> orderedRelevant = new TreeMap<String, ZipEntry>(relevant);
- for(Map.Entry<String, ZipEntry> entry : orderedRelevant.entrySet())
- {
- ZipEntry ent = entry.getValue();
- String fullName = ent.getName().substring(rootEntryPath.length());
-
- String [] split = splitParentChild(fullName);
- String parentPath = split[0];
- String name = split[1];
-
- EntryInfo ei = entries.get(parentPath);
- if(ei == null)
- ei = makeDummyParent(parentPath);
-
- AbstractVirtualFileHandler parent = ei != null ? ei.handler : null;
-
- if(ent.isDirectory() == false && JarUtils.isArchive(ent.getName()))
- {
- boolean useCopyMode = forceCopy;
- if (useCopyMode == false)
- {
- String flag = getOptions().get(VFSUtils.USE_COPY_QUERY);
- useCopyMode = Boolean.valueOf(flag);
- }
-
- DelegatingHandler delegator;
-
- if (useCopyMode)
- {
- // extract it to temp dir
- File dest = new File(getTempDir() + "/" + getTempFileName(ent.getName()));
- dest.deleteOnExit();
-
- // ensure parent exists
- dest.getParentFile().mkdirs();
-
- InputStream is = zipSource.openStream(ent);
- OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));
- copyStreamAndClose(is, os);
-
- // mount another instance of ZipEntryContext
- delegator = mountZipFile(parent, name, dest);
- }
- else
- {
- // mount another instance of ZipEntryContext
- delegator = mountZipStream(parent, name, zipSource.openStream(ent));
- }
-
- entries.put(delegator.getLocalPathName(), new EntryInfo(delegator, ent));
- addChild(parent, delegator);
- }
- else
- {
- ZipEntryHandler wrapper = new ZipEntryHandler(this, parent, name, ent.isDirectory() == false);
- entries.put(wrapper.getLocalPathName(), new EntryInfo(wrapper, ent));
- }
- }
- }
- finally
- {
- zipSource.release();
- }
- }
-
- /**
- * Mount ZipEntryContext created around extracted nested archive
- *
- * @param parent the parent
- * @param name the name
- * @param file the file
- * @return mounted delegate
- * @throws IOException for any error
- * @throws URISyntaxException for any URI syntax error
- */
- protected DelegatingHandler mountZipFile(VirtualFileHandler parent, String name, File file) throws IOException, URISyntaxException
- {
- DelegatingHandler delegator = new DelegatingHandler(this, parent, name);
- URL fileUrl = file.toURL();
- URL delegatorUrl = fileUrl;
-
- if (parent != null)
- delegatorUrl = getChildURL(parent, name);
-
- ZipEntryContext ctx = new ZipEntryContext(delegatorUrl, delegator, fileUrl, true);
- VirtualFileHandler handler = ctx.getRoot();
- delegator.setDelegate(handler);
-
- return delegator;
- }
-
- /**
- * Mount ZipEntryContext created around ZipStreamWrapper
- *
- * @param parent the parent
- * @param name the name
- * @param zipStream the zip stream
- * @return mounted delegate
- * @throws IOException for any error
- * @throws URISyntaxException for any URI syntax error
- */
- protected DelegatingHandler mountZipStream(VirtualFileHandler parent, String name, InputStream zipStream) throws IOException, URISyntaxException
- {
- DelegatingHandler delegator = new DelegatingHandler(this, parent, name);
- ZipStreamWrapper wrapper = new ZipStreamWrapper(zipStream, name, parent.getLastModified());
-
- URL delegatorUrl = null;
-
- if (parent != null)
- delegatorUrl = getChildURL(parent, name);
-
- ZipEntryContext ctx = new ZipEntryContext(delegatorUrl, delegator, wrapper, false);
- VirtualFileHandler handler = ctx.getRoot();
- delegator.setDelegate(handler);
-
- return delegator;
- }
-
- /**
- * Zip archives sometimes don't contain directory entries - only leaf entries
- *
- * @param parentPath the parent path
- * @return entry info
- * @throws IOException for any error
- */
- private EntryInfo makeDummyParent(String parentPath) throws IOException
- {
- // get grand parent first
- String [] split = splitParentChild(parentPath);
- String grandPa = split[0];
-
- EntryInfo eiParent = entries.get(grandPa);
- if(eiParent == null)
- eiParent = makeDummyParent(grandPa);
-
- ZipEntryHandler handler = new ZipEntryHandler(this, eiParent.handler, split[1], false);
- EntryInfo ei = new EntryInfo(handler, null);
- entries.put(parentPath, ei);
- return ei;
- }
-
- /**
- * Initialize rootEntryPath and return archive file path
- *
- * @param localRootUrl local root url
- * @return file path
- */
- private String initRootAndPath(URL localRootUrl)
- {
- String filePath = localRootUrl.toString();
- String zipPath = filePath;
-
- int pos = filePath.indexOf("!");
- if(pos > 0)
- {
- zipPath = filePath.substring(0, pos);
- rootEntryPath = filePath.substring(pos+2);
- if(rootEntryPath.length() != 0)
- rootEntryPath += "/";
- }
-
- // find where url protocol ends - i.e. jar:file:/ ...
- pos= zipPath.indexOf(":/");
- filePath = zipPath.substring(pos + 2);
-
- // cut out url query part if present
- int queryStart = filePath.indexOf("?");
- if (queryStart != -1)
- filePath = filePath.substring(0, queryStart);
-
- return filePath;
- }
-
- /**
- * If archive has been modified, clear <em>entries</em> and re-initialize
- */
- private synchronized void checkIfModified()
- {
- // TODO: if zipSource represents a nested archive we should maybe delegate lastModified to its parent
- if (zipSource.hasBeenModified())
- {
- EntryInfo rootInfo = entries.get("");
- entries = new ConcurrentHashMap<String, EntryInfo>();
- entries.put("", rootInfo);
-
- if (zipSource.exists())
- {
- try
- {
- initEntries();
- }
- catch(Exception ignored)
- {
- log.warn("IGNORING: Failed to reinitialize context: " + getRootURI(), ignored);
- }
- }
- }
- }
-
- /**
- * Returns this context's root
- *
- * @return root handler
- * @throws IOException for any error
- */
- public VirtualFileHandler getRoot() throws IOException
- {
- return entries.get("").handler;
- }
-
- /**
- * Find a child with a given name and a given parent
- *
- * @param parent parent handler
- * @param name name of the child
- * @return child handler or null if not found
- */
- public VirtualFileHandler getChild(ZipEntryHandler parent, String name)
- {
- if (parent == null)
- throw new IllegalArgumentException("Null parent");
-
- checkIfModified();
- String pathName = parent.getLocalPathName();
- if("".equals(pathName))
- pathName = name;
- else
- pathName = pathName + "/" + name;
-
- EntryInfo ei = entries.get(pathName);
-
- if(ei != null)
- return ei.handler;
-
- return null;
- }
-
- /**
- * Returns a list of children for a given parent
- *
- * @param parent parent handler
- * @param ignoreErrors true if errors should be silently ignored
- * @return list of handlers representing children of the given parent
- * @throws IOException for any error
- */
- public List<VirtualFileHandler> getChildren(VirtualFileHandler parent, boolean ignoreErrors) throws IOException
- {
- if (parent == null)
- throw new IllegalArgumentException("Null parent");
-
- checkIfModified();
- if(parent instanceof AbstractVirtualFileHandler)
- {
- AbstractVirtualFileHandler parentHandler = (AbstractVirtualFileHandler) parent;
- EntryInfo parentEntry = entries.get(parentHandler.getLocalPathName());
- if (parentEntry != null)
- {
- if (parentEntry.handler instanceof DelegatingHandler)
- return parentEntry.handler.getChildren(ignoreErrors);
-
- return parentEntry.getChildren();
- }
- }
- return Collections.emptyList();
- }
-
- /**
- * Returns lastModified timestamp for a given handler
- *
- * @param handler a handler
- * @return lastModified timestamp
- */
- public long getLastModified(ZipEntryHandler handler)
- {
- if (handler == null)
- throw new IllegalArgumentException("Null handler");
-
- checkIfModified();
- EntryInfo ei = entries.get(handler.getLocalPathName());
- if(ei == null)
- return 0;
-
- if(ei.entry == null) {
- return zipSource.getLastModified();
- }
-
- return ei.entry.getTime();
- }
-
- /**
- * Returns the size for a given handler
- *
- * @param handler a handler
- * @return size in bytes
- */
- public long getSize(ZipEntryHandler handler)
- {
- if (handler == null)
- throw new IllegalArgumentException("Null handler");
-
- checkIfModified();
- String pathName = handler.getLocalPathName();
- EntryInfo ei = entries.get(pathName);
- if(ei == null)
- return 0;
-
- if(ei.entry == null)
- {
- if(pathName.length() == 0)
- return zipSource.getSize();
- else
- return 0;
- }
-
- return ei.entry.getSize();
- }
-
- /**
- * Returns true if entry exists for a given handler
- *
- * @param handler a handler
- * @return true if entry exists
- */
- public boolean exists(ZipEntryHandler handler)
- {
- if (handler == null)
- throw new IllegalArgumentException("Null handler");
-
- checkIfModified();
- String pathName = handler.getLocalPathName();
- EntryInfo ei = entries.get(pathName);
- if(ei == null)
- return false;
-
- if (ei.entry == null && pathName.length() == 0)
- return zipSource.exists();
-
- return true;
- }
-
- /**
- * Returns true if handler represents a non-directory entry
- *
- * @param handler a handler
- * @return true if not a directory
- */
- public boolean isLeaf(ZipEntryHandler handler)
- {
- if (handler == null)
- throw new IllegalArgumentException("Null handler");
-
- checkIfModified();
- EntryInfo ei = entries.get(handler.getLocalPathName());
- if(ei == null || ei.entry == null)
- return false;
-
- return !ei.entry.isDirectory();
- }
-
- /**
- * Is archive.
- *
- * @param handler the handler
- * @return true if archive
- */
- static boolean isArchive(VirtualFileHandler handler)
- {
- if (handler instanceof ZipEntryHandler && "".equals(handler.getLocalPathName()))
- {
- return true;
- }
-
- if (handler instanceof DelegatingHandler && ((DelegatingHandler) handler).getDelegate() instanceof ZipEntryHandler)
- {
- return true;
- }
-
- return false;
- }
-
- /**
- * Get parent.
- *
- * @param handler the handler to check
- * @return parent handler
- * @throws IOException for any error
- */
- static VirtualFileHandler getParent(VirtualFileHandler handler) throws IOException
- {
- VirtualFileHandler parent = handler.getParent();
- if (parent == null)
- {
- VirtualFileHandler peer = handler.getVFSContext().getRootPeer();
- if (peer != null)
- parent = peer.getParent();
- }
- return parent;
- }
-
- /**
- * Is nested.
- *
- * @param handler the handler
- * @return true if nested
- * @throws IOException for any error
- */
- static boolean isNested(VirtualFileHandler handler) throws IOException
- {
- VirtualFileHandler parent = getParent(handler);
- while (parent != null)
- {
- if(isArchive(parent))
- return true;
-
- parent = getParent(parent);
- }
- return false;
- }
-
- /**
- * Contents of the file represented by a given handler
- *
- * @param handler a handler
- * @return InputStream with entry's content
- * @throws IOException for any error
- */
- public InputStream openStream(ZipEntryHandler handler) throws IOException
- {
- if (handler == null)
- throw new IllegalArgumentException("Null handler");
-
- checkIfModified();
-
- String localPathName = handler.getLocalPathName();
- EntryInfo ei = entries.get(localPathName);
-
- if (ei == null)
- {
- String uriStr;
- try
- {
- uriStr = handler.toURI().toString();
- }
- catch(Exception ex)
- {
- throw new RuntimeException("ASSERTION ERROR - uri generation failed for ZipEntryHandler: " + handler, ex);
- }
- throw new FileNotFoundException(uriStr);
- }
-
- if(ei.entry == null)
- {
- if ("".equals(localPathName)) // root
- return zipSource.getRootAsStream();
- else // directory
- return new ByteArrayInputStream(new byte[0]);
- }
-
- return zipSource.openStream(ei.entry);
- }
-
- /**
- * Add a child to a given parent
- *
- * @param parent a parent
- * @param child a child
- */
- public void addChild(AbstractVirtualFileHandler parent, AbstractVirtualFileHandler child)
- {
- if (parent == null)
- throw new IllegalArgumentException("Null parent");
-
- if (child == null)
- throw new IllegalArgumentException("Null child");
-
- EntryInfo parentEntry = entries.get(parent.getLocalPathName());
- if (parentEntry != null)
- parentEntry.add(child);
- else
- throw new RuntimeException("Parent does not exist: " + parent);
- }
-
- /**
- * Properly release held resources
- */
- protected void finalize()
- {
- try
- {
- super.finalize();
- if (zipSource != null)
- zipSource.close();
- }
- catch (Throwable ignored)
- {
- log.debug("IGNORING: Failed to close zip source: " + zipSource, ignored);
- }
- }
-
- /**
- * Replace a current child of the given parent with another one
- *
- * @param parent a parent
- * @param original current child
- * @param replacement new child
- */
- public void replaceChild(ZipEntryHandler parent, AbstractVirtualFileHandler original, VirtualFileHandler replacement)
- {
- EntryInfo parentEntry = entries.get(parent.getLocalPathName());
- if (parentEntry != null)
- {
- DelegatingHandler newOne;
-
- if (replacement instanceof DelegatingHandler)
- {
- newOne = (DelegatingHandler) replacement;
- }
- else
- {
- newOne = new DelegatingHandler(this, parent, original.getName(), replacement);
- }
-
- synchronized(this)
- {
- parentEntry.replaceChild(original, newOne);
-
- EntryInfo ei = entries.get(original.getLocalPathName());
- ei.handler = newOne;
- ei.entry = null;
- ei.clearChildren();
- }
- }
- else
- {
- throw new RuntimeException("Parent does not exist: " + parent);
- }
- }
-
- /**
- * Internal data structure holding meta information of a virtual file in this context
- */
- static class EntryInfo
- {
- /** a handler */
- private AbstractVirtualFileHandler handler;
-
- /** a <tt>ZipEntry</tt> */
- private ZipEntry entry;
-
- /** a list of children */
- private List<AbstractVirtualFileHandler> children;
-
- /**
- * EntryInfo constructor
- *
- * @param handler a handler
- * @param entry an entry
- */
- EntryInfo(AbstractVirtualFileHandler handler, ZipEntry entry)
- {
- this.handler = handler;
- this.entry = entry;
- }
-
- /**
- * Get children.
- *
- * @return returns a list of children for this handler (by copy)
- */
- public synchronized List<VirtualFileHandler> getChildren()
- {
- if (children == null)
- return Collections.emptyList();
-
- return new LinkedList<VirtualFileHandler>(children);
- }
-
- /**
- * Replace a child.
- *
- * @param original existing child
- * @param replacement new child
- */
- public synchronized void replaceChild(AbstractVirtualFileHandler original, AbstractVirtualFileHandler replacement)
- {
- if (children != null)
- {
- int i = 0;
- Iterator<AbstractVirtualFileHandler> it = children.iterator();
- while(it.hasNext())
- {
- AbstractVirtualFileHandler child = it.next();
- if (child.getName().equals(original.getName()))
- {
- children.set(i, replacement);
- break;
- }
- i++;
- }
- }
- }
-
- /**
- * Clear the list of children
- */
- public synchronized void clearChildren()
- {
- if (children != null)
- children.clear();
- }
-
- /**
- * Add a child. If a child with the same name exists already, first remove it.
- *
- * @param child a child
- */
- public synchronized void add(AbstractVirtualFileHandler child)
- {
- if (children == null)
- {
- children = new LinkedList<AbstractVirtualFileHandler>();
- }
- else
- {
- // if a child exists with this name already, remove it
- Iterator<AbstractVirtualFileHandler> it = children.iterator();
- while (it.hasNext())
- {
- AbstractVirtualFileHandler handler = it.next();
- if (handler.getName().equals(child.getName()))
- {
- it.remove();
- break;
- }
- }
- }
-
- children.add(child);
- }
- }
-
- //
- // Helper methods
- //
-
- /**
- * Copy input stream to output stream and close them both
- *
- * @param is input stream
- * @param os output stream
- * @throws IOException for any error
- */
- static void copyStreamAndClose(InputStream is, OutputStream os) throws IOException
- {
- try
- {
- byte [] buff = new byte[65536];
- int count = is.read(buff);
- while(count != -1)
- {
- os.write(buff, 0, count);
- count = is.read(buff);
- }
- }
- finally
- {
- if(is != null)
- {
- try {
- is.close();
- }
- catch(Exception ignored)
- {
- }
- }
- os.close();
- }
- }
-
- /**
- * Make sure url protocol is <em>vfszip</em>
- *
- * @param rootURL the root url
- * @return fixed url
- * @throws MalformedURLException for any error
- */
- private static URL fixUrl(URL rootURL) throws MalformedURLException
- {
- if ("vfszip".equals(rootURL.getProtocol()) == false)
- {
- String url = rootURL.toString();
- int pos = url.indexOf(":/");
- if (pos != -1)
- url = url.substring(pos);
-
- return new URL("vfszip" + url);
- }
- return rootURL;
- }
-
- /**
- * Break to path + name
- *
- * @param pathName the path name
- * @return path tokens
- */
- public static String [] splitParentChild(String pathName)
- {
- if(pathName.length() == 0)
- return new String [] {null, pathName};
-
- int toPos = pathName.length();
- if(pathName.charAt(pathName.length()-1) == '/')
- toPos --;
-
- int delimPos = pathName.lastIndexOf('/', toPos-1);
-
- String [] ret;
- if(delimPos == -1)
- {
- ret = new String []
- {
- "",
- pathName.substring(delimPos+1, toPos)
- };
- }
- else
- {
- ret = new String []
- {
- pathName.substring(0, delimPos),
- pathName.substring(delimPos+1, toPos)
- };
- }
- return ret;
- }
-
- /**
- * Temporary files naming scheme
- *
- * @param name the name
- * @return random name
- */
- private static String getTempFileName(String name)
- {
- int delim = name.lastIndexOf("/");
- if (delim != -1)
- name = name.substring(delim+1);
- return UUID.randomUUID().toString().substring(0, 8) + "_" + name;
- }
-
- /**
- * Use VFS's temp directory and make 'vfs-nested.tmp' sub-directory inside it for our purposes
- *
- * @return temp dir
- */
- private static String getTempDir()
- {
- File dir = new File(AbstractCopyMechanism.getTempDirectory(), "vfs-nested.tmp");
- return dir.toString();
- }
-
- /**
- * Delete the contents of a temporary directory. Delete first-level files only, don't drill down.
- */
- private static void deleteTmpDirContents()
- {
- try
- {
- File tmpDir = new File(getTempDir());
- File [] files = tmpDir.listFiles();
- if (files != null && files.length > 0)
- {
- for (File file : files)
- {
- if (file.isDirectory() == false && file.isHidden() == false)
- file.delete();
- }
- }
- }
- catch(Exception ignored)
- {
- }
- }
-
- /**
- * <tt>PriviligedAction</tt> class for checking a system property
- */
- private static class CheckForceCopy implements PrivilegedAction<Boolean>
- {
- public Boolean run()
- {
- String forceString = System.getProperty(VFSUtils.FORCE_COPY_KEY, "false");
- return Boolean.valueOf(forceString);
- }
- }
-}
Copied: projects/vfs/tags/2.0.0.Beta17/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java (from rev 74618, projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java)
===================================================================
--- projects/vfs/tags/2.0.0.Beta17/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java (rev 0)
+++ projects/vfs/tags/2.0.0.Beta17/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java 2008-06-16 14:28:54 UTC (rev 74620)
@@ -0,0 +1,1191 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.virtual.plugins.context.zip;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.jboss.logging.Logger;
+import org.jboss.virtual.VFSUtils;
+import org.jboss.virtual.plugins.context.AbstractVFSContext;
+import org.jboss.virtual.plugins.context.AbstractVirtualFileHandler;
+import org.jboss.virtual.plugins.context.DelegatingHandler;
+import org.jboss.virtual.plugins.context.jar.JarUtils;
+import org.jboss.virtual.plugins.copy.AbstractCopyMechanism;
+import org.jboss.virtual.spi.VirtualFileHandler;
+
+/**
+ * <tt>ZipEntryContext</tt> implements a {@link org.jboss.virtual.spi.VFSContext}
+ * that exposes a zip archive as a virtual file system.
+ *
+ * Zip archive can be in a form of a file or a stream.
+ *
+ * Nested archives are processed through this same class.
+ * By default nested archives are cached in memory and mounted as new
+ * instances of <tt>ZipEntryContext</tt> with <tt>ZipStreamWrapper</tt> as a source.
+ * If system property <em>jboss.vfs.forceCopy=true</em> is specified,
+ * or URL query parameter <em>forceCopy=true</em> is present,
+ * nested archives are extracted into a temp directory before being
+ * mounted as new instances of <tt>ZipEntryContext</tt>.
+ *
+ * In-memory nested archives may consume a lot of memory. To reduce memory footprint
+ * at the expense of performance, system property <em>jboss.vfs.optimizeForMemory=true<em>
+ * can be set.
+ *
+ * This context implementation has two modes of releasing file locks.
+ * <em>Asynchronous</em> mode is the default one since it is better performant.
+ * To switch this to <em>synchronous</em> mode a system property
+ * <em>jboss.vfs.forceNoReaper=true</em> can be specified or URL query parameter
+ * <em>noReaper=true</em> can be included in context URL.
+ *
+ * This context implementation is a replacement for
+ * {@link org.jboss.virtual.plugins.context.jar.JarContext}.
+ *
+ * @author <a href="strukelj at parsek.net">Marko Strukelj</a>
+ * @version $Revision: 1.0 $
+ */
+public class ZipEntryContext extends AbstractVFSContext
+{
+ /** Logger */
+ private static final Logger log = Logger.getLogger(ZipEntryContext.class);
+
+ /** Global setting for nested archive processing mode: copy or no-copy (default) */
+ private static boolean forceCopy;
+
+ static
+ {
+ deleteTmpDirContents();
+
+ forceCopy = AccessController.doPrivileged(new CheckForceCopy());
+
+ if (forceCopy)
+ log.info("VFS force nested jars copy-mode is enabled.");
+ }
+
+ /** Abstracted access to zip archive - either ZipFileWrapper or ZipStreamWrapper */
+ private ZipWrapper zipSource;
+
+ /** Entry path representing a context root - archive root is not necessarily a context root */
+ private String rootEntryPath = "";
+
+ /** AutoClean signals if zip archive should be deleted after closing the context - true for nested archives */
+ private boolean autoClean = false;
+
+ /** Registry of everything that zipSource contains */
+ private Map<String, EntryInfo> entries = new ConcurrentHashMap<String, EntryInfo>();
+
+ /**
+ * Create a new ZipEntryContext
+ *
+ * @param rootURL - file or jar:file url
+ * @throws URISyntaxException for any URI error
+ * @throws java.io.IOException for any error
+ */
+ public ZipEntryContext(URL rootURL) throws URISyntaxException, IOException
+ {
+ this(rootURL, false);
+ }
+
+ /**
+ * Create a new ZipEntryContext
+ *
+ * @param rootURL - file or jar:file url
+ * @param autoClean - true if file represented by rootURL should be deleted after this context is closed
+ * @throws URISyntaxException for any URI error
+ * @throws java.io.IOException for any error
+ */
+ public ZipEntryContext(URL rootURL, boolean autoClean) throws URISyntaxException, IOException
+ {
+ super(VFSUtils.toURI(fixUrl(rootURL)));
+ this.autoClean = autoClean;
+ init(rootURL, null, null);
+ }
+
+ /**
+ * Create a new ZipEntryContext to be mounted into another context
+ *
+ * @param rootURL - url representing this context within another context
+ * @param peer - file handler in another context through which this context is being mounted
+ * @param localRootUrl - file or jar:file url
+ * @throws URISyntaxException for any URI error
+ * @throws java.io.IOException for any error
+ */
+ public ZipEntryContext(URL rootURL, VirtualFileHandler peer, URL localRootUrl) throws URISyntaxException, IOException
+ {
+ this(rootURL, peer, localRootUrl, false);
+ }
+
+ /**
+ * Create a new ZipEntryContext to be mounted into another context
+ *
+ * @param rootURL - url representing this context within another context
+ * @param peer - file handler in another context through which this context is being mounted
+ * @param localRootUrl - file or jar:file url
+ * @param autoClean - true if file represented by localRootURL should be deleted after this context is closed
+ * @throws URISyntaxException for any URI error
+ * @throws java.io.IOException for any error
+ */
+ public ZipEntryContext(URL rootURL, VirtualFileHandler peer, URL localRootUrl, boolean autoClean) throws URISyntaxException, IOException
+ {
+ super(VFSUtils.toURI(fixUrl(rootURL)));
+ this.autoClean = autoClean;
+ init(localRootUrl, peer, null);
+ }
+
+ /**
+ * Create a new ZipEntryContext to be mounted into another context
+ *
+ * @param rootURL - url representing this context within another context
+ * @param peer - file handler in another context through which this context is being mounted
+ * @param zipWrapper - abstracted zip archive source
+ * @param autoClean - true if file represented by localRootURL should be deleted after this context is closed
+ * @throws URISyntaxException for any URI error
+ * @throws java.io.IOException for any error
+ */
+ public ZipEntryContext(URL rootURL, VirtualFileHandler peer, ZipWrapper zipWrapper, boolean autoClean) throws URISyntaxException, IOException
+ {
+ super(VFSUtils.toURI(fixUrl(rootURL)));
+ this.autoClean = autoClean;
+ init(null, peer, zipWrapper);
+ }
+
+ /**
+ * Extra initialization in addition to what's inside constructors
+ *
+ * @param localRootURL the local url
+ * @param peer the peer
+ * @param zipWrapper zip wrapper
+ * @throws URISyntaxException for any URI error
+ * @throws java.io.IOException for any error
+ */
+ private void init(URL localRootURL, VirtualFileHandler peer, ZipWrapper zipWrapper) throws IOException, URISyntaxException
+ {
+ if (zipWrapper == null)
+ {
+ if (localRootURL == null)
+ throw new IllegalArgumentException("No ZipWrapper specified and localRootURL is null");
+
+ // initialize rootEntryPath and get archive file path
+ String rootPath = initRootAndPath(localRootURL);
+ zipSource = createZipSource(rootPath);
+ }
+ else
+ {
+ zipSource = zipWrapper;
+ }
+
+ setRootPeer(peer);
+
+ String name = getRootURI().toString();
+ int toPos = name.length();
+
+ // cut off any ending slash
+ if(name.length() != 0 && name.charAt(name.length()-1) == '/')
+ toPos --;
+
+ // name is last path component
+ int namePos = name.lastIndexOf("/", toPos-1);
+ name = name.substring(namePos+1, toPos);
+
+ // cut off any ending exclamation
+ if(name.length() != 0 && name.charAt(name.length()-1) == '!')
+ name = name.substring(0, name.length()-1);
+
+ // init initial root EntryInfo that will be overwritten
+ // if zip entry exists for rootEntryPath
+ entries.put("", new EntryInfo(new ZipEntryHandler(this, null, name, true), null));
+
+ initEntries();
+ }
+
+ /**
+ * Create zip source.
+ *
+ * @param rootPath the root path
+ * @return zip entry wrapper
+ * @throws IOException for any error
+ */
+ protected ZipWrapper createZipSource(String rootPath) throws IOException
+ {
+ File file = null;
+ String relative = null;
+ File fp = new File(rootPath);
+ if (fp.exists())
+ {
+ file = fp;
+ }
+ else
+ {
+ File curr = fp;
+ relative = fp.getName();
+ while ((curr = curr.getParentFile()) != null)
+ {
+ if (curr.exists())
+ {
+ file = curr;
+ break;
+ }
+ else
+ {
+ relative = curr.getName() + "/" + relative;
+ }
+ }
+ }
+
+ if (file == null)
+ throw new IOException("VFS file does not exist: " + rootPath);
+
+ if (relative != null)
+ {
+ return findEntry(new FileInputStream(file), relative);
+ }
+ else
+ {
+ boolean noReaper = Boolean.valueOf(getOptions().get(VFSUtils.NO_REAPER_QUERY));
+ return new ZipFileWrapper(file, autoClean, noReaper);
+ }
+ }
+
+ /**
+ * Find exact entry.
+ * Use recursion on relative path.
+ *
+ * @param is the input stream
+ * @param relative relative path
+ * @return zip wrapper instance
+ * @throws IOException for any error
+ */
+ protected static ZipWrapper findEntry(InputStream is, String relative) throws IOException
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ZipEntryContext.copyStreamAndClose(is, baos);
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+
+ // first we need to find best/longest name
+ ZipInputStream zis = new ZipInputStream(bais);
+ ZipEntry entry;
+ String longestNameMatch = null;
+ while((entry = zis.getNextEntry()) != null)
+ {
+ String entryName = entry.getName();
+ if (relative.startsWith(entryName))
+ {
+ if (entryName.equals(relative))
+ {
+ InputStream stream = new SizeLimitedInputStream(zis, entry.getSize());
+ // directories and non archives
+ if (entry.isDirectory() || JarUtils.isArchive(entryName) == false)
+ {
+ return new ZipEntryWrapper(stream, entryName, System.currentTimeMillis());
+ }
+ else
+ return new ZipStreamWrapper(stream, entryName, System.currentTimeMillis());
+ }
+
+ if (longestNameMatch == null || longestNameMatch.length() < entryName.length())
+ {
+ longestNameMatch = entryName;
+ }
+ }
+ }
+ if (longestNameMatch == null)
+ throw new IllegalArgumentException("Cannot find entry: " + is + ", " + relative);
+
+ // do recursion on relative
+ bais.reset();
+ zis = new ZipInputStream(bais);
+ while((entry = zis.getNextEntry()) != null)
+ {
+ String entryName = entry.getName();
+ if (entryName.equals(longestNameMatch))
+ {
+ relative = relative.substring(longestNameMatch.length() + 1);
+ return findEntry(new SizeLimitedInputStream(zis, entry.getSize()), relative);
+ }
+ }
+ throw new IllegalArgumentException("No such entry: " + is + ", " + relative);
+ }
+
+ /**
+ * Returns archive file name - if this is a top-level ZipEntryContext.
+ * Otherwise it returns the last component of URL.
+ *
+ * @return name
+ */
+ public String getName()
+ {
+ VirtualFileHandler peer = getRootPeer();
+ if (peer != null)
+ return peer.getName();
+ else
+ return zipSource.getName();
+ }
+
+ /**
+ * Iterate through zip archive entries, compose a tree structure of archive's content
+ *
+ * @throws URISyntaxException for any URI error
+ * @throws java.io.IOException for any error
+ */
+ private synchronized void initEntries() throws IOException, URISyntaxException
+ {
+ // we're using a two phase approach - we first select the relevant ones
+ // then we order these by name and only then we process them
+ // this way we ensure that parent entries are processed before child entries
+
+ Map<String, ZipEntry> relevant = new HashMap<String, ZipEntry>();
+ zipSource.acquire();
+ try
+ {
+ Enumeration<? extends ZipEntry> zipEntries = zipSource.entries();
+ // zoom-in on entries under rootEntryPath - ignoring the rest
+ while(zipEntries.hasMoreElements())
+ {
+ ZipEntry ent = zipEntries.nextElement();
+ if(ent.getName().startsWith(rootEntryPath))
+ {
+ relevant.put(ent.getName(), ent);
+ }
+ }
+
+ Map<String, ZipEntry> orderedRelevant = new TreeMap<String, ZipEntry>(relevant);
+ for(Map.Entry<String, ZipEntry> entry : orderedRelevant.entrySet())
+ {
+ ZipEntry ent = entry.getValue();
+ String fullName = ent.getName().substring(rootEntryPath.length());
+
+ String [] split = splitParentChild(fullName);
+ String parentPath = split[0];
+ String name = split[1];
+
+ EntryInfo ei = entries.get(parentPath);
+ if(ei == null)
+ ei = makeDummyParent(parentPath);
+
+ AbstractVirtualFileHandler parent = ei != null ? ei.handler : null;
+
+ if(ent.isDirectory() == false && JarUtils.isArchive(ent.getName()))
+ {
+ boolean useCopyMode = forceCopy;
+ if (useCopyMode == false)
+ {
+ String flag = getOptions().get(VFSUtils.USE_COPY_QUERY);
+ useCopyMode = Boolean.valueOf(flag);
+ }
+
+ DelegatingHandler delegator;
+
+ if (useCopyMode)
+ {
+ // extract it to temp dir
+ File dest = new File(getTempDir() + "/" + getTempFileName(ent.getName()));
+ dest.deleteOnExit();
+
+ // ensure parent exists
+ dest.getParentFile().mkdirs();
+
+ InputStream is = zipSource.openStream(ent);
+ OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));
+ copyStreamAndClose(is, os);
+
+ // mount another instance of ZipEntryContext
+ delegator = mountZipFile(parent, name, dest);
+ }
+ else
+ {
+ // mount another instance of ZipEntryContext
+ delegator = mountZipStream(parent, name, zipSource.openStream(ent));
+ }
+
+ entries.put(delegator.getLocalPathName(), new EntryInfo(delegator, ent));
+ addChild(parent, delegator);
+ }
+ else
+ {
+ ZipEntryHandler wrapper = new ZipEntryHandler(this, parent, name, ent.isDirectory() == false);
+ entries.put(wrapper.getLocalPathName(), new EntryInfo(wrapper, ent));
+ }
+ }
+ }
+ finally
+ {
+ zipSource.release();
+ }
+ }
+
+ /**
+ * Mount ZipEntryContext created around extracted nested archive
+ *
+ * @param parent the parent
+ * @param name the name
+ * @param file the file
+ * @return mounted delegate
+ * @throws IOException for any error
+ * @throws URISyntaxException for any URI syntax error
+ */
+ protected DelegatingHandler mountZipFile(VirtualFileHandler parent, String name, File file) throws IOException, URISyntaxException
+ {
+ DelegatingHandler delegator = new DelegatingHandler(this, parent, name);
+ URL fileUrl = file.toURL();
+ URL delegatorUrl = fileUrl;
+
+ if (parent != null)
+ delegatorUrl = getChildURL(parent, name);
+
+ ZipEntryContext ctx = new ZipEntryContext(delegatorUrl, delegator, fileUrl, true);
+ VirtualFileHandler handler = ctx.getRoot();
+ delegator.setDelegate(handler);
+
+ return delegator;
+ }
+
+ /**
+ * Mount ZipEntryContext created around ZipStreamWrapper
+ *
+ * @param parent the parent
+ * @param name the name
+ * @param zipStream the zip stream
+ * @return mounted delegate
+ * @throws IOException for any error
+ * @throws URISyntaxException for any URI syntax error
+ */
+ protected DelegatingHandler mountZipStream(VirtualFileHandler parent, String name, InputStream zipStream) throws IOException, URISyntaxException
+ {
+ DelegatingHandler delegator = new DelegatingHandler(this, parent, name);
+ ZipStreamWrapper wrapper = new ZipStreamWrapper(zipStream, name, parent.getLastModified());
+
+ URL delegatorUrl = null;
+
+ if (parent != null)
+ delegatorUrl = getChildURL(parent, name);
+
+ ZipEntryContext ctx = new ZipEntryContext(delegatorUrl, delegator, wrapper, false);
+ VirtualFileHandler handler = ctx.getRoot();
+ delegator.setDelegate(handler);
+
+ return delegator;
+ }
+
+ /**
+ * Zip archives sometimes don't contain directory entries - only leaf entries
+ *
+ * @param parentPath the parent path
+ * @return entry info
+ * @throws IOException for any error
+ */
+ private EntryInfo makeDummyParent(String parentPath) throws IOException
+ {
+ // get grand parent first
+ String [] split = splitParentChild(parentPath);
+ String grandPa = split[0];
+
+ EntryInfo eiParent = entries.get(grandPa);
+ if(eiParent == null)
+ eiParent = makeDummyParent(grandPa);
+
+ ZipEntryHandler handler = new ZipEntryHandler(this, eiParent.handler, split[1], false);
+ EntryInfo ei = new EntryInfo(handler, null);
+ entries.put(parentPath, ei);
+ return ei;
+ }
+
+ /**
+ * Initialize rootEntryPath and return archive file path
+ *
+ * @param localRootUrl local root url
+ * @return file path
+ */
+ private String initRootAndPath(URL localRootUrl)
+ {
+ String filePath = localRootUrl.toString();
+ String zipPath = filePath;
+
+ int pos = filePath.indexOf("!");
+ if(pos > 0)
+ {
+ zipPath = filePath.substring(0, pos);
+ rootEntryPath = filePath.substring(pos+2);
+ if(rootEntryPath.length() != 0)
+ rootEntryPath += "/";
+ }
+
+ // find where url protocol ends - i.e. jar:file:/ ...
+ pos= zipPath.indexOf(":/");
+ filePath = zipPath.substring(pos + 1);
+
+ // cut out url query part if present
+ int queryStart = filePath.indexOf("?");
+ if (queryStart != -1)
+ filePath = filePath.substring(0, queryStart);
+
+ return filePath;
+ }
+
+ /**
+ * If archive has been modified, clear <em>entries</em> and re-initialize
+ */
+ private synchronized void checkIfModified()
+ {
+ // TODO: if zipSource represents a nested archive we should maybe delegate lastModified to its parent
+ if (zipSource.hasBeenModified())
+ {
+ EntryInfo rootInfo = entries.get("");
+ entries = new ConcurrentHashMap<String, EntryInfo>();
+ entries.put("", rootInfo);
+
+ if (zipSource.exists())
+ {
+ try
+ {
+ initEntries();
+ }
+ catch(Exception ignored)
+ {
+ log.warn("IGNORING: Failed to reinitialize context: " + getRootURI(), ignored);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns this context's root
+ *
+ * @return root handler
+ * @throws IOException for any error
+ */
+ public VirtualFileHandler getRoot() throws IOException
+ {
+ return entries.get("").handler;
+ }
+
+ /**
+ * Find a child with a given name and a given parent
+ *
+ * @param parent parent handler
+ * @param name name of the child
+ * @return child handler or null if not found
+ */
+ public VirtualFileHandler getChild(ZipEntryHandler parent, String name)
+ {
+ if (parent == null)
+ throw new IllegalArgumentException("Null parent");
+
+ checkIfModified();
+ String pathName = parent.getLocalPathName();
+ if("".equals(pathName))
+ pathName = name;
+ else
+ pathName = pathName + "/" + name;
+
+ EntryInfo ei = entries.get(pathName);
+
+ if(ei != null)
+ return ei.handler;
+
+ return null;
+ }
+
+ /**
+ * Returns a list of children for a given parent
+ *
+ * @param parent parent handler
+ * @param ignoreErrors true if errors should be silently ignored
+ * @return list of handlers representing children of the given parent
+ * @throws IOException for any error
+ */
+ public List<VirtualFileHandler> getChildren(VirtualFileHandler parent, boolean ignoreErrors) throws IOException
+ {
+ if (parent == null)
+ throw new IllegalArgumentException("Null parent");
+
+ checkIfModified();
+ if(parent instanceof AbstractVirtualFileHandler)
+ {
+ AbstractVirtualFileHandler parentHandler = (AbstractVirtualFileHandler) parent;
+ EntryInfo parentEntry = entries.get(parentHandler.getLocalPathName());
+ if (parentEntry != null)
+ {
+ if (parentEntry.handler instanceof DelegatingHandler)
+ return parentEntry.handler.getChildren(ignoreErrors);
+
+ return parentEntry.getChildren();
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ /**
+ * Returns lastModified timestamp for a given handler
+ *
+ * @param handler a handler
+ * @return lastModified timestamp
+ */
+ public long getLastModified(ZipEntryHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ checkIfModified();
+ EntryInfo ei = entries.get(handler.getLocalPathName());
+ if(ei == null)
+ return 0;
+
+ if(ei.entry == null) {
+ return zipSource.getLastModified();
+ }
+
+ return ei.entry.getTime();
+ }
+
+ /**
+ * Returns the size for a given handler
+ *
+ * @param handler a handler
+ * @return size in bytes
+ */
+ public long getSize(ZipEntryHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ checkIfModified();
+ String pathName = handler.getLocalPathName();
+ EntryInfo ei = entries.get(pathName);
+ if(ei == null)
+ return 0;
+
+ if(ei.entry == null)
+ {
+ if(pathName.length() == 0)
+ return zipSource.getSize();
+ else
+ return 0;
+ }
+
+ return ei.entry.getSize();
+ }
+
+ /**
+ * Returns true if entry exists for a given handler
+ *
+ * @param handler a handler
+ * @return true if entry exists
+ */
+ public boolean exists(ZipEntryHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ checkIfModified();
+ String pathName = handler.getLocalPathName();
+ EntryInfo ei = entries.get(pathName);
+ if(ei == null)
+ return false;
+
+ if (ei.entry == null && pathName.length() == 0)
+ return zipSource.exists();
+
+ return true;
+ }
+
+ /**
+ * Returns true if handler represents a non-directory entry
+ *
+ * @param handler a handler
+ * @return true if not a directory
+ */
+ public boolean isLeaf(ZipEntryHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ checkIfModified();
+ EntryInfo ei = entries.get(handler.getLocalPathName());
+ if(ei == null || ei.entry == null)
+ return false;
+
+ return !ei.entry.isDirectory();
+ }
+
+ /**
+ * Is archive.
+ *
+ * @param handler the handler
+ * @return true if archive
+ */
+ static boolean isArchive(VirtualFileHandler handler)
+ {
+ if (handler instanceof ZipEntryHandler && "".equals(handler.getLocalPathName()))
+ {
+ return true;
+ }
+
+ if (handler instanceof DelegatingHandler && ((DelegatingHandler) handler).getDelegate() instanceof ZipEntryHandler)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Get parent.
+ *
+ * @param handler the handler to check
+ * @return parent handler
+ * @throws IOException for any error
+ */
+ static VirtualFileHandler getParent(VirtualFileHandler handler) throws IOException
+ {
+ VirtualFileHandler parent = handler.getParent();
+ if (parent == null)
+ {
+ VirtualFileHandler peer = handler.getVFSContext().getRootPeer();
+ if (peer != null)
+ parent = peer.getParent();
+ }
+ return parent;
+ }
+
+ /**
+ * Is nested.
+ *
+ * @param handler the handler
+ * @return true if nested
+ * @throws IOException for any error
+ */
+ static boolean isNested(VirtualFileHandler handler) throws IOException
+ {
+ VirtualFileHandler parent = getParent(handler);
+ while (parent != null)
+ {
+ if(isArchive(parent))
+ return true;
+
+ parent = getParent(parent);
+ }
+ return false;
+ }
+
+ /**
+ * Contents of the file represented by a given handler
+ *
+ * @param handler a handler
+ * @return InputStream with entry's content
+ * @throws IOException for any error
+ */
+ public InputStream openStream(ZipEntryHandler handler) throws IOException
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ checkIfModified();
+
+ String localPathName = handler.getLocalPathName();
+ EntryInfo ei = entries.get(localPathName);
+
+ if (ei == null)
+ {
+ String uriStr;
+ try
+ {
+ uriStr = handler.toURI().toString();
+ }
+ catch(Exception ex)
+ {
+ throw new RuntimeException("ASSERTION ERROR - uri generation failed for ZipEntryHandler: " + handler, ex);
+ }
+ throw new FileNotFoundException(uriStr);
+ }
+
+ if(ei.entry == null)
+ {
+ if ("".equals(localPathName)) // root
+ return zipSource.getRootAsStream();
+ else // directory
+ return new ByteArrayInputStream(new byte[0]);
+ }
+
+ return zipSource.openStream(ei.entry);
+ }
+
+ /**
+ * Add a child to a given parent
+ *
+ * @param parent a parent
+ * @param child a child
+ */
+ public void addChild(AbstractVirtualFileHandler parent, AbstractVirtualFileHandler child)
+ {
+ if (parent == null)
+ throw new IllegalArgumentException("Null parent");
+
+ if (child == null)
+ throw new IllegalArgumentException("Null child");
+
+ EntryInfo parentEntry = entries.get(parent.getLocalPathName());
+ if (parentEntry != null)
+ parentEntry.add(child);
+ else
+ throw new RuntimeException("Parent does not exist: " + parent);
+ }
+
+ /**
+ * Properly release held resources
+ */
+ protected void finalize()
+ {
+ try
+ {
+ super.finalize();
+ if (zipSource != null)
+ zipSource.close();
+ }
+ catch (Throwable ignored)
+ {
+ log.debug("IGNORING: Failed to close zip source: " + zipSource, ignored);
+ }
+ }
+
+ /**
+ * Replace a current child of the given parent with another one
+ *
+ * @param parent a parent
+ * @param original current child
+ * @param replacement new child
+ */
+ public void replaceChild(ZipEntryHandler parent, AbstractVirtualFileHandler original, VirtualFileHandler replacement)
+ {
+ EntryInfo parentEntry = entries.get(parent.getLocalPathName());
+ if (parentEntry != null)
+ {
+ DelegatingHandler newOne;
+
+ if (replacement instanceof DelegatingHandler)
+ {
+ newOne = (DelegatingHandler) replacement;
+ }
+ else
+ {
+ newOne = new DelegatingHandler(this, parent, original.getName(), replacement);
+ }
+
+ synchronized(this)
+ {
+ parentEntry.replaceChild(original, newOne);
+
+ EntryInfo ei = entries.get(original.getLocalPathName());
+ ei.handler = newOne;
+ ei.entry = null;
+ ei.clearChildren();
+ }
+ }
+ else
+ {
+ throw new RuntimeException("Parent does not exist: " + parent);
+ }
+ }
+
+ /**
+ * Internal data structure holding meta information of a virtual file in this context
+ */
+ static class EntryInfo
+ {
+ /** a handler */
+ private AbstractVirtualFileHandler handler;
+
+ /** a <tt>ZipEntry</tt> */
+ private ZipEntry entry;
+
+ /** a list of children */
+ private List<AbstractVirtualFileHandler> children;
+
+ /**
+ * EntryInfo constructor
+ *
+ * @param handler a handler
+ * @param entry an entry
+ */
+ EntryInfo(AbstractVirtualFileHandler handler, ZipEntry entry)
+ {
+ this.handler = handler;
+ this.entry = entry;
+ }
+
+ /**
+ * Get children.
+ *
+ * @return returns a list of children for this handler (by copy)
+ */
+ public synchronized List<VirtualFileHandler> getChildren()
+ {
+ if (children == null)
+ return Collections.emptyList();
+
+ return new LinkedList<VirtualFileHandler>(children);
+ }
+
+ /**
+ * Replace a child.
+ *
+ * @param original existing child
+ * @param replacement new child
+ */
+ public synchronized void replaceChild(AbstractVirtualFileHandler original, AbstractVirtualFileHandler replacement)
+ {
+ if (children != null)
+ {
+ int i = 0;
+ Iterator<AbstractVirtualFileHandler> it = children.iterator();
+ while(it.hasNext())
+ {
+ AbstractVirtualFileHandler child = it.next();
+ if (child.getName().equals(original.getName()))
+ {
+ children.set(i, replacement);
+ break;
+ }
+ i++;
+ }
+ }
+ }
+
+ /**
+ * Clear the list of children
+ */
+ public synchronized void clearChildren()
+ {
+ if (children != null)
+ children.clear();
+ }
+
+ /**
+ * Add a child. If a child with the same name exists already, first remove it.
+ *
+ * @param child a child
+ */
+ public synchronized void add(AbstractVirtualFileHandler child)
+ {
+ if (children == null)
+ {
+ children = new LinkedList<AbstractVirtualFileHandler>();
+ }
+ else
+ {
+ // if a child exists with this name already, remove it
+ Iterator<AbstractVirtualFileHandler> it = children.iterator();
+ while (it.hasNext())
+ {
+ AbstractVirtualFileHandler handler = it.next();
+ if (handler.getName().equals(child.getName()))
+ {
+ it.remove();
+ break;
+ }
+ }
+ }
+
+ children.add(child);
+ }
+ }
+
+ //
+ // Helper methods
+ //
+
+ /**
+ * Copy input stream to output stream and close them both
+ *
+ * @param is input stream
+ * @param os output stream
+ * @throws IOException for any error
+ */
+ static void copyStreamAndClose(InputStream is, OutputStream os) throws IOException
+ {
+ try
+ {
+ byte [] buff = new byte[65536];
+ int count = is.read(buff);
+ while(count != -1)
+ {
+ os.write(buff, 0, count);
+ count = is.read(buff);
+ }
+ }
+ finally
+ {
+ if(is != null)
+ {
+ try {
+ is.close();
+ }
+ catch(Exception ignored)
+ {
+ }
+ }
+ os.close();
+ }
+ }
+
+ /**
+ * Make sure url protocol is <em>vfszip</em>
+ *
+ * @param rootURL the root url
+ * @return fixed url
+ * @throws MalformedURLException for any error
+ */
+ private static URL fixUrl(URL rootURL) throws MalformedURLException
+ {
+ if ("vfszip".equals(rootURL.getProtocol()) == false)
+ {
+ String url = rootURL.toString();
+ int pos = url.indexOf(":/");
+ if (pos != -1)
+ url = url.substring(pos);
+
+ return new URL("vfszip" + url);
+ }
+ return rootURL;
+ }
+
+ /**
+ * Break to path + name
+ *
+ * @param pathName the path name
+ * @return path tokens
+ */
+ public static String [] splitParentChild(String pathName)
+ {
+ if(pathName.length() == 0)
+ return new String [] {null, pathName};
+
+ int toPos = pathName.length();
+ if(pathName.charAt(pathName.length()-1) == '/')
+ toPos --;
+
+ int delimPos = pathName.lastIndexOf('/', toPos-1);
+
+ String [] ret;
+ if(delimPos == -1)
+ {
+ ret = new String []
+ {
+ "",
+ pathName.substring(delimPos+1, toPos)
+ };
+ }
+ else
+ {
+ ret = new String []
+ {
+ pathName.substring(0, delimPos),
+ pathName.substring(delimPos+1, toPos)
+ };
+ }
+ return ret;
+ }
+
+ /**
+ * Temporary files naming scheme
+ *
+ * @param name the name
+ * @return random name
+ */
+ private static String getTempFileName(String name)
+ {
+ int delim = name.lastIndexOf("/");
+ if (delim != -1)
+ name = name.substring(delim+1);
+ return UUID.randomUUID().toString().substring(0, 8) + "_" + name;
+ }
+
+ /**
+ * Use VFS's temp directory and make 'vfs-nested.tmp' sub-directory inside it for our purposes
+ *
+ * @return temp dir
+ */
+ private static String getTempDir()
+ {
+ File dir = new File(AbstractCopyMechanism.getTempDirectory(), "vfs-nested.tmp");
+ return dir.toString();
+ }
+
+ /**
+ * Delete the contents of a temporary directory. Delete first-level files only, don't drill down.
+ */
+ private static void deleteTmpDirContents()
+ {
+ try
+ {
+ File tmpDir = new File(getTempDir());
+ File [] files = tmpDir.listFiles();
+ if (files != null && files.length > 0)
+ {
+ for (File file : files)
+ {
+ if (file.isDirectory() == false && file.isHidden() == false)
+ file.delete();
+ }
+ }
+ }
+ catch(Exception ignored)
+ {
+ }
+ }
+
+ /**
+ * <tt>PriviligedAction</tt> class for checking a system property
+ */
+ private static class CheckForceCopy implements PrivilegedAction<Boolean>
+ {
+ public Boolean run()
+ {
+ String forceString = System.getProperty(VFSUtils.FORCE_COPY_KEY, "false");
+ return Boolean.valueOf(forceString);
+ }
+ }
+}
Deleted: projects/vfs/tags/2.0.0.Beta17/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java 2008-06-16 06:57:54 UTC (rev 74595)
+++ projects/vfs/tags/2.0.0.Beta17/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java 2008-06-16 14:28:54 UTC (rev 74620)
@@ -1,87 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.test.virtual.test;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import junit.textui.TestRunner;
-import org.jboss.virtual.VFS;
-
-/**
- * VFS All Test Suite.
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @author <a href="ales.justin at jboss.com">Ales Justin</a>
- * @version $Revision: 46146 $
- */
-public class VFSAllTestSuite extends TestSuite
-{
- public static void main(String[] args)
- {
- TestRunner.run(suite());
- }
-
- public static Test suite()
- {
- VFS.init();
- TestSuite suite = new TestSuite("VFS Tests default");
-
- // vfs / spi
- suite.addTest(VFSUnitTestCase.suite());
- suite.addTest(VirtualFileUnitTestCase.suite());
- // url
- suite.addTest(URLResolutionUnitTestCase.suite());
- suite.addTest(URLExistsUnitTestCase.suite());
- suite.addTest(URLConnectionUnitTestCase.suite());
- // files
- suite.addTest(FileVFSUnitTestCase.suite());
- suite.addTest(CopyFileVFSUnitTestCase.suite());
- suite.addTest(FileVFSContextUnitTestCase.suite());
- suite.addTest(FileVirtualFileHandlerUnitTestCase.suite());
- // jars
- suite.addTest(JARCacheUnitTestCase.suite());
- suite.addTest(CopyJARCacheUnitTestCase.suite());
- suite.addTest(JARVFSContextUnitTestCase.suite());
- suite.addTest(JARVirtualFileHandlerUnitTestCase.suite());
- suite.addTest(JARSerializationUnitTestCase.suite());
- suite.addTest(CopyJARSerializationUnitTestCase.suite());
- suite.addTest(JAREntryTestCase.suite());
- suite.addTest(CopyJAREntryTestCase.suite());
- suite.addTest(ZipEntryHandlerUnitTestCase.suite());
- suite.addTest(ZipEntryVFSContextUnitTestCase.suite());
- // contexts
- suite.addTest(AssembledContextTestCase.suite());
- suite.addTest(MemoryTestCase.suite());
- suite.addTest(SundryVFSUnitTestCase.suite());
- // options / policy / path
- suite.addTest(PathQueryTestCase.suite());
- suite.addTest(PathTokensTestCase.suite());
- // unpack
- suite.addTest(UnpackTestCase.suite());
- suite.addTest(ExplodeTestCase.suite());
- suite.addTest(TempTestCase.suite());
- // visitor
- suite.addTest(VisitorUnitTestCase.suite());
-
- return suite;
- }
-}
Copied: projects/vfs/tags/2.0.0.Beta17/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java (from rev 74599, projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java)
===================================================================
--- projects/vfs/tags/2.0.0.Beta17/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java (rev 0)
+++ projects/vfs/tags/2.0.0.Beta17/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java 2008-06-16 14:28:54 UTC (rev 74620)
@@ -0,0 +1,89 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.virtual.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.jboss.virtual.VFS;
+
+/**
+ * VFS All Test Suite.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ * @version $Revision: 46146 $
+ */
+public class VFSAllTestSuite extends TestSuite
+{
+ public static void main(String[] args)
+ {
+ TestRunner.run(suite());
+ }
+
+ public static Test suite()
+ {
+ VFS.init();
+ TestSuite suite = new TestSuite("VFS Tests default");
+
+ // vfs / spi
+ suite.addTest(VFSUnitTestCase.suite());
+ suite.addTest(VirtualFileUnitTestCase.suite());
+ // url
+ suite.addTest(URLResolutionUnitTestCase.suite());
+ suite.addTest(URLExistsUnitTestCase.suite());
+ suite.addTest(URLConnectionUnitTestCase.suite());
+ // files
+ suite.addTest(FileVFSUnitTestCase.suite());
+ suite.addTest(CopyFileVFSUnitTestCase.suite());
+ suite.addTest(FileVFSContextUnitTestCase.suite());
+ suite.addTest(FileVirtualFileHandlerUnitTestCase.suite());
+ // jars
+ suite.addTest(JARCacheUnitTestCase.suite());
+ suite.addTest(CopyJARCacheUnitTestCase.suite());
+ suite.addTest(JARVFSContextUnitTestCase.suite());
+ suite.addTest(JARVirtualFileHandlerUnitTestCase.suite());
+ suite.addTest(JARSerializationUnitTestCase.suite());
+ suite.addTest(CopyJARSerializationUnitTestCase.suite());
+ suite.addTest(JAREntryTestCase.suite());
+ suite.addTest(CopyJAREntryTestCase.suite());
+ suite.addTest(ZipEntryHandlerUnitTestCase.suite());
+ suite.addTest(ZipEntryVFSContextUnitTestCase.suite());
+ // contexts
+ suite.addTest(AssembledContextTestCase.suite());
+ suite.addTest(MemoryTestCase.suite());
+ suite.addTest(SundryVFSUnitTestCase.suite());
+ // options / policy / path
+ suite.addTest(PathQueryTestCase.suite());
+ suite.addTest(PathTokensTestCase.suite());
+ // unpack
+ suite.addTest(UnpackTestCase.suite());
+ suite.addTest(ExplodeTestCase.suite());
+ suite.addTest(TempTestCase.suite());
+ // visitor
+ suite.addTest(VisitorUnitTestCase.suite());
+ // utils
+ suite.addTest(VFSUtilTestCase.suite());
+
+ return suite;
+ }
+}
Copied: projects/vfs/tags/2.0.0.Beta17/src/test/java/org/jboss/test/virtual/test/VFSUtilTestCase.java (from rev 74599, projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/VFSUtilTestCase.java)
===================================================================
--- projects/vfs/tags/2.0.0.Beta17/src/test/java/org/jboss/test/virtual/test/VFSUtilTestCase.java (rev 0)
+++ projects/vfs/tags/2.0.0.Beta17/src/test/java/org/jboss/test/virtual/test/VFSUtilTestCase.java 2008-06-16 14:28:54 UTC (rev 74620)
@@ -0,0 +1,61 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.virtual.test;
+
+import java.net.URL;
+import java.util.List;
+import java.util.ArrayList;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.jboss.virtual.VFS;
+import org.jboss.virtual.VirtualFile;
+import org.jboss.virtual.VFSUtils;
+
+/**
+ * VFSUtilTestCase.
+ *
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ */
+public class VFSUtilTestCase extends AbstractMockVFSTest
+{
+ public VFSUtilTestCase(String name)
+ {
+ super(name);
+ }
+
+ public static Test suite()
+ {
+ return new TestSuite(VFSUtilTestCase.class);
+ }
+
+ public void testAddManifestLocations() throws Throwable
+ {
+ URL url = getResource("/vfs/test");
+ VirtualFile root = VFS.getRoot(url);
+ VirtualFile file = root.getChild("badmf.jar");
+ assertNotNull(file);
+ List<VirtualFile> paths = new ArrayList<VirtualFile>();
+ VFSUtils.addManifestLocations(file, paths);
+ assertEquals(3, paths.size());
+ }
+}
\ No newline at end of file
Copied: projects/vfs/tags/2.0.0.Beta17/src/test/resources/vfs/test/badmf.jar (from rev 74599, projects/vfs/trunk/src/test/resources/vfs/test/badmf.jar)
===================================================================
(Binary files differ)
More information about the jboss-cvs-commits
mailing list