/*******************************************************************************
* Copyright (c) 2014, 2015 IBH SYSTEMS GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBH SYSTEMS GmbH - initial API and implementation
*******************************************************************************/
package org.eclipse.packagedrone.repo.utils.osgi.feature;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import org.eclipse.packagedrone.repo.MetaKey;
import org.eclipse.packagedrone.repo.utils.osgi.ParserHelper;
import org.eclipse.packagedrone.repo.utils.osgi.TranslatedInformation;
import org.eclipse.packagedrone.utils.Filters.Multi;
import org.eclipse.packagedrone.utils.Filters.Pair;
import org.osgi.framework.Version;
import org.osgi.framework.VersionRange;
import org.w3c.dom.Element;
public class FeatureInformation implements TranslatedInformation
{
public static final MetaKey META_KEY = new MetaKey ( "osgi", "feature-information" );
private String id;
private Version version;
private String label;
private String provider;
private String plugin;
private Map<String, Properties> localization = new HashMap<> ();
private String description;
private String descriptionUrl;
private String copyright;
private String copyrightUrl;
private String license;
private String licenseUrl;
public static class Qualifiers
{
private Set<String> operatingSystems = new TreeSet<> ();
private Set<String> windowSystems = new TreeSet<> ();
private Set<String> architectures = new TreeSet<> ();
private Set<String> languages = new TreeSet<> ();
public Set<String> getOperatingSystems ()
{
return this.operatingSystems;
}
public void setOperatingSystems ( final Set<String> operatingSystems )
{
this.operatingSystems = operatingSystems;
}
public Set<String> getWindowSystems ()
{
return this.windowSystems;
}
public void setWindowSystems ( final Set<String> windowSystems )
{
this.windowSystems = windowSystems;
}
public Set<String> getArchitectures ()
{
return this.architectures;
}
public void setArchitectures ( final Set<String> architectures )
{
this.architectures = architectures;
}
public Set<String> getLanguages ()
{
return this.languages;
}
public void setLanguages ( final Set<String> languages )
{
this.languages = languages;
}
public static Qualifiers parse ( final Element ele )
{
final String os = ele.getAttribute ( "os" );
final String ws = ele.getAttribute ( "ws" );
final String arch = ele.getAttribute ( "arch" );
final String nl = ele.getAttribute ( "nl" );
final Qualifiers q = new Qualifiers ();
q.getOperatingSystems ().addAll ( makeList ( os ) );
q.getWindowSystems ().addAll ( makeList ( ws ) );
q.getArchitectures ().addAll ( makeList ( arch ) );
q.getLanguages ().addAll ( makeList ( nl ) );
return q;
}
private static List<String> makeList ( final String string )
{
if ( string == null || string.isEmpty () )
{
return Collections.emptyList ();
}
return Arrays.asList ( string.split ( "\\s*,\\s*" ) );
}
public String toFilterString ()
{
if ( isEmpty () )
{
return null;
}
final Multi and = new Multi ( "&" );
and.addNode ( expand ( "|", "osgi.os", this.operatingSystems ) );
and.addNode ( expand ( "|", "osgi.ws", this.windowSystems ) );
and.addNode ( expand ( "|", "osgi.arch", this.architectures ) );
and.addNode ( expand ( "|", "osgi.nl", this.languages ) );
return and.toString ();
}
private Multi expand ( final String oper, final String key, final Set<String> values )
{
final Multi m = new Multi ( "|" );
for ( final String v : values )
{
m.addNode ( new Pair ( key, v ) );
}
return m;
}
public boolean isEmpty ()
{
return this.operatingSystems.isEmpty () && this.windowSystems.isEmpty () && this.architectures.isEmpty () && this.languages.isEmpty ();
}
}
public static class PluginInclude implements Comparable<PluginInclude>
{
private String id;
private Version version;
private boolean unpack;
private Qualifiers qualifiers;
public PluginInclude ( final String id, final Version version, final boolean unpack, final Qualifiers qualifiers )
{
this.id = id;
this.version = version;
this.unpack = unpack;
this.qualifiers = qualifiers;
}
public String getId ()
{
return this.id;
}
public void setId ( final String id )
{
this.id = id;
}
public Version getVersion ()
{
return this.version;
}
public void setVersion ( final Version version )
{
this.version = version;
}
public boolean isUnpack ()
{
return this.unpack;
}
public void setUnpack ( final boolean unpack )
{
this.unpack = unpack;
}
public Qualifiers getQualifiers ()
{
return this.qualifiers;
}
public void setQualifiers ( final Qualifiers qualifiers )
{
this.qualifiers = qualifiers;
}
public VersionRange makeVersionRange ()
{
if ( this.version == null )
{
return new VersionRange ( "0.0.0" );
}
else
{
return new VersionRange ( VersionRange.LEFT_CLOSED, this.version, this.version, VersionRange.RIGHT_CLOSED );
}
}
@Override
public int compareTo ( final PluginInclude o )
{
int rc;
rc = this.id.compareTo ( o.id );
if ( rc != 0 )
{
return rc;
}
return this.version.compareTo ( o.version );
}
@Override
public int hashCode ()
{
final int prime = 31;
int result = 1;
result = prime * result + ( this.id == null ? 0 : this.id.hashCode () );
result = prime * result + ( this.version == null ? 0 : this.version.hashCode () );
return result;
}
@Override
public boolean equals ( final Object obj )
{
if ( this == obj )
{
return true;
}
if ( obj == null )
{
return false;
}
if ( ! ( obj instanceof PluginInclude ) )
{
return false;
}
final PluginInclude other = (PluginInclude)obj;
if ( this.id == null )
{
if ( other.id != null )
{
return false;
}
}
else if ( !this.id.equals ( other.id ) )
{
return false;
}
if ( this.version == null )
{
if ( other.version != null )
{
return false;
}
}
else if ( !this.version.equals ( other.version ) )
{
return false;
}
return true;
}
}
public static class FeatureInclude implements Comparable<FeatureInclude>
{
private final String id;
private final Version version;
private final String name;
private final boolean optional;
private final Qualifiers qualifiers;
public FeatureInclude ( final String id, final Version version, final String name, final boolean optional, final Qualifiers qualifiers )
{
this.id = id;
this.version = version;
this.name = name;
this.optional = optional;
this.qualifiers = qualifiers;
}
public String getId ()
{
return this.id;
}
public Version getVersion ()
{
return this.version;
}
public String getName ()
{
return this.name;
}
public boolean isOptional ()
{
return this.optional;
}
public Qualifiers getQualifiers ()
{
return this.qualifiers;
}
public VersionRange makeVersionRange ()
{
if ( this.version == null )
{
return new VersionRange ( "0.0.0" );
}
else
{
return new VersionRange ( VersionRange.LEFT_CLOSED, this.version, this.version, VersionRange.RIGHT_CLOSED );
}
}
@Override
public int compareTo ( final FeatureInclude o )
{
int rc;
rc = this.id.compareTo ( o.id );
if ( rc != 0 )
{
return rc;
}
return this.version.compareTo ( o.version );
}
@Override
public int hashCode ()
{
final int prime = 31;
int result = 1;
result = prime * result + ( this.id == null ? 0 : this.id.hashCode () );
result = prime * result + ( this.version == null ? 0 : this.version.hashCode () );
return result;
}
@Override
public boolean equals ( final Object obj )
{
if ( this == obj )
{
return true;
}
if ( obj == null )
{
return false;
}
if ( ! ( obj instanceof FeatureInclude ) )
{
return false;
}
final FeatureInclude other = (FeatureInclude)obj;
if ( this.id == null )
{
if ( other.id != null )
{
return false;
}
}
else if ( !this.id.equals ( other.id ) )
{
return false;
}
if ( this.version == null )
{
if ( other.version != null )
{
return false;
}
}
else if ( !this.version.equals ( other.version ) )
{
return false;
}
return true;
}
}
public static class Requirement implements Comparable<Requirement>
{
public static enum Type
{
FEATURE,
PLUGIN
}
public static enum MatchRule
{
DEFAULT ( "default" )
{
@Override
public VersionRange makeRange ( final Version version )
{
return new VersionRange ( "0.0.0" );
}
},
EQUIVALENT ( "equivalent" )
{
@Override
public VersionRange makeRange ( final Version version )
{
final Version endVersion = new Version ( version.getMajor (), version.getMinor () + 1, 0 );
return new VersionRange ( VersionRange.LEFT_CLOSED, version, endVersion, VersionRange.RIGHT_OPEN );
}
},
COMPATIBLE ( "compatible" )
{
@Override
public VersionRange makeRange ( final Version version )
{
final Version endVersion = new Version ( version.getMajor () + 1, 0, 0 );
return new VersionRange ( VersionRange.LEFT_CLOSED, version, endVersion, VersionRange.RIGHT_OPEN );
}
},
PERFECT ( "perfect" )
{
@Override
public VersionRange makeRange ( final Version version )
{
return new VersionRange ( VersionRange.LEFT_CLOSED, version, version, VersionRange.RIGHT_CLOSED );
}
},
GREATER_OR_EQUAL ( "greaterOrEqual" )
{
@Override
public VersionRange makeRange ( final Version version )
{
return new VersionRange ( version.toString () );
}
};
private String id;
private MatchRule ( final String id )
{
this.id = id;
}
public String getId ()
{
return this.id;
}
public static MatchRule findById ( final String id )
{
for ( final MatchRule mr : values () )
{
if ( mr.getId ().equals ( id ) )
{
return mr;
}
}
return null;
}
public abstract VersionRange makeRange ( Version version );
}
private final Type type;
private final String id;
private final Version version;
private final MatchRule matchRule;
public Requirement ( final Type type, final String id, final Version version, final MatchRule matchRule )
{
this.type = type;
this.id = id;
this.version = version;
this.matchRule = matchRule;
}
public Type getType ()
{
return this.type;
}
public String getId ()
{
return this.id;
}
public Version getVersion ()
{
return this.version;
}
public MatchRule getMatchRule ()
{
return this.matchRule;
}
@Override
public int compareTo ( final Requirement o )
{
int rc;
rc = this.id.compareTo ( o.id );
return rc;
}
}
private Qualifiers qualifiers;
private Set<Requirement> requirements = new HashSet<> ();
private Set<FeatureInclude> includedFeatures = new HashSet<> ();
private Set<PluginInclude> includedPlugins = new HashSet<> ();
public void setQualifiers ( final Qualifiers qualifiers )
{
this.qualifiers = qualifiers;
}
public Qualifiers getQualifiers ()
{
return this.qualifiers;
}
public void setIncludedPlugins ( final Set<PluginInclude> includedPlugins )
{
this.includedPlugins = includedPlugins;
}
public Set<PluginInclude> getIncludedPlugins ()
{
return this.includedPlugins;
}
public void setRequirements ( final Set<Requirement> requirements )
{
this.requirements = requirements;
}
public Set<Requirement> getRequirements ()
{
return this.requirements;
}
public void setIncludedFeatures ( final Set<FeatureInclude> includedFeatures )
{
this.includedFeatures = includedFeatures;
}
public Set<FeatureInclude> getIncludedFeatures ()
{
return this.includedFeatures;
}
public void setLocalization ( final Map<String, Properties> localization )
{
this.localization = localization;
}
@Override
public Map<String, Properties> getLocalization ()
{
return this.localization;
}
public void setPlugin ( final String plugin )
{
this.plugin = plugin;
}
public String getPlugin ()
{
return this.plugin;
}
public void setId ( final String id )
{
this.id = id;
}
public String getId ()
{
return this.id;
}
public Version getVersion ()
{
return this.version;
}
public void setVersion ( final Version version )
{
this.version = version;
}
public String getLabel ()
{
return this.label;
}
public void setLabel ( final String label )
{
this.label = label;
}
public String getProvider ()
{
return this.provider;
}
public void setProvider ( final String provider )
{
this.provider = provider;
}
public String getDescription ()
{
return this.description;
}
public void setDescription ( final String description )
{
this.description = description;
}
public String getDescriptionUrl ()
{
return this.descriptionUrl;
}
public void setDescriptionUrl ( final String descriptionUrl )
{
this.descriptionUrl = descriptionUrl;
}
public String getCopyright ()
{
return this.copyright;
}
public void setCopyright ( final String copyright )
{
this.copyright = copyright;
}
public String getCopyrightUrl ()
{
return this.copyrightUrl;
}
public void setCopyrightUrl ( final String copyrightUrl )
{
this.copyrightUrl = copyrightUrl;
}
public String getLicense ()
{
return this.license;
}
public void setLicense ( final String license )
{
this.license = license;
}
public String getLicenseUrl ()
{
return this.licenseUrl;
}
public void setLicenseUrl ( final String licenseUrl )
{
this.licenseUrl = licenseUrl;
}
@Override
public String toString ()
{
return String.format ( "[Feature: %s]", this.id );
}
public static FeatureInformation fromJson ( final String string )
{
return fromJson ( string, FeatureInformation.class );
}
public static <T extends FeatureInformation> T fromJson ( final String string, final Class<T> clazz )
{
if ( string == null )
{
return null;
}
return ParserHelper.newGson ().fromJson ( string, clazz );
}
public String toJson ()
{
return ParserHelper.newGson ().toJson ( this );
}
}