2013-05-22 15 views
12

私はMavenのアーキタイプを作ることに興味があり、私は基本の大部分を失ってしまったと思います。しかし、私が固執していることの1つは、テンプレートを記入するためにカスタムロジックを使用することが時々あるということです。たとえば、誰かが私のアーキタイプを生成し、artifactIdをhello-worldとして指定した場合、単にHello Worldという名前のクラスを生成したいと思います。コンソールに接続します。別の人がartifactId = howdy-thereでそれを生成すると、gennedクラスはHowdyThereになり、 "Howdy There!"が出力されます。Mavenアーキタイプでカスタムロジックを提供するにはどうすればよいですか?

MavenのアーキタイプメカニズムはVelocity Template Engineを利用していることがわかりましたので、この記事をcreating custom directivesで読んでいます。これは私が探していたものと思われたので、org.apache.velocity.runtime.directive.Directiveを拡張したHyphenatedToCamelCaseDirectiveというクラスを作成しました。そのクラスでは、私のgetName()実装は "hyphenatedCamelCase"を返します。私の原型-のmetadata.xmlファイルでは、私は以下を持っている...

<requiredProperties> 
    <requiredProperty key="userdirective"> 
     <defaultValue>com.jlarge.HyphenatedToCamelCaseDirective</defaultValue> 
    </requiredProperty> 
</requiredProperties> 

マイテンプレートクラスは、私は私の原型をインストールして原型を行う

package ${package}; 

public class #hyphenatedToCamelCase('$artifactId') { 

    // userdirective = $userdirective 
    public static void main(String[] args) { 
     System.out.println("#hyphenatedToCamelCase('$artifactId')")); 
    } 
} 

後...次のようになります。ハウディ-そこたartifactId =とのgroupId = f1.f2を指定することによって発生する、結果のクラスは、このようになります...

package f1.f2; 

public class #hyphenatedToCamelCase('howdy-there') { 

    // userdirective = com.jlarge.HyphenatedToCamelCaseDirective  
    public static void main(String[] args) { 
     System.out.println("#hyphenatedToCamelCase('howdy-there')")); 
    } 
} 

結果にもかかわらずuserdirectiveが、私はそれが期待されるように設定されていることを示し、そうではありません#hyphenatedToCamelCaseディレクティブをevaulatingしていました。ディレクティブクラスでは、レンダリングメソッドがSystem.outにメッセージをロギングしていますが、そのメッセージはコンソールに表示されません。そのため、archetype:generateの間にメソッドが実行されたことはありません。

ここでは単純なものがありませんか、またはこの方法はちょうど行く方法ではありませんか?

答えて

2

archetype-metatadata xmlの必須プロパティセクションは、ベロシティコンテキストに追加のプロパティを渡すために使用されます。ではなく、がベロシティエンジン構成を通過することを意味します。したがって、userDirectiveというプロパティを設定すると、変数$ userDirectiveが使用可能になり、カスタムディレクティブがベロシティエンジンに追加されなくなります。

ソースコードが表示されている場合、maven-archetypeプラグインで使用される速度エンジンは、その設定の外部プロパティソースに依存しません。 generates the projectコードは、VelocityComponentのautowired(plexusコンテナによる)実装に依存しています。

これは、速度エンジンが初期化されたコードです:

public void initialize() 
    throws InitializationException 
{ 
    engine = new VelocityEngine(); 

    // avoid "unable to find resource 'VM_global_library.vm' in any resource loader." 
    engine.setProperty("velocimacro.library", ""); 

    engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, this); 

    if (properties != null) 
    { 
     for (Enumeration e = properties.propertyNames(); e.hasMoreElements();) 
     { 
      String key = e.nextElement().toString(); 

      String value = properties.getProperty(key); 

      engine.setProperty(key, value); 

      getLogger().debug("Setting property: " + key + " => '" + value + "'."); 
     } 
    } 

    try 
    { 
     engine.init(); 
    } 
    catch (Exception e) 
    { 
     throw new InitializationException("Cannot start the velocity engine: ", e); 
    } 
} 

カスタムディレクティブを追加するハックの方法があります。上記のプロパティは、plexus-velocity-1.1.8.jarのcomponents.xmlファイルから読み込まれます。このファイルを開き、設定プロパティを追加してください。

<component-set> 
    <components> 
    <component> 
     <role>org.codehaus.plexus.velocity.VelocityComponent</role> 
     <role-hint>default</role-hint> 
     <implementation>org.codehaus.plexus.velocity.DefaultVelocityComponent</implementation> 
     <configuration> 
     <properties> 
      <property> 
      <name>resource.loader</name> 
      <value>classpath,site</value> 
      </property> 
      ... 
      <property> 
      <name>userdirective</name> 
      <value>com.jlarge.HyphenatedToCamelCaseDirective</value> 
      </property> 
     </properties> 
     </configuration> 
    </component> 
    </components> 
</component-set> 

このカスタムjarファイルにカスタムディレクティブクラスファイルを追加し、archetype:generateを実行します。

これは非常に脆弱で、このハッキングされた叢線速度の瓶を配布する方法を理解する必要があります。このアーキタイプを使用しようとしているものによっては、その努力の価値があるかもしれません。