Skip to content
Permalink
Browse files
FELIX-518 - support localization and signature files:
- ignore signature files (for now);
- allow localization files to precede bundle files.



git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1716193 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
Jan Willem Janssen committed Nov 24, 2015
1 parent d75cb0a commit 30f2afb9ad42fef83ccf5f74769f5ff75fd7ae88
Show file tree
Hide file tree
Showing 10 changed files with 245 additions and 48 deletions.
@@ -24,6 +24,7 @@
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.jar.Manifest;

@@ -160,7 +161,7 @@ public boolean uninstallForced() throws DeploymentException {
* @param manifest The manifest of the deployment package.
* @param bundleContext The bundle context.
* @throws DeploymentException Thrown if the specified manifest does not
* describe a valid deployment package.
* describe a valid deployment package.
*/
public AbstractDeploymentPackage(Manifest manifest, BundleContext bundleContext, DeploymentAdminImpl deploymentAdmin) throws DeploymentException {
m_manifest = new DeploymentPackageManifest(manifest);
@@ -279,7 +280,7 @@ public BundleInfo[] getBundleInfos() {
* @return Stream to the bundle identified by the specified symbolic name or
* null if no such bundle exists in this deployment package.
* @throws IOException If the bundle can not be properly offered as an
* inputstream
* inputstream
*/
public abstract InputStream getBundleStream(String symbolicName) throws IOException;

@@ -491,12 +492,25 @@ public boolean uninstallForced() throws DeploymentException {
* it's path/resource-id.
*
* @param path String containing a resource path (either bundle or processed
* resource)
* resource)
* @return <code>AbstractInfoImpl</code> for the resource identified by the
* specified path or null if the path is unknown
*/
protected AbstractInfo getAbstractInfoByPath(String path) {
return (AbstractInfo) m_pathToEntry.get(path);
}

/**
* Returns whether the given name (which is expected to be the name of a
* JarEntry) is a signature file or the JAR index file.
*
* @param name the name of the JAR entry to test, cannot be
* <code>null</code>.
* @return <code>true</code> if the given JAR entry name is a signature file
* or JAR index file, <code>false</code> otherwise.
*/
protected boolean isMetaInfFile(String name) {
name = name.toUpperCase(Locale.US);
return name.startsWith("META-INF/") && (name.endsWith("/INDEX.LIST") || name.endsWith(".SF") || name.endsWith(".DSA") || name.endsWith(".RS"));
}
}
@@ -35,6 +35,7 @@
public class StreamDeploymentPackage extends AbstractDeploymentPackage {
private final JarInputStream m_input;
private final List m_names = new ArrayList();
private boolean m_inMetaInf = true;

/**
* Creates an instance of this class.
@@ -57,17 +58,37 @@ public InputStream getCurrentEntryStream() {
}

public AbstractInfo getNextEntry() throws IOException {
ZipEntry nextEntry = m_input.getNextJarEntry();
if (nextEntry == null) {
return null;
String name;

boolean metaInfFile = true;
do {
ZipEntry nextEntry = m_input.getNextJarEntry();
if (nextEntry == null) {
return null;
}
name = nextEntry.getName();

// FELIX-518: do not try to process signature or localization files...
metaInfFile = isMetaInfFile(name);
if (metaInfFile) {
if (!m_inMetaInf) {
throw new IOException("Unexpected signature file found after manifest files: " + name);
}
else {
continue;
}
}
}
String name = nextEntry.getName();
while (metaInfFile);

m_inMetaInf = false;
m_names.add(name);
AbstractInfo abstractInfoByPath = getAbstractInfoByPath(name);
return abstractInfoByPath;

return getAbstractInfoByPath(name);
}

// This only works for those resources that have been read from the stream already, no guarantees for remainder of stream
// This only works for those resources that have been read from the stream already, no guarantees for remainder of
// stream
public BundleInfoImpl[] getOrderedBundleInfos() {
List result = new ArrayList();

@@ -65,6 +65,10 @@ protected void doExecute(DeploymentSessionImpl session) throws Exception {
String name = entry.getPath();
BundleInfoImpl bundleInfo = (BundleInfoImpl) expectedBundles.remove(name);
if (bundleInfo == null) {
if (isLocalizationFile(name)) {
// FELIX-518: do not try to process signature or localization files...
continue;
}
throw new DeploymentException(CODE_OTHER_ERROR, "Resource '" + name + "' is not described in the manifest.");
}

@@ -100,8 +104,8 @@ protected void doExecute(DeploymentSessionImpl session) throws Exception {

Version targetVersion = getVersion(bundle);
if (!sourceVersion.equals(targetVersion)) {
throw new DeploymentException(CODE_OTHER_ERROR, "Installed/updated bundle version (" + targetVersion + ") do not match what was installed/updated: " + sourceVersion
+ ", offending bundle = " + bsn);
throw new DeploymentException(CODE_OTHER_ERROR,
"Installed/updated bundle version (" + targetVersion + ") do not match what was installed/updated: " + sourceVersion + ", offending bundle = " + bsn);
}
}
}
@@ -114,6 +118,10 @@ private Version getVersion(Bundle bundle) {
return Version.parseVersion((String) bundle.getHeaders().get(BUNDLE_VERSION));
}

private boolean isLocalizationFile(String name) {
return name.startsWith("OSGI-INF/l10n/");
}

private static class UninstallBundleRunnable extends AbstractAction {
private final Bundle m_bundle;
private final LogService m_log;
@@ -20,7 +20,7 @@
</parent>
<properties>
<osgi.version>4.2.0</osgi.version>
<pax.exam.version>3.4.0</pax.exam.version>
<pax.exam.version>3.6.0</pax.exam.version>
<pax.url.version>1.6.0</pax.url.version>
</properties>
<name>Apache Felix DeploymentAdmin Integration Tests</name>
@@ -46,7 +46,7 @@
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.dependencymanager</artifactId>
<version>3.1.0</version>
<version>4.1.1</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -58,7 +58,7 @@
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.metatype</artifactId>
<version>1.0.6</version>
<version>1.1.2</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -82,7 +82,12 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
<scope>test</scope>
</dependency>

@@ -114,13 +119,13 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.2</version>
<version>1.1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
<version>1.1.3</version>
<scope>test</scope>
</dependency>

@@ -147,6 +152,14 @@
<source>1.6</source>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
@@ -88,6 +88,7 @@ public Option[] config() throws Exception {
mavenBundle("org.apache.felix", "org.apache.felix.deploymentadmin").versionAsInProject(),
mavenBundle("org.apache.felix", "org.apache.felix.eventadmin").versionAsInProject(),
mavenBundle("org.apache.felix", "org.apache.felix.configadmin").versionAsInProject(),
mavenBundle("commons-codec", "commons-codec").versionAsInProject(),

junitBundles()
);
@@ -19,6 +19,7 @@
package org.apache.felix.deploymentadmin.itest;

import java.io.File;
import java.net.URL;

import org.apache.felix.deploymentadmin.itest.util.DeploymentPackageBuilder;
import org.apache.felix.deploymentadmin.itest.util.DeploymentPackageBuilder.JarManifestManipulatingFilter;
@@ -36,6 +37,24 @@
@RunWith(PaxExam.class)
public class InstallDeploymentPackageTest extends BaseIntegrationTest
{
/**
* FELIX-518 - Test that DP with localization and signature files are properly deployed.
*/
@Test
public void testInstallDeploymentPackageWithLocalizationAndSignatureFilesOk() throws Exception {
URL dpProps = getClass().getResource("/dp.properties");
assertNotNull(dpProps);

DeploymentPackageBuilder dpBuilder = createNewDeploymentPackageBuilder("1.0.0");
dpBuilder
.addSignatures()
.add(dpBuilder.createLocalizationResource().setUrl(dpProps).setResourceProcessorPID(TEST_FAILING_BUNDLE_RP1).setFilename("dp.properties"))
.add(dpBuilder.createResourceProcessorResource().setUrl(getTestBundleURL("rp1")));

installDeploymentPackage(dpBuilder);
}


/**
* FELIX-4409/4410/4463 - test the installation of an invalid deployment package.
*/
@@ -66,6 +66,10 @@ public boolean isBundle() {
return m_isBundle;
}

public boolean isLocalizationFile() {
return m_filename.startsWith("OSGI-INF/l10n/");
}

public boolean isCustomizer() {
return m_isCustomizer;
}

0 comments on commit 30f2afb

Please sign in to comment.