public final class SymbolDependency extends java.lang.Object implements SymbolDependencyContainer, ToSmithyBuilder<SymbolDependency>, java.lang.Comparable<SymbolDependency>
Symbol
.
SymbolProvider
implementations sometimes need to refer to
Symbol
values that require a dependency to be brought in when
generating code. A dependency can be associated with the Symbol to
specify the relationship of a Symbol to a dependency.
This dependency class was designed to be as generic as possible while
still allowing for some extension points through typed properties.
If a feature you need is missing (for example, specifying a GitHub
repository), use TypedPropertiesBag.Builder.putProperty(java.lang.String, java.lang.Object)
to add a
property on the dependency that can be understood by you code generator.
It's up to code generators to make sense of the values provided in a
dependency and to aggregate them in a meaningful way. This class uses a
package + version combination to define the coordinates of a dependency.
Some dependency managers like Maven use a group + package + version
combination. In cases like this, it is recommended to specify the
package
of the symbol as the group + package name (e.g.,
"software.amazon.smithy.model:0.9.3" becomes a package of
"software.amazon.smithy.model" and a version of "0.9.3").
The dependencyType
of a dependency is application and
target-specific. When omitted, it defaults to an empty string (""). An
arbitrary string value can be provided and should refer to something that
makes sense for the target language. For illustrative purposed only:
a code generator that targets JavaScript and NPM could set the
dependencyType
of a dependency to "devDependencies" to add the
dependency to the "devDependencies" property of a generated package.json.
version
is also an opaque values that is target-specific and
can even be specific to a dependencyType
. For example, PHP's
Composer provides a section named "suggest" that is a map of package names
to a description of the suggestion. A SymbolDependency
that is
meant to define a "suggest" entry for a composer.json file could set the
dependencyType
to "suggest", the packageName
to the name
of the suggested package, and version
to the description of the
suggestion.
Modifier and Type | Class and Description |
---|---|
static class |
SymbolDependency.Builder
Builds a SymbolDependency.
|
Modifier and Type | Method and Description |
---|---|
static SymbolDependency.Builder |
builder() |
int |
compareTo(SymbolDependency other)
Dependencies can be sorted based on the natural sort order of
the dependencyType, packageName, and finally the version.
|
boolean |
equals(java.lang.Object o) |
java.lang.Object |
expectProperty(java.lang.String name)
Gets a specific additional property or throws if missing.
|
<T> T |
expectProperty(java.lang.String name,
java.lang.Class<T> type)
Gets a specific additional property or throws if missing or if the
property is not an instance of the given type.
|
static java.util.Map<java.lang.String,java.util.Map<java.lang.String,SymbolDependency>> |
gatherDependencies(java.util.stream.Stream<SymbolDependency> symbolStream)
Gets a mapping of all dependencies used by the provided symbols.
|
static java.util.Map<java.lang.String,java.util.Map<java.lang.String,SymbolDependency>> |
gatherDependencies(java.util.stream.Stream<SymbolDependency> symbolStream,
java.util.function.BinaryOperator<SymbolDependency> versionMergeFunction)
Gets a mapping of all dependencies used by the provided symbols.
|
java.util.List<SymbolDependency> |
getDependencies()
Gets the list of dependencies that this object introduces.
|
java.lang.String |
getDependencyType()
Gets the type of dependency (for example, "dev", "optional", etc).
|
java.lang.String |
getPackageName()
Gets the package name referenced by the dependency.
|
java.util.Map<java.lang.String,java.lang.Object> |
getProperties()
Gets the additional properties of the object.
|
java.util.Optional<java.lang.Object> |
getProperty(java.lang.String name)
Gets a specific property if present.
|
<T> java.util.Optional<T> |
getProperty(java.lang.String name,
java.lang.Class<T> type)
Gets an additional property of a specific type.
|
java.lang.String |
getVersion()
Gets the version string of the dependency.
|
int |
hashCode() |
SymbolDependency.Builder |
toBuilder()
Take this object and create a builder that contains all of the
current property values of this object.
|
java.lang.String |
toString() |
public static SymbolDependency.Builder builder()
public static java.util.Map<java.lang.String,java.util.Map<java.lang.String,SymbolDependency>> gatherDependencies(java.util.stream.Stream<SymbolDependency> symbolStream)
Given a stream of symbols, the dependencies of the symbol are gathered into a map of the dependencyType to a map of a package name to package version.
By default, when two versions conflict, an exception is thrown. In the
case the a conflict is possible or it is necessary to detect incompatibilities,
use gatherDependencies(Stream, BinaryOperator)
and provide a
custom version merge function.
symbolStream
- Stream of symbols to compute from.CodegenException
- when two package versions conflict.public static java.util.Map<java.lang.String,java.util.Map<java.lang.String,SymbolDependency>> gatherDependencies(java.util.stream.Stream<SymbolDependency> symbolStream, java.util.function.BinaryOperator<SymbolDependency> versionMergeFunction)
Given a stream of symbols, the dependencies of the symbol are gathered into a map of the dependencyType to a map of a package name to package version. Dependencies are sorted while they are collected, meaning that newer versions of a conflicting dependency typically take precedence over older versions. However, this is not always true with a natural sort order (e.g., 0.9 and 0.10).
versionMergeFunction
is invoked each time a package import version
of a package conflicts with another version of the same package for the
same dependency type. The function accepts the dependency type, the package
name, the previous version that was registered, the new conflicting version,
and is expected to return the version that should be used or can throw in
the case of an incompatible conflict. It is a target-specific concern to
determine if two version are compatible or to find an acceptable compromise
between the two versions.
symbolStream
- Stream of symbols to compute from.versionMergeFunction
- Function that determines which two conflicting versions wins.public java.lang.String getDependencyType()
This value defaults to an empty string if not explicitly set.
public java.lang.String getPackageName()
public java.lang.String getVersion()
public java.util.List<SymbolDependency> getDependencies()
SymbolDependencyContainer
A dependency is a dependency on another package that a Symbol or type requires. It is quite different from a reference since a reference only refers to a symbol; a reference provides no context as to whether or not a dependency is required or the dependency's coordinates.
getDependencies
in interface SymbolDependencyContainer
public SymbolDependency.Builder toBuilder()
ToSmithyBuilder
toBuilder
in interface ToSmithyBuilder<SymbolDependency>
public java.lang.String toString()
toString
in class java.lang.Object
public boolean equals(java.lang.Object o)
public int hashCode()
public int compareTo(SymbolDependency other)
compareTo
in interface java.lang.Comparable<SymbolDependency>
public java.util.Map<java.lang.String,java.lang.Object> getProperties()
public java.util.Optional<java.lang.Object> getProperty(java.lang.String name)
name
- Property to retrieve.public <T> java.util.Optional<T> getProperty(java.lang.String name, java.lang.Class<T> type)
T
- Type of value to expect.name
- Name of the property to get.type
- Type of value to expect.java.lang.IllegalArgumentException
- if the value is not of the given type.public java.lang.Object expectProperty(java.lang.String name)
name
- Property to retrieve.java.lang.IllegalArgumentException
- if the property is not present.public <T> T expectProperty(java.lang.String name, java.lang.Class<T> type)
T
- Type of value to expect.name
- Property to retrieve.type
- Type of value to expect.java.lang.IllegalArgumentException
- if the property is not present.java.lang.IllegalArgumentException
- if the value is not of the given type.