如何创建自定义Intellij模板设置器以与Guava的Optional一起使用

时间:2016-02-20 22:59:28

标签: java android templates intellij-idea guava

我正在尝试使用Intelij Template编写自定义setter,但是对于Google的Guava Optionals。例如,如果我有一个类如下:

public class Note {
    public Optional<String> title;
}

在Android Studio输出中使用默认的Setter代:

public class Note {
    public Optional<String> title;

    public void setTitle(Optional<String> title) {
        this.title = title;
    } 
}

我想要实现的目标是:

public class Note {
    public Optional<String> title;

    public void setTitle(String title) {
        this.title = Optional.fromNullable(title);
    } 
}

我到目前为止所尝试的是复制Intelij的模板并使用StringUtil.split()去除方法签名的Optional<部分。但是,当我使用下面的模板时,我收到了错误。

错误

Incorrect method 'public void setTitle($StringUtil.split($field.type, true, "<").get(1) title) { mTitle = title; }

关于我应该做什么的任何建议?

Setter Generation的默认Intelij Default模板

#set($paramName = $helper.getParamName($field, $project))
public ##
#if($field.modifierStatic)
  static ##
#end
void set$StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier($helper.getPropertyName($field, $project)))($field.type $paramName) {
  #if ($field.name == $paramName)
    #if (!$field.modifierStatic)
      this.##
    #else
      $classname.##
    #end
  #end
  $field.name = $paramName;
}

我的自定义Guava可选Setter生成

#set($paramName = $helper.getParamName($field, $project))
public ##
#if($field.modifierStatic)
  static ##
#end
void set$StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier($helper.getPropertyName($field, $project)))($StringUtil.split($field.type, true, "<").get(1) $paramName) {
  #if ($field.name == $paramName)
    #if (!$field.modifierStatic)
      this.##
    #else
      $classname.##
    #end
  #end
  $field.name = $paramName;
}

3 个答案:

答案 0 :(得分:3)

经过一些搜索后,我发现在StringUtils中,split()的签名与上面发布的签名不同。

我能够编写一个完整的解决方案来为下面的Guava Optionals创建一个setter。它非常脆弱,因为我不熟悉IntelliJ中的模板,因为它依赖于包名com.google.common.base.Optional以及StringsUtils,而且似乎没有正式记录。

首先检查$paramName是否为Optional。如果是这样,请使用Guava可选设置完成setter。否则,回退到默认的IntelliJ设置器。

#set($paramName = $helper.getParamName($field, $project))
public ##
#if($field.modifierStatic)
    static ##
#end
#if($StringUtil.split($field.type, "<").get(0).equals("com.google.common.base.Optional"))    
    #set($paramSignature = $StringUtil.trimEnd($StringUtil.substringAfter($field.type, "<"), ">"))
    #set($fieldAssignment = "Optional.fromNullable(" + $paramName + ")") 
#else
    #set($paramSignature = $field.type)
    #set($fieldAssignment = $paramName)
#end
void set$StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier($helper.getPropertyName($field, $project)))($paramSignature $paramName) { 
#if ($field.name == $paramName)
    #if (!$field.modifierStatic)
        this.##
    #else
        $classname.##
    #end
#end
$field.name = $fieldAssignment;
}

已编辑基于@ChiefTwoPencils反馈的代码。

答案 1 :(得分:3)

我看到了你的答案,这很好,但你必须知道你不必为你需要的每种类型的条件复杂化模板(即使你现在只有一个;下次怎么样?)。

相反,为什么不为这个特定需求创建自己的,并选择何时去创建方法?

我会是第一个承认这可以做得更好的人;我只是想看看能否让它正常工作。尽管如此,它并不依赖于Optional的完全限定包名称;我甚至没有安装Guava,它可以工作。

#set($paramName = $helper.getParamName($field, $project))
public ##
#if($field.modifierStatic)
  static ##
#end
void set$StringUtil.capitalizeWithJavaBeanConvention(
  $StringUtil.sanitizeJavaIdentifier(
    $helper.getPropertyName($field, $project)
  )
)($StringUtil.trimEnd($StringUtil.substringAfter($field.type, "<"), ">") $paramName) {
  #if ($field.name == $paramName)
    #if (!$field.modifierStatic)
      this.##
    #else
      $classname.##
    #end
  #end
  $field.name = Optional.fromNullable($paramName);
}

答案 2 :(得分:0)

Getter,在我的情况下,我需要大写的第一个字母并删除字段变量的“m”

#if($field.modifierStatic)
static ##
#end
$field.type ##
#if($field.recordComponent)
  ${field.name}##
#else
#set($name = $StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier($helper.getPropertyName($field, $project))))
#if ($StringUtil.startsWithIgnoreCase($name, 'm'))
  #set($name = $name.substring(1, $name.length()))
#end
#if ($field.boolean && $field.primitive)
  Is##
#else
  Get##
#end  
${name}##
#end
() {
  return $field.name;
}

对于setter也是一样,去掉一个字段变量的'm',param也去掉它并设置小写首字母

#set($paramName = $helper.getParamName($field, $project))
#if($field.modifierStatic)
static ##
#end
#set($functionName = $StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier($helper.getPropertyName($field, $project))))
#if ($StringUtil.startsWithIgnoreCase($paramName, 'm'))
  #set($paramName = $paramName.substring(1,2).toLowerCase() + $paramName.substring(2, $paramName.length()))
  #set($functionName = $functionName.substring(1)) 
#end
void Set$functionName ($field.type $paramName) {
  #if ($field.name == $paramName)
    #if (!$field.modifierStatic)
      this.##
    #else
      $classname.##
    #end
  #end
  $field.name = $paramName;
}

示例:

private Handler mJobHandler;

吸气剂:

public Handler GetJobHandler()
{
    return mJobHandler;
}

二传手:

public void SetJobHandler(Handler jobHandler)
{
    mJobHandler = jobHandler;
}