Custom type converter for Mojo configuration?

后端 未结 3 885
刺人心
刺人心 2021-01-23 16:04

I need to use custom type, e.g., LunarDate, in my Mojo object:

class MyMojo extends AbstractMojo {

    /** @parameter */
    LunarDate lunarDate;

         


        
相关标签:
3条回答
  • 2021-01-23 16:26

    For newer Maven (tested with Maven 3.3.1) you can now subclass BasicComponentConfigurator to access the DefaultConverterLookup as a member variable:

    @Component(role = ComponentConfigurator.class, hint = "basic")
    public class ExtendedComponentRegistrator 
            extends BasicComponentConfigurator  
            implements Initializable {
    
        @Override
        public void initialize() throws InitializationException {
            converterLookup.registerConverter(new MyCustomConverter());
        }
    }
    

    Then in the pom.xml enable the generation of plexus meta data:

    <plugin>
      <groupId>org.codehaus.plexus</groupId>
      <artifactId>plexus-component-metadata</artifactId>
      <executions>
        <execution>
          <goals>
            <goal>generate-metadata</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    
    0 讨论(0)
  • 2021-01-23 16:34

    I was able to solve this by defining a ConfigurationConverter (my target type is a AnyLicenseInfo):

    @NoArgsConstructor @ToString
    public class LicenseConverter extends AbstractBasicConverter {
        private static final Class<?> TYPE = AnyLicenseInfo.class;
    
        @Override
        public boolean canConvert(Class<?> type) { return type.equals(TYPE); }
    
        @Override
        public Object fromString(String string) throws ComponentConfigurationException {
            Object object = null;
    
            try {
                object =
                    TYPE.cast(LicenseInfoFactory.parseSPDXLicenseString(string));
            } catch (Exception exception) {
                String message =
                    "Unable to convert '" + string + "' to " + TYPE.getName();
    
                throw new ComponentConfigurationException(message, exception);
            }
    
            return object;
        }
    }
    

    Registering it with a custom ComponentConfigurator:

    @Named("license-mojo-component-configurator")
    @NoArgsConstructor @ToString @Slf4j
    public class LicenseMojoComponentConfigurator extends BasicComponentConfigurator {
        @PostConstruct
        public void init() {
            converterLookup.registerConverter(new LicenseConverter());
        }
    
        @PreDestroy
        public void destroy() { }
    }
    

    And then specifying the configurator in the @Mogo annotation:

    @Mojo(name = "generate-license-resources",
          configurator = "license-mojo-component-configurator",
          requiresDependencyResolution = TEST,
          defaultPhase = GENERATE_RESOURCES, requiresProject = true)
    @NoArgsConstructor @ToString @Slf4j
    public class GenerateLicenseResourcesMojo extends AbstractLicenseMojo {
    
    0 讨论(0)
  • 2021-01-23 16:41

    DefaultBeanConfigurator is responsible for using DefaultConverterLookup, and it instantiates it directly without using the Plexus Container.

    You could I suppose copy and modify it in a build extension, but registering your copy via @Component(role=BeanConfigurator.class) will likely have no effect; I have tried replacing standard Maven components in the past from build extensions and been told on maven-dev that it is not possible.

    You could look up the default BeanConfigurator and use reflection to get its ConverterLookup converterLookup field, then call registerConverter with your custom convertor, but this would be fragile.

    Probably best is to just give up, declare your Mojo parameter to be of type String, and do the conversion explicitly in execute.

    0 讨论(0)
提交回复
热议问题