/* * 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.felix.deploymentadmin; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.jar.JarInputStream; import java.util.zip.ZipEntry; import org.osgi.framework.BundleContext; import org.osgi.service.deploymentadmin.DeploymentException; /** * This class represents a deployment package that is read from a jar stream. */ 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. * * @param input The stream from which the deployment package can be read. * @param bundleContext The bundle context. * @throws DeploymentException If it was not possible to read a valid deployment package from the specified stream. */ public StreamDeploymentPackage(JarInputStream input, BundleContext bundleContext, DeploymentAdminImpl deploymentAdmin) throws DeploymentException { super(input.getManifest(), bundleContext, deploymentAdmin); m_input = input; } public InputStream getBundleStream(String symbolicName) { throw new UnsupportedOperationException("Not applicable for stream-based deployment package"); } public InputStream getCurrentEntryStream() { return new NonCloseableStream(m_input); } public AbstractInfo getNextEntry() throws IOException { 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; } } } while (metaInfFile); m_inMetaInf = false; m_names.add(name); return getAbstractInfoByPath(name); } // 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(); // add all bundle resources ordered by location in stream for (Iterator i = m_names.iterator(); i.hasNext();) { String indexEntry = (String) i.next(); AbstractInfo bundleInfo = getBundleInfoByPath(indexEntry); if (bundleInfo != null) { result.add(bundleInfo); } } // add bundle resources marked missing to the end of the result BundleInfoImpl[] bundleInfoImpls = getBundleInfoImpls(); for (int i = 0; i < bundleInfoImpls.length; i++) { if (bundleInfoImpls[i].isMissing()) { result.add(bundleInfoImpls[i]); } } return (BundleInfoImpl[]) result.toArray(new BundleInfoImpl[result.size()]); } public ResourceInfoImpl[] getOrderedResourceInfos() { throw new UnsupportedOperationException("Not applicable for stream-based deployment package"); } }