blob: 29a5e308f33d5df503bce0994263fb25747b5db9 [file] [log] [blame]
/*
* 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.framework.util;
import org.apache.felix.framework.cache.BundleCache;
import org.apache.felix.framework.cache.Content;
import org.osgi.framework.Version;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;
public class MultiReleaseContent implements Content
{
private final Content m_content;
private final int m_javaVersion;
MultiReleaseContent(int javaVersion, Content content)
{
m_javaVersion = javaVersion;
m_content = content;
}
public static Content wrap(String javaVersionString, Content content)
{
int javaVersion = 8;
try
{
javaVersion = Version.parseVersion(javaVersionString).getMajor();
}
catch (Exception ex)
{
}
if (javaVersion > 8)
{
try
{
byte[] versionManifestInput = content.getEntryAsBytes("META-INF/MANIFEST.MF");
if (versionManifestInput != null)
{
Map<String, Object> versionManifest = BundleCache.getMainAttributes(
new StringMap(), new ByteArrayInputStream(versionManifestInput), versionManifestInput.length);
if ("true".equals(versionManifest.get("Multi-Release")))
{
content = new MultiReleaseContent(javaVersion, content);
}
}
}
catch (Exception ex)
{
}
}
return content;
}
@Override
public void close()
{
m_content.close();
}
@Override
public boolean hasEntry(String name)
{
return m_content.hasEntry(findPath(name));
}
@Override
public Enumeration<String> getEntries()
{
Enumeration<String> entries = m_content.getEntries();
if (entries != null)
{
Set<String> result = new LinkedHashSet<String>();
while (entries.hasMoreElements())
{
String path = entries.nextElement();
result.add(path);
String internalPath = path;
while (internalPath.startsWith("/"))
{
internalPath = internalPath.substring(1);
}
if (internalPath.startsWith("META-INF/versions/") )
{
int idx = internalPath.indexOf('/', "META-INF/versions/".length());
if ((idx != -1) && (idx + 1) < internalPath.length())
{
int version = Version.parseVersion(internalPath.substring("META-INF/versions/".length(), idx)).getMajor();
if ((version > 8) && (version <= m_javaVersion))
{
internalPath = internalPath.substring(idx + 1);
if (!internalPath.startsWith("META-INF/"))
{
result.add(internalPath);
}
}
}
}
}
return Collections.enumeration(result);
}
else
{
return entries;
}
}
@Override
public byte[] getEntryAsBytes(String name)
{
return m_content.getEntryAsBytes(findPath(name));
}
@Override
public InputStream getEntryAsStream(String name) throws IOException
{
return m_content.getEntryAsStream(findPath(name));
}
@Override
public Content getEntryAsContent(String name)
{
return m_content.getEntryAsContent(findPath(name));
}
@Override
public String getEntryAsNativeLibrary(String name)
{
return m_content.getEntryAsNativeLibrary(findPath(name));
}
@Override
public URL getEntryAsURL(String name)
{
return m_content.getEntryAsURL(findPath(name));
}
@Override
public long getContentTime(String name)
{
return m_content.getContentTime(findPath(name));
}
private String findPath(String path)
{
String internalPath = path;
while (internalPath.startsWith("/"))
{
internalPath = internalPath.substring(1);
}
if (!internalPath.startsWith("META-INF/"))
{
int version = m_javaVersion;
while (version >= 9)
{
String versionPath = "META-INF/versions/" + version-- + "/" + internalPath;
if (m_content.hasEntry(versionPath))
{
return versionPath;
}
}
}
return path;
}
}