diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/HollowVaultPackage.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/HollowVaultPackage.java new file mode 100644 index 0000000..487b531 --- /dev/null +++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/HollowVaultPackage.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.vault.packaging.impl; + +import java.io.File; +import java.util.Properties; + +import javax.jcr.Session; + +import org.apache.jackrabbit.vault.fs.config.MetaInf; +import org.apache.jackrabbit.vault.fs.io.Archive; +import org.apache.jackrabbit.vault.fs.io.ImportOptions; +import org.apache.jackrabbit.vault.packaging.PackageException; +import org.apache.jackrabbit.vault.packaging.PackageProperties; +import org.apache.jackrabbit.vault.packaging.VaultPackage; + +/** + * Implements a vault package that is a hollow representation of a file vault + * export i.e. when original zipped representation has been truncated. + */ +public class HollowVaultPackage extends PackagePropertiesImpl implements VaultPackage { + + private Properties properties; + + public HollowVaultPackage(Properties properties) { + this.properties = properties; + } + + @Override + public boolean isValid() { + return false; + } + + @Override + public boolean isClosed() { + return true; + } + + @Override + public MetaInf getMetaInf() { + return null; + } + + @Override + public long getSize() { + return -1; + } + + @Override + public void extract(Session session, ImportOptions opts) throws PackageException { + throw new PackageException("extract operation not supported by hollow package"); + } + + @Override + public File getFile() { + return null; + } + + @Override + public void close() { + } + + @Override + public Archive getArchive() { + return null; + } + + @Override + public PackageProperties getProperties() { + return this; + } + + @Override + protected Properties getPropertiesMap() { + return properties; + } +} diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistry.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistry.java index 95af2c5..e5598b2 100644 --- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistry.java +++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistry.java @@ -57,6 +57,7 @@ import org.apache.jackrabbit.vault.packaging.VaultPackage; import org.apache.jackrabbit.vault.packaging.events.PackageEvent; import org.apache.jackrabbit.vault.packaging.events.PackageEvent.Type; import org.apache.jackrabbit.vault.packaging.events.impl.PackageEventDispatcher; +import org.apache.jackrabbit.vault.packaging.impl.HollowVaultPackage; import org.apache.jackrabbit.vault.packaging.impl.PackagePropertiesImpl; import org.apache.jackrabbit.vault.packaging.impl.ZipVaultPackage; import org.apache.jackrabbit.vault.packaging.registry.DependencyReport; @@ -260,20 +261,28 @@ public class FSPackageRegistry extends AbstractPackageRegistry { } /** - * Opens the package of the given file. - * @param pkg Package file. + * Opens the package of a file with the given Id. + * @param id The Id of package file. * @return the package * @throws IOException if an I/O error occurrs. */ @Nonnull - protected VaultPackage open(File pkg) throws IOException { - try { - return new ZipVaultPackage(pkg, false, true); - } catch (IOException e) { - log.error("Cloud not open file {} as ZipVaultPackage.", pkg.getPath(), e); - throw e; + protected VaultPackage openPackageFile(@Nonnull PackageId id) throws IOException { + File pkg = getPackageFile(id); + if (pkg == null) { + throw new IOException("Could not find package file for id " + id); } + if (pkg.exists() && pkg.length() > 0) { + try { + return new ZipVaultPackage(pkg, false, true); + } catch (IOException e) { + log.error("Cloud not open file {} as ZipVaultPackage.", pkg.getPath(), e); + throw e; + } + } else { + return new HollowVaultPackage(getInstallState(id).getProperties()); + } } /** diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSRegisteredPackage.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSRegisteredPackage.java index 97416a4..85513a9 100644 --- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSRegisteredPackage.java +++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSRegisteredPackage.java @@ -17,7 +17,6 @@ package org.apache.jackrabbit.vault.packaging.registry.impl; import java.io.IOException; -import java.nio.file.Path; import java.util.Calendar; import javax.annotation.CheckForNull; @@ -47,7 +46,6 @@ public class FSRegisteredPackage implements RegisteredPackage { private VaultPackage vltPkg = null; private PackageId id; - private Path filepath; private PackageProperties packageProperties; private Dependency[] dependencies; private WorkspaceFilter filter; @@ -55,7 +53,6 @@ public class FSRegisteredPackage implements RegisteredPackage { public FSRegisteredPackage(FSPackageRegistry registry, FSInstallState installState) throws IOException { this.id = installState.getPackageId(); - this.filepath = installState.getFilePath(); this.dependencies = installState.getDependencies().toArray(new Dependency[installState.getDependencies().size()]); this.filter = installState.getFilter(); this.packageProperties = new FsPackageProperties(installState); @@ -73,7 +70,7 @@ public class FSRegisteredPackage implements RegisteredPackage { @Override public VaultPackage getPackage() throws IOException { if (this.vltPkg == null) { - this.vltPkg = registry.open(filepath.toFile()); + this.vltPkg = registry.openPackageFile(getId()); } return this.vltPkg; } diff --git a/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSRegisteredPackageTest.java b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSRegisteredPackageTest.java new file mode 100644 index 0000000..9eedc16 --- /dev/null +++ b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSRegisteredPackageTest.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jackrabbit.vault.packaging.registry.impl; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.jackrabbit.vault.packaging.PackageId; +import org.apache.jackrabbit.vault.packaging.VaultPackage; +import org.apache.jackrabbit.vault.packaging.impl.HollowVaultPackage; +import org.apache.jackrabbit.vault.packaging.impl.ZipVaultPackage; +import org.apache.jackrabbit.vault.packaging.registry.RegisteredPackage; +import org.junit.Test; +import org.mockito.Mockito; + +public class FSRegisteredPackageTest { + + private static final PackageId DUMMY_ID = new PackageId("someGroup", "someName", "someVersion"); + + private File getTempFile(String name) throws IOException { + InputStream in = getClass().getResourceAsStream(name); + File tmpFile = File.createTempFile("vaultpack", ".zip"); + FileOutputStream out = FileUtils.openOutputStream(tmpFile); + IOUtils.copy(in, out); + in.close(); + out.close(); + return tmpFile; + } + + private VaultPackage safeLoadVaultPackage(File packageFile) throws IOException { + if (packageFile.exists() && packageFile.length() > 0) { + return new ZipVaultPackage(packageFile, false, true); + } else { + return new HollowVaultPackage(new Properties()); + } + } + + private FSPackageRegistry newRegistry(File packageFile) throws IOException { + FSPackageRegistry registry = Mockito.mock(FSPackageRegistry.class); + Mockito.when(registry.openPackageFile(DUMMY_ID)).thenReturn(safeLoadVaultPackage(packageFile)); + return registry; + } + + private FSInstallState newInstallState(File packageFile) throws IOException { + FSInstallState installState = Mockito.mock(FSInstallState.class); + Mockito.when(installState.getFilePath()).thenReturn(packageFile.toPath()); + Mockito.when(installState.getPackageId()).thenReturn(DUMMY_ID); + return installState; + } + + @Test + public void testGetPackageFromNonTruncatedFile() throws IOException { + File packageFile = getTempFile("test-package.zip"); + RegisteredPackage regPack = new FSRegisteredPackage(newRegistry(packageFile), newInstallState(packageFile)); + try { + VaultPackage vltPack = regPack.getPackage(); + assertNotNull(vltPack); + assertNotNull(vltPack.getArchive()); + } catch (IOException e) { + fail("should not throw any exception, but thrown: " + e.getMessage()); + } finally { + regPack.close(); + } + } + + @Test + public void testGetPackageFromTruncatedFile() throws IOException { + File packageFile = getTempFile("test-package-truncated.zip"); + RegisteredPackage regPack = new FSRegisteredPackage(newRegistry(packageFile), newInstallState(packageFile)); + try { + VaultPackage vltPack = regPack.getPackage(); + assertNotNull(vltPack); + assertNull(vltPack.getArchive()); + } catch (IOException e) { + fail("should not throw any exception, but thrown: " + e.getMessage()); + } finally { + regPack.close(); + } + } + +} diff --git a/vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/registry/impl/test-package-truncated.zip b/vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/registry/impl/test-package-truncated.zip new file mode 100644 index 0000000..e69de29 diff --git a/vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/registry/impl/test-package.zip b/vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/registry/impl/test-package.zip new file mode 100644 index 0000000..b034af2 Binary files /dev/null and b/vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/registry/impl/test-package.zip differ