mirror of https://github.com/apache/maven.git
[MNG-8052] New lifecycle for Maven 4 (#1448)
This commit is contained in:
parent
9bc5cc88b4
commit
acec540547
|
@ -21,9 +21,11 @@ package org.apache.maven.api;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.maven.api.annotations.Experimental;
|
||||
import org.apache.maven.api.annotations.Immutable;
|
||||
import org.apache.maven.api.annotations.Nonnull;
|
||||
import org.apache.maven.api.model.Plugin;
|
||||
|
||||
/**
|
||||
|
@ -41,14 +43,20 @@ import org.apache.maven.api.model.Plugin;
|
|||
@Immutable
|
||||
public interface Lifecycle extends ExtensibleEnum {
|
||||
|
||||
// =========================
|
||||
// Maven defined lifecycles
|
||||
// =========================
|
||||
String CLEAN = "clean";
|
||||
|
||||
String DEFAULT = "default";
|
||||
|
||||
String SITE = "site";
|
||||
|
||||
String WRAPPER = "wrapper";
|
||||
|
||||
// ======================
|
||||
// Phase qualifiers
|
||||
// ======================
|
||||
String BEFORE = "before:";
|
||||
String AFTER = "after:";
|
||||
|
||||
/**
|
||||
* Name or identifier of this lifecycle.
|
||||
*
|
||||
|
@ -62,6 +70,18 @@ public interface Lifecycle extends ExtensibleEnum {
|
|||
*/
|
||||
Collection<Phase> phases();
|
||||
|
||||
/**
|
||||
* Stream of phases containing all child phases recursively.
|
||||
*/
|
||||
default Stream<Phase> allPhases() {
|
||||
return phases().stream().flatMap(Phase::allPhases);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collection of aliases.
|
||||
*/
|
||||
Collection<Alias> aliases();
|
||||
|
||||
/**
|
||||
* Pre-ordered list of phases.
|
||||
* If not provided, a default order will be computed.
|
||||
|
@ -72,10 +92,108 @@ public interface Lifecycle extends ExtensibleEnum {
|
|||
|
||||
/**
|
||||
* A phase in the lifecycle.
|
||||
*
|
||||
* A phase is identified by its name. It also contains a list of plugins bound to that phase,
|
||||
* a list of {@link Link links}, and a list of sub-phases. This forms a tree of phases.
|
||||
*/
|
||||
interface Phase {
|
||||
|
||||
// ======================
|
||||
// Maven defined phases
|
||||
// ======================
|
||||
String BUILD = "build";
|
||||
String INITIALIZE = "initialize";
|
||||
String VALIDATE = "validate";
|
||||
String SOURCES = "sources";
|
||||
String RESOURCES = "resources";
|
||||
String COMPILE = "compile";
|
||||
String READY = "ready";
|
||||
String PACKAGE = "package";
|
||||
String VERIFY = "verify";
|
||||
String UNIT_TEST = "unit-test";
|
||||
String TEST_SOURCES = "test-sources";
|
||||
String TEST_RESOURCES = "test-resources";
|
||||
String TEST_COMPILE = "test-compile";
|
||||
String TEST = "test";
|
||||
String INTEGRATION_TEST = "integration-test";
|
||||
String INSTALL = "install";
|
||||
String DEPLOY = "deploy";
|
||||
String CLEAN = "clean";
|
||||
|
||||
@Nonnull
|
||||
String name();
|
||||
|
||||
@Nonnull
|
||||
List<Plugin> plugins();
|
||||
|
||||
@Nonnull
|
||||
Collection<Link> links();
|
||||
|
||||
/**
|
||||
* {@return the list of sub-phases}
|
||||
*/
|
||||
@Nonnull
|
||||
List<Phase> phases();
|
||||
|
||||
@Nonnull
|
||||
Stream<Phase> allPhases();
|
||||
}
|
||||
|
||||
/**
|
||||
* A phase alias, mostly used to support the Maven 3 phases which are mapped
|
||||
* to dynamic phases in Maven 4.
|
||||
*/
|
||||
interface Alias {
|
||||
String v3Phase();
|
||||
|
||||
String v4Phase();
|
||||
}
|
||||
|
||||
/**
|
||||
* A link from a phase to another phase, consisting of a type which can be
|
||||
* {@link Kind#BEFORE} or {@link Kind#AFTER}, and a {@link Pointer} to
|
||||
* another phase.
|
||||
*/
|
||||
interface Link {
|
||||
enum Kind {
|
||||
BEFORE,
|
||||
AFTER
|
||||
}
|
||||
|
||||
Kind kind();
|
||||
|
||||
Pointer pointer();
|
||||
}
|
||||
|
||||
interface Pointer {
|
||||
enum Type {
|
||||
PROJECT,
|
||||
DEPENDENCIES,
|
||||
CHILDREN
|
||||
}
|
||||
|
||||
String phase();
|
||||
|
||||
Type type();
|
||||
}
|
||||
|
||||
interface PhasePointer extends Pointer {
|
||||
default Type type() {
|
||||
return Type.PROJECT;
|
||||
}
|
||||
}
|
||||
|
||||
interface DependenciesPointer extends Pointer {
|
||||
String scope(); // default: all
|
||||
|
||||
default Type type() {
|
||||
return Type.DEPENDENCIES;
|
||||
}
|
||||
}
|
||||
|
||||
interface ChildrenPointer extends Pointer {
|
||||
default Type type() {
|
||||
return Type.CHILDREN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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.maven.api.plugin.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.apache.maven.api.annotations.Experimental;
|
||||
|
||||
/**
|
||||
* Specifies that the mojo should be run after the specific phase.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@Experimental
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Inherited
|
||||
public @interface After {
|
||||
|
||||
/**
|
||||
* Type of pointer.
|
||||
* @see org.apache.maven.api.Lifecycle.Pointer.Type
|
||||
*/
|
||||
enum Type {
|
||||
PROJECT,
|
||||
DEPENDENCIES,
|
||||
CHILDREN
|
||||
}
|
||||
|
||||
/**
|
||||
* The phase name.
|
||||
*/
|
||||
String phase();
|
||||
|
||||
/**
|
||||
* The type of this pointer.
|
||||
*/
|
||||
Type type();
|
||||
|
||||
/**
|
||||
* The scope for dependencies, only if {@code type() == Type.Dependencies}.
|
||||
*/
|
||||
String scope() default "";
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.apache.maven.api.services;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
|
@ -28,4 +29,6 @@ public interface LifecycleRegistry extends ExtensibleEnumRegistry<Lifecycle>, It
|
|||
default Stream<Lifecycle> stream() {
|
||||
return StreamSupport.stream(spliterator(), false);
|
||||
}
|
||||
|
||||
List<String> computePhases(Lifecycle lifecycle);
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ under the License.
|
|||
<phase>generate-sources</phase>
|
||||
<configuration>
|
||||
<velocityBasedir>${project.basedir}/../../src/mdo</velocityBasedir>
|
||||
<version>1.0.0</version>
|
||||
<version>2.0.0</version>
|
||||
<models>
|
||||
<model>src/main/mdo/lifecycle.mdo</model>
|
||||
</models>
|
||||
|
|
|
@ -30,12 +30,12 @@ under the License.
|
|||
<classes>
|
||||
<class rootElement="true" xml.tagName="lifecycles" xsd.compositor="sequence">
|
||||
<name>LifecycleConfiguration</name>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.0+</version>
|
||||
<description>Root element of the {@code lifecycle.xml} file.</description>
|
||||
<fields>
|
||||
<field>
|
||||
<name>lifecycles</name>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.0+</version>
|
||||
<association xml.itemsStyle="flat">
|
||||
<type>Lifecycle</type>
|
||||
<multiplicity>*</multiplicity>
|
||||
|
@ -45,19 +45,19 @@ under the License.
|
|||
</class>
|
||||
<class>
|
||||
<name>Lifecycle</name>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.0+</version>
|
||||
<description>A custom lifecycle mapping definition.</description>
|
||||
<fields>
|
||||
<field>
|
||||
<name>id</name>
|
||||
<required>true</required>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.0+</version>
|
||||
<type>String</type>
|
||||
<description>The ID of this lifecycle, for identification in the mojo descriptor.</description>
|
||||
</field>
|
||||
<field>
|
||||
<name>phases</name>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.0+</version>
|
||||
<description>The phase mappings for this lifecycle.</description>
|
||||
<association>
|
||||
<type>Phase</type>
|
||||
|
@ -68,19 +68,35 @@ under the License.
|
|||
</class>
|
||||
<class>
|
||||
<name>Phase</name>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.0+</version>
|
||||
<description>A phase mapping definition.</description>
|
||||
<fields>
|
||||
<field>
|
||||
<name>id</name>
|
||||
<required>true</required>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.0+</version>
|
||||
<type>String</type>
|
||||
<description>The ID of this phase, e.g., <code>generate-sources</code>.</description>
|
||||
<description>The ID of this phase, e.g., {@code generate-sources}.</description>
|
||||
</field>
|
||||
<field xml.attribute="true">
|
||||
<name>executionPoint</name>
|
||||
<required>false</required>
|
||||
<version>2.0.0+</version>
|
||||
<type>String</type>
|
||||
<defaultValue><![CDATA[]]></defaultValue>
|
||||
<description><![CDATA[If specified, identifies this phase as a dynamic phase to decorate the specified phase id, e.g. {@code after} or {@code before}.]]></description>
|
||||
</field>
|
||||
<field xml.attribute="true">
|
||||
<name>priority</name>
|
||||
<required>false</required>
|
||||
<version>2.0.0+</version>
|
||||
<type>int</type>
|
||||
<defaultValue>0</defaultValue>
|
||||
<description>If specified, identifies a within phase prioritization of executions.</description>
|
||||
</field>
|
||||
<field>
|
||||
<name>executions</name>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.0+</version>
|
||||
<description>The goals to execute within the phase.</description>
|
||||
<association>
|
||||
<type>Execution</type>
|
||||
|
@ -89,26 +105,51 @@ under the License.
|
|||
</field>
|
||||
<field>
|
||||
<name>configuration</name>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.0+</version>
|
||||
<type>DOM</type>
|
||||
<description>Configuration to pass to all goals run in this phase.</description>
|
||||
</field>
|
||||
</fields>
|
||||
<codeSegments>
|
||||
<codeSegment>
|
||||
<version>2.0.0+</version>
|
||||
<code><![CDATA[
|
||||
/**
|
||||
* Get the effective ID of this phase, e.g.,
|
||||
* {@code generate-sources} or {@code after:integration-test[1000]}.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getEffectiveId() {
|
||||
if (executionPoint == null) {
|
||||
if (priority == 0) {
|
||||
return id;
|
||||
}
|
||||
return id + '[' + priority + ']';
|
||||
}
|
||||
if (priority == 0) {
|
||||
return executionPoint + ':' + id;
|
||||
}
|
||||
return executionPoint + ':' + id + '[' + priority + ']';
|
||||
}
|
||||
]]></code>
|
||||
</codeSegment>
|
||||
</codeSegments>
|
||||
</class>
|
||||
<class>
|
||||
<name>Execution</name>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.0+</version>
|
||||
<description>A set of goals to execute.</description>
|
||||
<fields>
|
||||
<field>
|
||||
<name>configuration</name>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.0+</version>
|
||||
<type>DOM</type>
|
||||
<description>Configuration to pass to the goals.</description>
|
||||
</field>
|
||||
<field>
|
||||
<name>goals</name>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.0+</version>
|
||||
<description>The goals to execute.</description>
|
||||
<association>
|
||||
<type>String</type>
|
||||
|
|
|
@ -364,6 +364,11 @@ public class ApiRunner {
|
|||
public Optional<Lifecycle> lookup(String id) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> computePhases(Lifecycle lifecycle) {
|
||||
return List.of();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,11 @@ public class EmptyLifecycleBindingsInjector extends DefaultLifecycleBindingsInje
|
|||
public Optional<Lifecycle> lookup(String id) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> computePhases(Lifecycle lifecycle) {
|
||||
return List.of();
|
||||
}
|
||||
};
|
||||
|
||||
private static final PackagingRegistry emptyPackagingRegistry = new PackagingRegistry() {
|
||||
|
@ -140,6 +145,11 @@ public class EmptyLifecycleBindingsInjector extends DefaultLifecycleBindingsInje
|
|||
protected LifecycleRegistry getDelegate() {
|
||||
return lifecycleRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> computePhases(Lifecycle lifecycle) {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
||||
static class WrapperPackagingRegistry implements PackagingRegistry {
|
||||
|
|
|
@ -24,6 +24,7 @@ import javax.inject.Provider;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
@ -47,8 +48,26 @@ import org.apache.maven.lifecycle.mapping.LifecyclePhase;
|
|||
import org.codehaus.plexus.PlexusContainer;
|
||||
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singleton;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.BUILD;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.COMPILE;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.DEPLOY;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.INITIALIZE;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.INSTALL;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.INTEGRATION_TEST;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.PACKAGE;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.READY;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.RESOURCES;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.SOURCES;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.TEST;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.TEST_COMPILE;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.TEST_RESOURCES;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.TEST_SOURCES;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.UNIT_TEST;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.VALIDATE;
|
||||
import static org.apache.maven.api.Lifecycle.Phase.VERIFY;
|
||||
import static org.apache.maven.internal.impl.Lifecycles.after;
|
||||
import static org.apache.maven.internal.impl.Lifecycles.alias;
|
||||
import static org.apache.maven.internal.impl.Lifecycles.dependencies;
|
||||
import static org.apache.maven.internal.impl.Lifecycles.phase;
|
||||
import static org.apache.maven.internal.impl.Lifecycles.plugin;
|
||||
|
||||
|
@ -59,6 +78,8 @@ import static org.apache.maven.internal.impl.Lifecycles.plugin;
|
|||
@Singleton
|
||||
public class DefaultLifecycleRegistry implements LifecycleRegistry {
|
||||
|
||||
private static final String MAVEN_PLUGINS = "org.apache.maven.plugins:";
|
||||
|
||||
private final List<LifecycleProvider> providers;
|
||||
|
||||
public DefaultLifecycleRegistry() {
|
||||
|
@ -73,7 +94,7 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry {
|
|||
// validate lifecycle
|
||||
for (Lifecycle lifecycle : this) {
|
||||
Set<String> set = new HashSet<>();
|
||||
lifecycle.phases().forEach(phase -> {
|
||||
lifecycle.allPhases().forEach(phase -> {
|
||||
if (!set.add(phase.name())) {
|
||||
throw new IllegalArgumentException(
|
||||
"Found duplicated phase '" + phase.name() + "' in '" + lifecycle.id() + "' lifecycle");
|
||||
|
@ -97,6 +118,57 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry {
|
|||
return stream().filter(lf -> Objects.equals(id, lf.id())).findAny();
|
||||
}
|
||||
|
||||
public List<String> computePhases(Lifecycle lifecycle) {
|
||||
Graph graph = new Graph();
|
||||
lifecycle.phases().forEach(phase -> addPhase(graph, null, null, phase));
|
||||
List<String> allPhases = graph.visitAll();
|
||||
Collections.reverse(allPhases);
|
||||
List<String> computed =
|
||||
allPhases.stream().filter(s -> !s.startsWith("$")).collect(Collectors.toList());
|
||||
List<String> given = lifecycle.orderedPhases().orElse(null);
|
||||
if (given != null) {
|
||||
if (given.size() != computed.size()) {
|
||||
Set<String> s1 =
|
||||
given.stream().filter(s -> !computed.contains(s)).collect(Collectors.toSet());
|
||||
Set<String> s2 =
|
||||
computed.stream().filter(s -> !given.contains(s)).collect(Collectors.toSet());
|
||||
throw new IllegalStateException(
|
||||
"List of phases differ in size: expected " + computed.size() + ", but received " + given.size()
|
||||
+ (s1.isEmpty() ? "" : ", missing " + s1)
|
||||
+ (s2.isEmpty() ? "" : ", unexpected " + s2));
|
||||
}
|
||||
return given;
|
||||
}
|
||||
return computed;
|
||||
}
|
||||
|
||||
private static void addPhase(
|
||||
Graph graph, Graph.Vertex before, Graph.Vertex after, org.apache.maven.api.Lifecycle.Phase phase) {
|
||||
Graph.Vertex ep0 = graph.addVertex("$" + phase.name());
|
||||
Graph.Vertex ep1 = graph.addVertex("$$" + phase.name());
|
||||
Graph.Vertex ep2 = graph.addVertex(phase.name());
|
||||
Graph.Vertex ep3 = graph.addVertex("$$$" + phase.name());
|
||||
graph.addEdge(ep0, ep1);
|
||||
graph.addEdge(ep1, ep2);
|
||||
graph.addEdge(ep2, ep3);
|
||||
if (before != null) {
|
||||
graph.addEdge(before, ep0);
|
||||
}
|
||||
if (after != null) {
|
||||
graph.addEdge(ep3, after);
|
||||
}
|
||||
phase.links().forEach(link -> {
|
||||
if (link.pointer().type() == Lifecycle.Pointer.Type.PROJECT) {
|
||||
if (link.kind() == Lifecycle.Link.Kind.AFTER) {
|
||||
graph.addEdge(graph.addVertex(link.pointer().phase()), ep0);
|
||||
} else {
|
||||
graph.addEdge(ep3, graph.addVertex("$" + link.pointer().phase()));
|
||||
}
|
||||
}
|
||||
});
|
||||
phase.phases().forEach(child -> addPhase(graph, ep1, ep2, child));
|
||||
}
|
||||
|
||||
@Named
|
||||
@Singleton
|
||||
public static class LifecycleWrapperProvider implements LifecycleProvider {
|
||||
|
@ -140,6 +212,17 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry {
|
|||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Phase> phases() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Phase> allPhases() {
|
||||
return Stream.concat(
|
||||
Stream.of(this), phases().stream().flatMap(Lifecycle.Phase::allPhases));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Plugin> plugins() {
|
||||
Map<String, LifecyclePhase> lfPhases = lifecycle.getDefaultLifecyclePhases();
|
||||
|
@ -151,16 +234,26 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry {
|
|||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Link> links() {
|
||||
return List.of();
|
||||
}
|
||||
})
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Alias> aliases() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static class WrappedLifecycle extends org.apache.maven.lifecycle.Lifecycle {
|
||||
WrappedLifecycle(Lifecycle lifecycle) {
|
||||
super(lifecycle);
|
||||
WrappedLifecycle(LifecycleRegistry registry, Lifecycle lifecycle) {
|
||||
super(registry, lifecycle);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,7 +271,7 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry {
|
|||
public org.apache.maven.lifecycle.Lifecycle get() {
|
||||
try {
|
||||
LifecycleRegistry registry = lookup.lookup(LifecycleRegistry.class);
|
||||
return new WrappedLifecycle(registry.require(name));
|
||||
return new WrappedLifecycle(registry, registry.require(name));
|
||||
} catch (ComponentLookupException e) {
|
||||
throw new LookupException(e);
|
||||
}
|
||||
|
@ -187,6 +280,7 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry {
|
|||
|
||||
@Singleton
|
||||
@Named(Lifecycle.CLEAN)
|
||||
@SuppressWarnings("unused")
|
||||
static class CleanLifecycleProvider extends BaseLifecycleProvider {
|
||||
CleanLifecycleProvider() {
|
||||
super(Lifecycle.CLEAN);
|
||||
|
@ -195,6 +289,7 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry {
|
|||
|
||||
@Singleton
|
||||
@Named(Lifecycle.DEFAULT)
|
||||
@SuppressWarnings("unused")
|
||||
static class DefaultLifecycleProvider extends BaseLifecycleProvider {
|
||||
DefaultLifecycleProvider() {
|
||||
super(Lifecycle.DEFAULT);
|
||||
|
@ -203,6 +298,7 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry {
|
|||
|
||||
@Singleton
|
||||
@Named(Lifecycle.SITE)
|
||||
@SuppressWarnings("unused")
|
||||
static class SiteLifecycleProvider extends BaseLifecycleProvider {
|
||||
SiteLifecycleProvider() {
|
||||
super(Lifecycle.SITE);
|
||||
|
@ -211,6 +307,7 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry {
|
|||
|
||||
@Singleton
|
||||
@Named(Lifecycle.WRAPPER)
|
||||
@SuppressWarnings("unused")
|
||||
static class WrapperLifecycleProvider extends BaseLifecycleProvider {
|
||||
WrapperLifecycleProvider() {
|
||||
super(Lifecycle.WRAPPER);
|
||||
|
@ -228,15 +325,16 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry {
|
|||
|
||||
@Override
|
||||
public Collection<Phase> phases() {
|
||||
return asList(
|
||||
phase("pre-clean"),
|
||||
phase(
|
||||
"clean",
|
||||
plugin(
|
||||
"org.apache.maven.plugins:maven-clean-plugin:" + MAVEN_CLEAN_PLUGIN_VERSION
|
||||
+ ":clean",
|
||||
"clean")),
|
||||
phase("post-clean"));
|
||||
return List.of(phase(
|
||||
Phase.CLEAN,
|
||||
plugin(
|
||||
MAVEN_PLUGINS + "maven-clean-plugin:" + MAVEN_CLEAN_PLUGIN_VERSION + ":clean",
|
||||
Phase.CLEAN)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Alias> aliases() {
|
||||
return List.of(alias("pre-clean", BEFORE + Phase.CLEAN), alias("post-clean", AFTER + Phase.CLEAN));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,36 +346,101 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry {
|
|||
|
||||
@Override
|
||||
public Collection<Phase> phases() {
|
||||
return asList(
|
||||
phase("validate"),
|
||||
phase("initialize"),
|
||||
phase("generate-sources"),
|
||||
phase("process-sources"),
|
||||
phase("generate-resources"),
|
||||
phase("process-resources"),
|
||||
phase("compile"),
|
||||
phase("process-classes"),
|
||||
phase("generate-test-sources"),
|
||||
phase("process-test-sources"),
|
||||
phase("generate-test-resources"),
|
||||
phase("process-test-resources"),
|
||||
phase("test-compile"),
|
||||
phase("process-test-classes"),
|
||||
phase("test"),
|
||||
phase("prepare-package"),
|
||||
phase("package"),
|
||||
phase("pre-integration-test"),
|
||||
phase("integration-test"),
|
||||
phase("post-integration-test"),
|
||||
phase("verify"),
|
||||
phase("install"),
|
||||
phase("deploy"));
|
||||
return List.of(phase(
|
||||
"all",
|
||||
phase(INITIALIZE, phase(VALIDATE)),
|
||||
phase(
|
||||
BUILD,
|
||||
after(VALIDATE),
|
||||
phase(SOURCES),
|
||||
phase(RESOURCES),
|
||||
phase(COMPILE, after(SOURCES), dependencies(COMPILE, READY)),
|
||||
phase(READY, after(COMPILE), after(RESOURCES)),
|
||||
phase(PACKAGE, after(READY), dependencies("runtime", PACKAGE))),
|
||||
phase(
|
||||
VERIFY,
|
||||
after(VALIDATE),
|
||||
phase(
|
||||
UNIT_TEST,
|
||||
phase(TEST_SOURCES),
|
||||
phase(TEST_RESOURCES),
|
||||
phase(
|
||||
TEST_COMPILE,
|
||||
after(TEST_SOURCES),
|
||||
after(READY),
|
||||
dependencies("test-only", READY)),
|
||||
phase(
|
||||
TEST,
|
||||
after(TEST_COMPILE),
|
||||
after(TEST_RESOURCES),
|
||||
dependencies("test", READY))),
|
||||
phase(INTEGRATION_TEST)),
|
||||
phase(INSTALL, after(PACKAGE)),
|
||||
phase(DEPLOY, after(PACKAGE))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Alias> aliases() {
|
||||
return List.of(
|
||||
alias("generate-sources", SOURCES),
|
||||
alias("process-sources", AFTER + SOURCES),
|
||||
alias("generate-resources", RESOURCES),
|
||||
alias("process-resources", AFTER + RESOURCES),
|
||||
alias("process-classes", AFTER + COMPILE),
|
||||
alias("generate-test-sources", TEST_SOURCES),
|
||||
alias("process-test-sources", AFTER + TEST_SOURCES),
|
||||
alias("generate-test-resources", TEST_RESOURCES),
|
||||
alias("process-test-resources", AFTER + TEST_RESOURCES),
|
||||
alias("process-test-classes", AFTER + TEST_COMPILE),
|
||||
alias("prepare-package", BEFORE + PACKAGE),
|
||||
alias("pre-integration-test", BEFORE + INTEGRATION_TEST),
|
||||
alias("post-integration-test", AFTER + INTEGRATION_TEST));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<List<String>> orderedPhases() {
|
||||
return Optional.of(Arrays.asList(
|
||||
VALIDATE,
|
||||
INITIALIZE,
|
||||
// "generate-sources",
|
||||
SOURCES,
|
||||
// "process-sources",
|
||||
// "generate-resources",
|
||||
RESOURCES,
|
||||
// "process-resources",
|
||||
COMPILE,
|
||||
// "process-classes",
|
||||
READY,
|
||||
// "generate-test-sources",
|
||||
TEST_SOURCES,
|
||||
// "process-test-sources",
|
||||
// "generate-test-resources",
|
||||
TEST_RESOURCES,
|
||||
// "process-test-resources",
|
||||
TEST_COMPILE,
|
||||
// "process-test-classes",
|
||||
TEST,
|
||||
UNIT_TEST,
|
||||
// "prepare-package",
|
||||
PACKAGE,
|
||||
BUILD,
|
||||
// "pre-integration-test",
|
||||
INTEGRATION_TEST,
|
||||
// "post-integration-test",
|
||||
VERIFY,
|
||||
INSTALL,
|
||||
DEPLOY,
|
||||
"all"));
|
||||
}
|
||||
}
|
||||
|
||||
static class SiteLifecycle implements Lifecycle {
|
||||
|
||||
private static final String MAVEN_SITE_PLUGIN_VERSION = "3.12.1";
|
||||
private static final String MAVEN_SITE_PLUGIN =
|
||||
MAVEN_PLUGINS + "maven-site-plugin:" + MAVEN_SITE_PLUGIN_VERSION + ":";
|
||||
private static final String PHASE_SITE = "site";
|
||||
private static final String PHASE_SITE_DEPLOY = "site-deploy";
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
|
@ -286,26 +449,24 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry {
|
|||
|
||||
@Override
|
||||
public Collection<Phase> phases() {
|
||||
return asList(
|
||||
phase("pre-site"),
|
||||
return List.of(
|
||||
phase(PHASE_SITE, plugin(MAVEN_SITE_PLUGIN + "site", PHASE_SITE)),
|
||||
phase(
|
||||
"site",
|
||||
plugin(
|
||||
"org.apache.maven.plugins:maven-site-plugin:" + MAVEN_SITE_PLUGIN_VERSION + ":site",
|
||||
"site")),
|
||||
phase("post-site"),
|
||||
phase(
|
||||
"site-deploy",
|
||||
plugin(
|
||||
"org.apache.maven.plugins:maven-site-plugin:" + MAVEN_SITE_PLUGIN_VERSION
|
||||
+ ":deploy",
|
||||
"site-deploy")));
|
||||
PHASE_SITE_DEPLOY,
|
||||
after(PHASE_SITE),
|
||||
plugin(MAVEN_SITE_PLUGIN + "deploy", PHASE_SITE_DEPLOY)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Alias> aliases() {
|
||||
return List.of(alias("pre-site", BEFORE + PHASE_SITE), alias("post-site", AFTER + PHASE_SITE));
|
||||
}
|
||||
}
|
||||
|
||||
static class WrapperLifecycle implements Lifecycle {
|
||||
|
||||
private static final String MAVEN_WRAPPER_PLUGIN_VERSION = "3.2.0";
|
||||
private static final String PHASE_WRAPPER = "wrapper";
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
|
@ -314,12 +475,16 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry {
|
|||
|
||||
@Override
|
||||
public Collection<Phase> phases() {
|
||||
return singleton(phase(
|
||||
"wrapper",
|
||||
return List.of(phase(
|
||||
PHASE_WRAPPER,
|
||||
plugin(
|
||||
"org.apache.maven.plugins:maven-wrapper-plugin:" + MAVEN_WRAPPER_PLUGIN_VERSION
|
||||
+ ":wrapper",
|
||||
"wrapper")));
|
||||
MAVEN_PLUGINS + "maven-wrapper-plugin:" + MAVEN_WRAPPER_PLUGIN_VERSION + ":wrapper",
|
||||
PHASE_WRAPPER)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Alias> aliases() {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,21 +18,52 @@
|
|||
*/
|
||||
package org.apache.maven.internal.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.maven.api.Lifecycle;
|
||||
import org.apache.maven.api.model.Plugin;
|
||||
import org.apache.maven.api.model.PluginExecution;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
public class Lifecycles {
|
||||
|
||||
static Lifecycle.Phase phase(String name) {
|
||||
return new DefaultPhase(name, Collections.emptyList(), Collections.emptyList());
|
||||
return new DefaultPhase(name, Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
|
||||
}
|
||||
|
||||
static Lifecycle.Phase phase(String name, Lifecycle.Phase... phases) {
|
||||
return new DefaultPhase(name, Collections.emptyList(), Collections.emptyList(), asList(phases));
|
||||
}
|
||||
|
||||
static Lifecycle.Phase phase(String name, Lifecycle.Link link, Lifecycle.Phase... phases) {
|
||||
return new DefaultPhase(name, Collections.emptyList(), Collections.singletonList(link), asList(phases));
|
||||
}
|
||||
|
||||
static Lifecycle.Phase phase(String name, Plugin plugin) {
|
||||
return new DefaultPhase(name, Collections.singletonList(plugin), Collections.emptyList());
|
||||
return new DefaultPhase(
|
||||
name, Collections.singletonList(plugin), Collections.emptyList(), Collections.emptyList());
|
||||
}
|
||||
|
||||
static Lifecycle.Phase phase(String name, Lifecycle.Link link, Plugin plugin) {
|
||||
return new DefaultPhase(
|
||||
name, Collections.singletonList(plugin), Collections.singletonList(link), Collections.emptyList());
|
||||
}
|
||||
|
||||
static Lifecycle.Phase phase(String name, Lifecycle.Link link1, Lifecycle.Link link2, Lifecycle.Phase... phases) {
|
||||
return new DefaultPhase(name, Collections.emptyList(), asList(link1, link2), asList(phases));
|
||||
}
|
||||
|
||||
static Lifecycle.Phase phase(
|
||||
String name, Lifecycle.Link link1, Lifecycle.Link link2, Lifecycle.Link link3, Lifecycle.Phase... phases) {
|
||||
return new DefaultPhase(name, Collections.emptyList(), asList(link1, link2, link3), asList(phases));
|
||||
}
|
||||
|
||||
static Lifecycle.Phase phase(String name, Collection<Lifecycle.Link> links, Lifecycle.Phase... phases) {
|
||||
return new DefaultPhase(name, Collections.emptyList(), links, asList(phases));
|
||||
}
|
||||
|
||||
static Plugin plugin(String coords, String phase) {
|
||||
|
@ -49,14 +80,66 @@ public class Lifecycles {
|
|||
.build();
|
||||
}
|
||||
|
||||
/** Indicates the phase is after the phases given in arguments */
|
||||
static Lifecycle.Link after(String b) {
|
||||
return new Lifecycle.Link() {
|
||||
@Override
|
||||
public Kind kind() {
|
||||
return Kind.AFTER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lifecycle.Pointer pointer() {
|
||||
return new Lifecycle.PhasePointer() {
|
||||
@Override
|
||||
public String phase() {
|
||||
return b;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** Indicates the phase is after the phases for the dependencies in the given scope */
|
||||
static Lifecycle.Link dependencies(String scope, String phase) {
|
||||
return new Lifecycle.Link() {
|
||||
@Override
|
||||
public Kind kind() {
|
||||
return Kind.AFTER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lifecycle.Pointer pointer() {
|
||||
return new Lifecycle.DependenciesPointer() {
|
||||
@Override
|
||||
public String phase() {
|
||||
return phase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String scope() {
|
||||
return scope;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static Lifecycle.Alias alias(String v3Phase, String v4Phase) {
|
||||
return new DefaultAlias(v3Phase, v4Phase);
|
||||
}
|
||||
|
||||
static class DefaultPhase implements Lifecycle.Phase {
|
||||
private final String name;
|
||||
private final List<Plugin> plugins;
|
||||
private final Collection<Lifecycle.Link> links;
|
||||
private final List<Lifecycle.Phase> phases;
|
||||
|
||||
DefaultPhase(String name, List<Plugin> plugins, List<Lifecycle.Phase> phases) {
|
||||
DefaultPhase(
|
||||
String name, List<Plugin> plugins, Collection<Lifecycle.Link> links, List<Lifecycle.Phase> phases) {
|
||||
this.name = name;
|
||||
this.plugins = plugins;
|
||||
this.links = links;
|
||||
this.phases = phases;
|
||||
}
|
||||
|
||||
|
@ -69,5 +152,40 @@ public class Lifecycles {
|
|||
public List<Plugin> plugins() {
|
||||
return plugins;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Lifecycle.Link> links() {
|
||||
return links;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Lifecycle.Phase> phases() {
|
||||
return phases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Lifecycle.Phase> allPhases() {
|
||||
return Stream.concat(Stream.of(this), phases().stream().flatMap(Lifecycle.Phase::allPhases));
|
||||
}
|
||||
}
|
||||
|
||||
static class DefaultAlias implements Lifecycle.Alias {
|
||||
private final String v3Phase;
|
||||
private final String v4Phase;
|
||||
|
||||
DefaultAlias(String v3Phase, String v4Phase) {
|
||||
this.v3Phase = v3Phase;
|
||||
this.v4Phase = v4Phase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String v3Phase() {
|
||||
return v3Phase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String v4Phase() {
|
||||
return v4Phase;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,8 @@ public class DefaultLifecycles {
|
|||
|
||||
private Map<String, Lifecycle> customLifecycles;
|
||||
|
||||
private boolean lifecyclesPrinted;
|
||||
|
||||
public DefaultLifecycles() {
|
||||
this.lookup = null;
|
||||
this.registry = null;
|
||||
|
@ -94,20 +96,23 @@ public class DefaultLifecycles {
|
|||
* @return A map of lifecycles, indexed on id
|
||||
*/
|
||||
public Map<String, Lifecycle> getPhaseToLifecycleMap() {
|
||||
if (logger.isDebugEnabled() && !lifecyclesPrinted) {
|
||||
for (Lifecycle lifecycle : getLifeCycles()) {
|
||||
logger.debug("Lifecycle {}", lifecycle);
|
||||
}
|
||||
lifecyclesPrinted = true;
|
||||
}
|
||||
|
||||
// If people are going to make their own lifecycles then we need to tell people how to namespace them correctly
|
||||
// so that they don't interfere with internally defined lifecycles.
|
||||
|
||||
Map<String, Lifecycle> phaseToLifecycleMap = new HashMap<>();
|
||||
|
||||
for (Lifecycle lifecycle : getLifeCycles()) {
|
||||
logger.debug("Lifecycle {}", lifecycle);
|
||||
|
||||
for (String phase : lifecycle.getPhases()) {
|
||||
// The first definition wins.
|
||||
if (!phaseToLifecycleMap.containsKey(phase)) {
|
||||
phaseToLifecycleMap.put(phase, lifecycle);
|
||||
} else if (logger.isWarnEnabled()) {
|
||||
Lifecycle original = phaseToLifecycleMap.get(phase);
|
||||
Lifecycle original = phaseToLifecycleMap.put(phase, lifecycle);
|
||||
if (original != null && logger.isWarnEnabled()) {
|
||||
logger.warn(
|
||||
"Duplicated lifecycle phase {}. Defined in {} but also in {}",
|
||||
phase,
|
||||
|
@ -115,6 +120,19 @@ public class DefaultLifecycles {
|
|||
lifecycle.getId());
|
||||
}
|
||||
}
|
||||
if (lifecycle.getDelegate() != null) {
|
||||
for (org.apache.maven.api.Lifecycle.Alias alias :
|
||||
lifecycle.getDelegate().aliases()) {
|
||||
Lifecycle original = phaseToLifecycleMap.put(alias.v3Phase(), lifecycle);
|
||||
if (original != null && logger.isWarnEnabled()) {
|
||||
logger.warn(
|
||||
"Duplicated lifecycle phase {}. Defined in {} but also in {}",
|
||||
alias.v3Phase(),
|
||||
original.getId(),
|
||||
lifecycle.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return phaseToLifecycleMap;
|
||||
|
@ -156,7 +174,7 @@ public class DefaultLifecycles {
|
|||
// Lifecycles cannot be cached as extensions might add custom lifecycles later in the execution.
|
||||
try {
|
||||
return registry != null
|
||||
? registry.stream().collect(Collectors.toMap(lf -> lf.id(), lf -> new Lifecycle(lf)))
|
||||
? registry.stream().collect(Collectors.toMap(lf -> lf.id(), lf -> new Lifecycle(registry, lf)))
|
||||
: Map.of();
|
||||
} catch (LookupException e) {
|
||||
throw new IllegalStateException("Unable to lookup lifecycles from the plexus container", e);
|
||||
|
|
|
@ -23,9 +23,13 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.maven.lifecycle.mapping.LifecyclePhase;
|
||||
|
||||
import static org.apache.maven.api.Lifecycle.AFTER;
|
||||
import static org.apache.maven.api.Lifecycle.BEFORE;
|
||||
|
||||
/**
|
||||
* Lifecycle definition, with eventual plugin bindings (when they are not packaging-specific).
|
||||
*/
|
||||
|
@ -38,11 +42,12 @@ public class Lifecycle {
|
|||
this.defaultPhases = defaultPhases;
|
||||
}
|
||||
|
||||
public Lifecycle(org.apache.maven.api.Lifecycle lifecycle) {
|
||||
public Lifecycle(
|
||||
org.apache.maven.api.services.LifecycleRegistry registry, org.apache.maven.api.Lifecycle lifecycle) {
|
||||
this.lifecycle = lifecycle;
|
||||
this.id = lifecycle.id();
|
||||
this.phases = lifecycle.phases().stream()
|
||||
.map(org.apache.maven.api.Lifecycle.Phase::name)
|
||||
this.phases = registry.computePhases(lifecycle).stream()
|
||||
.flatMap(p -> Stream.of(BEFORE + p, p, AFTER + p))
|
||||
.toList();
|
||||
this.defaultPhases = getDefaultPhases(lifecycle);
|
||||
}
|
||||
|
@ -71,13 +76,17 @@ public class Lifecycle {
|
|||
return id;
|
||||
}
|
||||
|
||||
public org.apache.maven.api.Lifecycle getDelegate() {
|
||||
return lifecycle;
|
||||
}
|
||||
|
||||
public List<String> getPhases() {
|
||||
return phases;
|
||||
}
|
||||
|
||||
static Map<String, LifecyclePhase> getDefaultPhases(org.apache.maven.api.Lifecycle lifecycle) {
|
||||
Map<String, List<String>> goals = new HashMap<>();
|
||||
lifecycle.phases().forEach(phase -> phase.plugins()
|
||||
lifecycle.allPhases().forEach(phase -> phase.plugins()
|
||||
.forEach(plugin -> plugin.getExecutions().forEach(exec -> exec.getGoals()
|
||||
.forEach(goal -> goals.computeIfAbsent(phase.name(), n -> new ArrayList<>())
|
||||
.add(plugin.getGroupId() + ":" + plugin.getArtifactId() + ":" + plugin.getVersion()
|
||||
|
@ -97,6 +106,10 @@ public class Lifecycle {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return id + " -> " + phases;
|
||||
return id + " -> "
|
||||
+ lifecycle
|
||||
.allPhases()
|
||||
.map(org.apache.maven.api.Lifecycle.Phase::name)
|
||||
.collect(Collectors.joining(", ", "[", "]"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -475,7 +475,14 @@ public class DefaultLifecycleExecutionPlanCalculator implements LifecycleExecuti
|
|||
}
|
||||
|
||||
for (Phase phase : lifecycleOverlay.getPhases()) {
|
||||
List<MojoExecution> forkedExecutions = lifecycleMappings.get(phase.getId());
|
||||
String phaseId = defaultLifecycles.getLifeCycles().stream()
|
||||
.flatMap(l -> l.getDelegate().aliases().stream())
|
||||
.filter(a -> phase.getId().equals(a.v3Phase()))
|
||||
.findFirst()
|
||||
.map(a -> a.v4Phase())
|
||||
.orElse(phase.getId());
|
||||
|
||||
List<MojoExecution> forkedExecutions = lifecycleMappings.get(phaseId);
|
||||
|
||||
if (forkedExecutions != null) {
|
||||
for (Execution execution : phase.getExecutions()) {
|
||||
|
|
|
@ -23,10 +23,12 @@ import javax.inject.Named;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.maven.execution.MavenSession;
|
||||
import org.apache.maven.lifecycle.Lifecycle;
|
||||
|
@ -70,10 +72,19 @@ public class DefaultLifecycleMappingDelegate implements LifecycleMappingDelegate
|
|||
* is interested in, i.e. all phases up to and including the specified phase.
|
||||
*/
|
||||
|
||||
Map<String, Map<Integer, List<MojoExecution>>> mappings = new LinkedHashMap<>();
|
||||
Map<String, Map<PhaseId, List<MojoExecution>>> mappings =
|
||||
new TreeMap<>(new PhaseComparator(lifecycle.getPhases()));
|
||||
|
||||
Map<String, String> aliases = lifecycle.getDelegate().aliases().stream()
|
||||
.collect(Collectors.toMap(a -> a.v3Phase(), a -> a.v4Phase()));
|
||||
|
||||
if (aliases.containsKey(lifecyclePhase)) {
|
||||
lifecyclePhase = PhaseId.of(aliases.get(lifecyclePhase)).phase();
|
||||
}
|
||||
|
||||
for (String phase : lifecycle.getPhases()) {
|
||||
Map<Integer, List<MojoExecution>> phaseBindings = new TreeMap<>();
|
||||
Map<PhaseId, List<MojoExecution>> phaseBindings =
|
||||
new TreeMap<>(Comparator.comparing(PhaseId::toString, new PhaseComparator(lifecycle.getPhases())));
|
||||
|
||||
mappings.put(phase, phaseBindings);
|
||||
|
||||
|
@ -93,13 +104,21 @@ public class DefaultLifecycleMappingDelegate implements LifecycleMappingDelegate
|
|||
for (PluginExecution execution : plugin.getExecutions()) {
|
||||
// if the phase is specified then I don't have to go fetch the plugin yet and pull it down
|
||||
// to examine the phase it is associated to.
|
||||
if (execution.getPhase() != null) {
|
||||
Map<Integer, List<MojoExecution>> phaseBindings = mappings.get(execution.getPhase());
|
||||
String phase = execution.getPhase();
|
||||
if (aliases.containsKey(phase)) {
|
||||
phase = aliases.get(phase);
|
||||
}
|
||||
if (phase != null) {
|
||||
Map<PhaseId, List<MojoExecution>> phaseBindings = getPhaseBindings(mappings, phase);
|
||||
if (phaseBindings != null) {
|
||||
for (String goal : execution.getGoals()) {
|
||||
MojoExecution mojoExecution = new MojoExecution(plugin, goal, execution.getId());
|
||||
mojoExecution.setLifecyclePhase(execution.getPhase());
|
||||
addMojoExecution(phaseBindings, mojoExecution, execution.getPriority());
|
||||
mojoExecution.setLifecyclePhase(phase);
|
||||
PhaseId phaseId = PhaseId.of(phase);
|
||||
if (phaseId.priority() == 0) {
|
||||
phaseId = PhaseId.of(phase + "[" + execution.getPriority() + "]");
|
||||
}
|
||||
addMojoExecution(phaseBindings, mojoExecution, phaseId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,11 +128,16 @@ public class DefaultLifecycleMappingDelegate implements LifecycleMappingDelegate
|
|||
MojoDescriptor mojoDescriptor = pluginManager.getMojoDescriptor(
|
||||
plugin, goal, project.getRemotePluginRepositories(), session.getRepositorySession());
|
||||
|
||||
Map<Integer, List<MojoExecution>> phaseBindings = mappings.get(mojoDescriptor.getPhase());
|
||||
phase = mojoDescriptor.getPhase();
|
||||
if (aliases.containsKey(phase)) {
|
||||
phase = aliases.get(phase);
|
||||
}
|
||||
Map<PhaseId, List<MojoExecution>> phaseBindings = getPhaseBindings(mappings, phase);
|
||||
if (phaseBindings != null) {
|
||||
MojoExecution mojoExecution = new MojoExecution(mojoDescriptor, execution.getId());
|
||||
mojoExecution.setLifecyclePhase(mojoDescriptor.getPhase());
|
||||
addMojoExecution(phaseBindings, mojoExecution, execution.getPriority());
|
||||
mojoExecution.setLifecyclePhase(phase);
|
||||
PhaseId phaseId = PhaseId.of(phase + "[" + execution.getPriority() + "]");
|
||||
addMojoExecution(phaseBindings, mojoExecution, phaseId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +146,7 @@ public class DefaultLifecycleMappingDelegate implements LifecycleMappingDelegate
|
|||
|
||||
Map<String, List<MojoExecution>> lifecycleMappings = new LinkedHashMap<>();
|
||||
|
||||
for (Map.Entry<String, Map<Integer, List<MojoExecution>>> entry : mappings.entrySet()) {
|
||||
for (Map.Entry<String, Map<PhaseId, List<MojoExecution>>> entry : mappings.entrySet()) {
|
||||
List<MojoExecution> mojoExecutions = new ArrayList<>();
|
||||
|
||||
for (List<MojoExecution> executions : entry.getValue().values()) {
|
||||
|
@ -135,9 +159,18 @@ public class DefaultLifecycleMappingDelegate implements LifecycleMappingDelegate
|
|||
return lifecycleMappings;
|
||||
}
|
||||
|
||||
private Map<PhaseId, List<MojoExecution>> getPhaseBindings(
|
||||
Map<String, Map<PhaseId, List<MojoExecution>>> mappings, String phase) {
|
||||
if (phase != null) {
|
||||
PhaseId id = PhaseId.of(phase);
|
||||
return mappings.get(id.phase());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void addMojoExecution(
|
||||
Map<Integer, List<MojoExecution>> phaseBindings, MojoExecution mojoExecution, int priority) {
|
||||
List<MojoExecution> mojoExecutions = phaseBindings.computeIfAbsent(priority, k -> new ArrayList<>());
|
||||
Map<PhaseId, List<MojoExecution>> phaseBindings, MojoExecution mojoExecution, PhaseId phaseId) {
|
||||
List<MojoExecution> mojoExecutions = phaseBindings.computeIfAbsent(phaseId, k -> new ArrayList<>());
|
||||
|
||||
mojoExecutions.add(mojoExecution);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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.maven.lifecycle.internal;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Compares phases within the context of a specific lifecycle with secondary sorting based on the {@link PhaseId}.
|
||||
*/
|
||||
public class PhaseComparator implements Comparator<String> {
|
||||
/**
|
||||
* The lifecycle phase ordering.
|
||||
*/
|
||||
private final List<String> lifecyclePhases;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param lifecyclePhases the lifecycle phase ordering.
|
||||
*/
|
||||
public PhaseComparator(List<String> lifecyclePhases) {
|
||||
this.lifecyclePhases = lifecyclePhases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
PhaseId p1 = PhaseId.of(o1);
|
||||
PhaseId p2 = PhaseId.of(o2);
|
||||
int i1 = lifecyclePhases.indexOf(p1.phase());
|
||||
int i2 = lifecyclePhases.indexOf(p2.phase());
|
||||
if (i1 == -1 && i2 == -1) {
|
||||
// unknown phases, leave in existing order
|
||||
return 0;
|
||||
}
|
||||
if (i1 == -1) {
|
||||
// second one is known, so it comes first
|
||||
return 1;
|
||||
}
|
||||
if (i2 == -1) {
|
||||
// first one is known, so it comes first
|
||||
return -1;
|
||||
}
|
||||
int rv = Integer.compare(i1, i2);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
// same phase, now compare execution points
|
||||
i1 = p1.executionPoint().ordinal();
|
||||
i2 = p2.executionPoint().ordinal();
|
||||
rv = Integer.compare(i1, i2);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
// same execution point, now compare priorities
|
||||
return Integer.compare(p1.priority(), p2.priority());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.maven.lifecycle.internal;
|
||||
|
||||
/**
|
||||
* Represents where a dynamic phase should be executed within a static phase.
|
||||
*/
|
||||
public enum PhaseExecutionPoint {
|
||||
/**
|
||||
* Execution must occur before any executions of the phase proper. Failure of any {@code #BEFORE} dynamic phase
|
||||
* execution will prevent the {@link #AT} phase but will not prevent any {@link #AFTER} dynamic phases.
|
||||
*/
|
||||
BEFORE("before:"),
|
||||
/**
|
||||
* Execution is the execution of the phase proper. Failure of any {@code #AT} dynamic phase execution will fail
|
||||
* the phase. Any {@link #AFTER} phases will still be executed.
|
||||
*/
|
||||
AT(""),
|
||||
/**
|
||||
* Guaranteed execution dynamic phases on completion of the static phase. All {@code #AFTER} dynamic phases will
|
||||
* be executed provided at least one {@link #BEFORE} or {@link #AT} dynamic phase has started execution.
|
||||
*/
|
||||
AFTER("after:");
|
||||
|
||||
private final String prefix;
|
||||
|
||||
PhaseExecutionPoint(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public String prefix() {
|
||||
return prefix;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* 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.maven.lifecycle.internal;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Represents a parsed phase identifier.
|
||||
*/
|
||||
public class PhaseId {
|
||||
/**
|
||||
* Interned {@link PhaseId} instances.
|
||||
*/
|
||||
private static final Map<String, PhaseId> INSTANCES = new WeakHashMap<>();
|
||||
|
||||
/**
|
||||
* The execution point of this {@link PhaseId}.
|
||||
*/
|
||||
private final PhaseExecutionPoint executionPoint;
|
||||
|
||||
/**
|
||||
* The static phase that this dynamic phase belongs to.
|
||||
*/
|
||||
private final String phase;
|
||||
|
||||
/**
|
||||
* The priority of this dynamic phase within the static phase.
|
||||
*/
|
||||
private final int priority;
|
||||
|
||||
/**
|
||||
* Parses the phase identifier.
|
||||
*
|
||||
* @param phase the phase identifier.
|
||||
* @return the {@link PhaseId}.
|
||||
*/
|
||||
public static synchronized PhaseId of(String phase) {
|
||||
return INSTANCES.computeIfAbsent(phase, PhaseId::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param phase the phase identifier string.
|
||||
*/
|
||||
private PhaseId(String phase) {
|
||||
int phaseStart;
|
||||
if (phase.startsWith(PhaseExecutionPoint.BEFORE.prefix())) {
|
||||
executionPoint = PhaseExecutionPoint.BEFORE;
|
||||
phaseStart = PhaseExecutionPoint.BEFORE.prefix().length();
|
||||
} else if (phase.startsWith(PhaseExecutionPoint.AFTER.prefix())) {
|
||||
executionPoint = PhaseExecutionPoint.AFTER;
|
||||
phaseStart = PhaseExecutionPoint.AFTER.prefix().length();
|
||||
} else {
|
||||
executionPoint = PhaseExecutionPoint.AT;
|
||||
phaseStart = 0;
|
||||
}
|
||||
int phaseEnd = phase.indexOf('[');
|
||||
if (phaseEnd == -1) {
|
||||
priority = 0;
|
||||
this.phase = phase.substring(phaseStart);
|
||||
} else {
|
||||
int priorityEnd = phase.lastIndexOf(']');
|
||||
boolean hasPriority;
|
||||
int priority;
|
||||
if (priorityEnd < phaseEnd + 1) {
|
||||
priority = 0;
|
||||
hasPriority = false;
|
||||
} else {
|
||||
try {
|
||||
priority = Integer.parseInt(phase.substring(phaseEnd + 1, priorityEnd));
|
||||
hasPriority = true;
|
||||
} catch (NumberFormatException e) {
|
||||
// priority must be an integer
|
||||
priority = 0;
|
||||
hasPriority = false;
|
||||
}
|
||||
}
|
||||
if (hasPriority) {
|
||||
this.phase = phase.substring(phaseStart, phaseEnd);
|
||||
this.priority = priority;
|
||||
} else {
|
||||
this.phase = phase.substring(phaseStart);
|
||||
this.priority = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
} else if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
} else {
|
||||
PhaseId phaseId = (PhaseId) o;
|
||||
return Objects.equals(executionPoint(), phaseId.executionPoint())
|
||||
&& Objects.equals(phase(), phaseId.phase())
|
||||
&& Objects.equals(priority(), phaseId.priority());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(executionPoint(), phase(), priority());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return executionPoint().prefix() + phase() + (priority() != 0 ? "[" + priority() + ']' : "");
|
||||
}
|
||||
|
||||
public PhaseExecutionPoint executionPoint() {
|
||||
return executionPoint;
|
||||
}
|
||||
|
||||
public String phase() {
|
||||
return phase;
|
||||
}
|
||||
|
||||
public int priority() {
|
||||
return priority;
|
||||
}
|
||||
}
|
|
@ -38,11 +38,12 @@ public class PhaseRecorder {
|
|||
String lifecyclePhase = mojoExecution.getLifecyclePhase();
|
||||
|
||||
if (lifecyclePhase != null) {
|
||||
PhaseId phaseId = PhaseId.of(lifecyclePhase);
|
||||
if (lastLifecyclePhase == null) {
|
||||
lastLifecyclePhase = lifecyclePhase;
|
||||
} else if (!lifecyclePhase.equals(lastLifecyclePhase)) {
|
||||
lastLifecyclePhase = phaseId.phase();
|
||||
} else if (!phaseId.phase().equals(lastLifecyclePhase)) {
|
||||
project.addLifecyclePhase(lastLifecyclePhase);
|
||||
lastLifecyclePhase = lifecyclePhase;
|
||||
lastLifecyclePhase = phaseId.phase();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,6 +57,6 @@ public class PhaseRecorder {
|
|||
if (lifecyclePhase == null) {
|
||||
return lastLifecyclePhase != null;
|
||||
}
|
||||
return !lifecyclePhase.equals(lastLifecyclePhase);
|
||||
return !PhaseId.of(lifecyclePhase).phase().equals(lastLifecyclePhase);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ class DefaultLifecyclesTest {
|
|||
void testDefaultLifecycle() {
|
||||
final Lifecycle lifecycle = getLifeCycleById("default");
|
||||
assertThat(lifecycle.getId(), is("default"));
|
||||
assertThat(lifecycle.getPhases(), hasSize(23));
|
||||
assertThat(lifecycle.getPhases(), hasSize(54));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -73,14 +73,14 @@ class DefaultLifecyclesTest {
|
|||
void testSiteLifecycle() {
|
||||
final Lifecycle lifecycle = getLifeCycleById("site");
|
||||
assertThat(lifecycle.getId(), is("site"));
|
||||
assertThat(lifecycle.getPhases(), hasSize(4));
|
||||
assertThat(lifecycle.getPhases(), hasSize(6));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWrapperLifecycle() {
|
||||
final Lifecycle lifecycle = getLifeCycleById("wrapper");
|
||||
assertThat(lifecycle.getId(), is("wrapper"));
|
||||
assertThat(lifecycle.getPhases(), hasSize(1));
|
||||
assertThat(lifecycle.getPhases(), hasSize(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -152,6 +152,7 @@ class LifecycleExecutorTest extends AbstractCoreMavenComponentTestCase {
|
|||
}
|
||||
|
||||
// We need to take in multiple lifecycles
|
||||
@Test
|
||||
public void testCalculationOfBuildPlanTasksOfTheCleanLifecycleAndTheInstallLifecycle() throws Exception {
|
||||
File pom = getProject("project-with-additional-lifecycle-elements");
|
||||
MavenSession session = createMavenSession(pom);
|
||||
|
@ -195,6 +196,7 @@ class LifecycleExecutorTest extends AbstractCoreMavenComponentTestCase {
|
|||
}
|
||||
|
||||
// We need to take in multiple lifecycles
|
||||
@Test
|
||||
public void testCalculationOfBuildPlanWithMultipleExecutionsOfModello() throws Exception {
|
||||
File pom = getProject("project-with-multiple-executions");
|
||||
MavenSession session = createMavenSession(pom);
|
||||
|
|
|
@ -61,6 +61,11 @@ public class EmptyLifecycleBindingsInjector extends DefaultLifecycleBindingsInje
|
|||
public Optional<Lifecycle> lookup(String id) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> computePhases(Lifecycle lifecycle) {
|
||||
return List.of();
|
||||
}
|
||||
};
|
||||
|
||||
private static final PackagingRegistry emptyPackagingRegistry = new PackagingRegistry() {
|
||||
|
@ -139,6 +144,11 @@ public class EmptyLifecycleBindingsInjector extends DefaultLifecycleBindingsInje
|
|||
protected LifecycleRegistry getDelegate() {
|
||||
return lifecycleRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> computePhases(Lifecycle lifecycle) {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
||||
static class WrapperPackagingRegistry implements PackagingRegistry {
|
||||
|
|
|
@ -117,7 +117,7 @@ under the License.
|
|||
<models>
|
||||
<model>../api/maven-api-plugin/src/main/mdo/lifecycle.mdo</model>
|
||||
</models>
|
||||
<version>1.0.0</version>
|
||||
<version>2.0.0</version>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
|
|
|
@ -551,6 +551,9 @@ public class ${className} {
|
|||
#foreach ( $field in $allFields )
|
||||
#if ( $Helper.xmlFieldMetadata( $field ).attribute )
|
||||
#set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName )
|
||||
#if ( ! $fieldTagName )
|
||||
#set ( $fieldTagName = $field.name )
|
||||
#end
|
||||
#set ( $fieldCapName = $Helper.capitalise( $field.name ) )
|
||||
} else if ("$fieldTagName".equals(name)) {
|
||||
#if ( $locationTracking )
|
||||
|
@ -562,6 +565,8 @@ public class ${className} {
|
|||
${classLcapName}.${field.name}(interpolatedTrimmed(value, "$fieldTagName"));
|
||||
#elseif ( $field.type == "boolean" || $field.type == "Boolean" )
|
||||
${classLcapName}.${field.name}(getBooleanValue(interpolatedTrimmed(value, "$fieldTagName"), "$fieldTagName", parser, ${field.defaultValue}));
|
||||
#elseif ( $field.type == "int" || $field.type == "Integer" )
|
||||
${classLcapName}.${field.name}(getIntegerValue(interpolatedTrimmed(value, "$fieldTagName"), "$fieldTagName", parser, strict, ${field.defaultValue}));
|
||||
#else
|
||||
// TODO: type=${field.type} to=${field.to} multiplicity=${field.multiplicity}
|
||||
#end
|
||||
|
|
|
@ -227,6 +227,9 @@ public class ${className} {
|
|||
#foreach ( $field in $allFields )
|
||||
#if ( $Helper.xmlFieldMetadata( $field ).attribute && ! $Helper.xmlFieldMetadata( $field ).format )
|
||||
#set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName )
|
||||
#if ( ! $fieldTagName )
|
||||
#set ( $fieldTagName = $field.name )
|
||||
#end
|
||||
#set ( $fieldCapName = $Helper.capitalise( $field.name ) )
|
||||
#if ( $field.type == "String" )
|
||||
writeAttr("$fieldTagName", ${classLcapName}.get${fieldCapName}(), serializer);
|
||||
|
@ -237,6 +240,8 @@ public class ${className} {
|
|||
#else
|
||||
writeAttr("$fieldTagName", ${classLcapName}.is${fieldCapName}() ? "true" : null, serializer);
|
||||
#end
|
||||
#elseif ( $field.type == "int" || $field.type == "Integer" )
|
||||
writeAttr("$fieldTagName", Integer.toString(${classLcapName}.get${fieldCapName}()), serializer);
|
||||
#else
|
||||
// TODO: type=${field.type} to=${field.to} multiplicity=${field.multiplicity}
|
||||
#end
|
||||
|
|
|
@ -152,6 +152,9 @@ public class ${className} {
|
|||
#foreach ( $field in $allFields )
|
||||
#if ( $Helper.xmlFieldMetadata( $field ).attribute )
|
||||
#set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName )
|
||||
#if ( ! $fieldTagName )
|
||||
#set ( $fieldTagName = $field.name )
|
||||
#end
|
||||
#set ( $fieldCapName = $Helper.capitalise( $field.name ) )
|
||||
#if ( $field.type == "String" )
|
||||
writeAttr("$fieldTagName", ${classLcapName}.get${fieldCapName}(), serializer);
|
||||
|
@ -162,6 +165,8 @@ public class ${className} {
|
|||
#else
|
||||
writeAttr("$fieldTagName", ${classLcapName}.is${fieldCapName}() ? "true" : null, serializer);
|
||||
#end
|
||||
#elseif ( $field.type == "int" || $field.type == "Integer" )
|
||||
writeAttr("$fieldTagName", Integer.toString(${classLcapName}.get${fieldCapName}()), serializer);
|
||||
#else
|
||||
// TODO: type=${field.type} to=${field.to} multiplicity=${field.multiplicity}
|
||||
#end
|
||||
|
|
Loading…
Reference in New Issue