org.eclipse.packager.rpm.info.RpmInformations Maven / Gradle / Ivy
/**
* Copyright (c) 2016, 2019 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.packager.rpm.info;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.compress.archivers.cpio.CpioArchiveEntry;
import org.apache.commons.compress.archivers.cpio.CpioArchiveInputStream;
import org.eclipse.packager.rpm.RpmSignatureTag;
import org.eclipse.packager.rpm.RpmTag;
import org.eclipse.packager.rpm.info.RpmInformation.Dependency;
import org.eclipse.packager.rpm.parse.InputHeader;
import org.eclipse.packager.rpm.parse.RpmInputStream;
public final class RpmInformations
{
private RpmInformations ()
{
}
public static RpmInformation makeInformation ( final RpmInputStream in ) throws IOException
{
final InputHeader header = in.getPayloadHeader ();
final InputHeader signature = in.getSignatureHeader ();
final RpmInformation result = new RpmInformation ();
result.setHeaderStart ( header.getStart () );
result.setHeaderEnd ( header.getStart () + header.getLength () );
result.setName ( asString ( header.getTag ( RpmTag.NAME ) ) );
result.setArchitecture ( asString ( header.getTag ( RpmTag.ARCH ) ) );
result.setSummary ( asString ( header.getTag ( RpmTag.SUMMARY ) ) );
result.setDescription ( asString ( header.getTag ( RpmTag.DESCRIPTION ) ) );
result.setPackager ( asString ( header.getTag ( RpmTag.PACKAGER ) ) );
result.setUrl ( asString ( header.getTag ( RpmTag.URL ) ) );
result.setLicense ( asString ( header.getTag ( RpmTag.LICENSE ) ) );
result.setVendor ( asString ( header.getTag ( RpmTag.VENDOR ) ) );
result.setGroup ( asString ( header.getTag ( RpmTag.GROUP ) ) );
result.setBuildHost ( asString ( header.getTag ( RpmTag.BUILDHOST ) ) );
result.setBuildTimestamp ( asLong ( header.getTag ( RpmTag.BUILDTIME ) ) );
result.setSourcePackage ( asString ( header.getTag ( RpmTag.SOURCE_PACKAGE ) ) );
result.setInstalledSize ( asLong ( header.getTag ( RpmTag.SIZE ) ) );
result.setArchiveSize ( asLong ( header.getTag ( RpmTag.ARCHIVE_SIZE ) ) );
if ( result.getArchiveSize () == null )
{
result.setArchiveSize ( asLong ( signature.getTag ( RpmSignatureTag.PAYLOAD_SIZE ) ) );
}
// version
final RpmInformation.Version ver = new RpmInformation.Version ( asString ( header.getTag ( RpmTag.VERSION ) ), asString ( header.getTag ( RpmTag.RELEASE ) ), asString ( header.getTag ( RpmTag.EPOCH ) ) );
result.setVersion ( ver );
// changelog
final Object val = header.getTag ( RpmTag.CHANGELOG_TIMESTAMP );
if ( val instanceof Long[] )
{
final Long[] ts = (Long[])val;
final String[] authors = (String[])header.getTag ( RpmTag.CHANGELOG_AUTHOR );
final String[] texts = (String[])header.getTag ( RpmTag.CHANGELOG_TEXT );
final List changes = new ArrayList<> ( ts.length );
for ( int i = 0; i < ts.length; i++ )
{
changes.add ( new RpmInformation.Changelog ( ts[i], authors[i], texts[i] ) );
}
Collections.sort ( changes, ( o1, o2 ) -> Long.compare ( o1.getTimestamp (), o2.getTimestamp () ) );
result.setChangelog ( changes );
}
// dependencies
result.setProvides ( makeDependencies ( header, RpmTag.PROVIDE_NAME, RpmTag.PROVIDE_VERSION, RpmTag.PROVIDE_FLAGS ) );
result.setRequires ( makeDependencies ( header, RpmTag.REQUIRE_NAME, RpmTag.REQUIRE_VERSION, RpmTag.REQUIRE_FLAGS ) );
result.setConflicts ( makeDependencies ( header, RpmTag.CONFLICT_NAME, RpmTag.CONFLICT_VERSION, RpmTag.CONFLICT_FLAGS ) );
result.setObsoletes ( makeDependencies ( header, RpmTag.OBSOLETE_NAME, RpmTag.OBSOLETE_VERSION, RpmTag.OBSOLETE_FLAGS ) );
// files
final CpioArchiveInputStream cpio = in.getCpioStream ();
CpioArchiveEntry cpioEntry;
while ( ( cpioEntry = cpio.getNextCPIOEntry () ) != null )
{
final String name = normalize ( cpioEntry.getName () );
if ( cpioEntry.isRegularFile () )
{
result.getFiles ().add ( name );
}
else if ( cpioEntry.isDirectory () )
{
result.getDirectories ().add ( name );
}
}
cpio.close ();
return result;
}
public static List makeDependencies ( final InputHeader header, final RpmTag namesTag, final RpmTag versionsTag, final RpmTag flagsTag )
{
Object namesVal = header.getTag ( namesTag );
Object versionsVal = header.getTag ( versionsTag );
Object flagsVal = header.getTag ( flagsTag );
if ( namesVal == null || ! ( namesVal instanceof String[] ) )
{
if ( namesVal instanceof String )
{
namesVal = new String[] { (String)namesVal };
}
else
{
return Collections.emptyList ();
}
}
if ( versionsVal != null && ! ( versionsVal instanceof String[] ) )
{
if ( versionsVal instanceof String )
{
versionsVal = new String[] { (String)versionsVal };
}
else
{
throw new IllegalStateException ( String.format ( "Invalid dependencies version format [%s]: %s", versionsTag, versionsVal ) );
}
}
if ( flagsVal != null && ! ( flagsVal instanceof Long[] ) )
{
if ( flagsVal instanceof Long )
{
flagsVal = new Long[] { (Long)flagsVal };
}
else if ( flagsVal instanceof Integer )
{
flagsVal = new Long[] { ( (Integer)flagsVal ).longValue () };
}
else if ( flagsVal instanceof Integer[] )
{
flagsVal = Arrays.stream ( (Integer[])flagsVal ).map ( Integer::longValue ).toArray ( Long[]::new );
}
else
{
throw new IllegalStateException ( String.format ( "Invalid dependencies flags format [%s]: %s", flagsTag, flagsVal ) );
}
}
final String[] names = (String[])namesVal;
final String[] versions = (String[])versionsVal;
final Long[] flags = (Long[])flagsVal;
if ( versions != null && names.length != versions.length )
{
throw new IllegalStateException ( String.format ( "Invalid size of dependency versions array [%s] - expected: %s, actual: %s", versionsTag, names.length, versions.length ) );
}
if ( flags != null && names.length != flags.length )
{
throw new IllegalStateException ( String.format ( "Invalid size of dependency flags array [%s] - expected: %s, actual: %s", flagsTag, names.length, flags.length ) );
}
final List result = new ArrayList<> ( names.length );
final Set known = new HashSet<> ();
for ( int i = 0; i < names.length; i++ )
{
final String name = names[i];
String version = versions != null ? versions[i] : null;
if ( version != null && version.isEmpty () )
{
version = null;
}
final Long flag = flags != null ? flags[i] : null;
final String key = name; // for now the key is the name
if ( known.add ( key ) )
{
result.add ( new Dependency ( name, version, flag != null ? flag : 0L ) );
}
}
return result;
}
public static String normalize ( final String name )
{
if ( name.startsWith ( "./" ) )
{
return name.substring ( 1 );
}
return name;
}
public static String asString ( final Object value )
{
if ( value == null )
{
return null;
}
if ( value instanceof String )
{
return (String)value;
}
if ( value instanceof String[] )
{
final String[] values = (String[])value;
if ( values.length > 0 )
{
return values[0];
}
return null;
}
return value.toString ();
}
public static Long asLong ( final Object value )
{
if ( value == null )
{
return null;
}
if ( value instanceof Number )
{
return ( (Number)value ).longValue ();
}
try
{
return Long.parseLong ( value.toString () );
}
catch ( final NumberFormatException e )
{
return null;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy