2010-06-09 29 views
6

Tiêu đề gốc là "Cách tạo enum từ tệp thuộc tính bằng cách sử dụng kiến?"Làm thế nào để tạo ra enum từ tập tin thuộc tính trong Maven?

Tôi muốn lặp qua tất cả thuộc tính và tạo lớp enum có mọi thuộc tính.

Tôi đang nghĩ về việc viết tác vụ tùy chỉnh, nhưng tôi nghĩ tôi sẽ cần phải đặt nó trong bình thêm: |

Tôi đang sử dụng maven và tôi muốn thực hiện điều đó trong giai đoạn tạo nguồn.

+1

thực sự bạn nên chỉnh sửa tiêu đề câu hỏi, vì môi trường của bạn là con quạ và kiến ​​chỉ là một lựa chọn có thể –

+0

Tôi biết điều này là cũ, nhưng tại sao không chỉ vứt bỏ các tập tin thuộc tính và chỉ sử dụng enums? –

Trả lời

8

Mặc dù tôi phần nào đồng ý với Peter Tilemans, tôi cũng bị cám dỗ bởi vấn đề này và tôi đã tấn công một giải pháp sử dụng groovy và GMaven-Plugin. EDIT: Điều tuyệt vời về GMaven là bạn có thể truy cập trực tiếp vào mô hình đối tượng maven mà không cần tạo plugin trước và vẫn có khả năng lập trình đầy đủ của Groovy.

Những gì tôi làm trong trường hợp như thế này là tạo thư mục nguồn được gọi là src/main/groovy không phải là một phần của quá trình xây dựng thực tế (và do đó sẽ không đóng góp vào jar/war etc). Ở đó tôi có thể đặt các tập tin nguồn groovy, do đó cho phép nhật thực để sử dụng chúng như các thư mục nguồn groovy cho tự động hoàn thành vv mà không thay đổi xây dựng.

Vì vậy, trong thư mục này tôi có ba tập tin: EnumGenerator.groovy, enumTemplate.txt và enum.properties (Tôi đã làm điều này để đơn giản, bạn có thể sẽ nhận được các thuộc tính tập tin từ một nơi khác)

Ở đây họ :

EnumGenerator.groovy

import java.util.Arrays; 
import java.util.HashMap; 
import java.util.TreeMap; 
import java.io.File; 
import java.util.Properties; 

class EnumGenerator{ 

    public EnumGenerator(
     File targetDir, 
     File propfile, 
     File templateFile, 
     String pkgName, 
     String clsName 
    ) { 
     def properties = new Properties(); 
     properties.load(propfile.newInputStream()); 
     def bodyText = generateBody(new TreeMap(properties)); 
     def enumCode = templateFile.getText(); 
     def templateMap = [ body:bodyText, packageName:pkgName, className: clsName ]; 
     templateMap.each{ key, value -> 
           enumCode = enumCode.replace("\${$key}", value) } 
     writeToFile(enumCode, targetDir, pkgName, clsName) 
    } 

    void writeToFile(code, dir, pkg, cls) { 
     def parentDir = new File(dir, pkg.replace('.','/')) 
     parentDir.mkdirs(); 
     def enumFile = new File (parentDir, cls + '.java') 
     enumFile.write(code) 
     System.out.println("Wrote file $enumFile successfully") 
    } 

    String generateBody(values) { 

     // create constructor call PROPERTY_KEY("value") 
     // from property.key=value 
     def body = ""; 
     values.eachWithIndex{ 
      key, value, index -> 
       body += 
       ( 
        (index > 0 ? ",\n\t" : "\t") 
        + toConstantCase(key) + '("' + value + '")' 
       ) 
     } 
     body += ";"; 
     return body; 

    } 

    String toConstantCase(value) { 
     // split camelCase and dot.notation to CAMEL_CASE and DOT_NOTATION 
     return Arrays.asList( 
      value.split("(?:(?=\\p{Upper})|\\.)") 
     ).join('_').toUpperCase(); 
    } 

} 

enumTemplate.txt

package ${packageName}; 

public enum ${className} { 

${body} 

    private ${className}(String value){ 
     this.value = value; 
    } 

    private String value; 

    public String getValue(){ 
     return this.value; 
    } 

} 

enum.tính

simple=value 
not.so.simple=secondvalue 
propertyWithCamelCase=thirdvalue 

Dưới đây là cấu hình pom:

<plugin> 
    <groupId>org.codehaus.groovy.maven</groupId> 
    <artifactId>gmaven-plugin</artifactId> 
    <version>1.0</version> 
    <executions> 
     <execution> 
      <id>create-enum</id> 
      <phase>generate-sources</phase> 
      <goals> 
       <goal>execute</goal> 
      </goals> 
      <configuration> 
       <scriptpath> 
        <element>${pom.basedir}/src/main/groovy</element> 
       </scriptpath> 
       <source> 
        import java.io.File 
        import EnumGenerator 

        File groovyDir = new File(pom.basedir, 
         "src/main/groovy") 
        new EnumGenerator(
         new File(pom.build.directory, 
          "generated-sources/enums"), 
         new File(groovyDir, 
          "enum.properties"), 
         new File(groovyDir, 
          "enumTemplate.txt"), 
         "com.mycompany.enums", 
         "ServiceProperty" 
        ); 

       </source> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 

Và đây là kết quả:

package com.mycompany.enums; 

public enum ServiceProperty { 

    NOT_SO_SIMPLE("secondvalue"), 
    PROPERTY_WITH_CAMEL_CASE("thirdvalue"), 
    SIMPLE("value"); 

    private ServiceProperty(String value){ 
     this.value = value; 
    } 

    private String value; 

    public String getValue(){ 
     return this.value; 
    } 

} 

bằng cách sử dụng mẫu, bạn có thể tùy chỉnh các enum cho phù hợp với nhu cầu của bạn . và kể từ khi gmaven nhúng groovy vào maven, bạn không phải cài đặt bất kỳ thứ gì hoặc thay đổi cấu hình xây dựng của mình.

Điều duy nhất cần nhớ là bạn sẽ cần phải sử dụng plugin buildhelper để add the generated source folder để tạo.

+0

ý tưởng tuyệt vời, cảm ơn. – IAdapter

+0

+1 cho sự sáng tạo (một lần nữa) –

+0

@pascal (chúng ta sẽ thấy một số chi tiết về điều đó, tôi hy vọng :-)) –

3

Tôi thực sự khuyên bạn nên xem xét lại.

Bạn có nguy cơ kết thúc mã hóa cứng với các giá trị đến từ tệp cấu hình và có thể thay đổi bất kỳ lúc nào.

Tôi nghĩ rằng một lớp trình bao quanh HashMap hoặc BidiMap đọc tệp thuộc tính sẽ đạt được hầu hết các lợi ích tương tự và các nhà phát triển sau này sẽ không rút ra được các lý do tại sao họ nhận được lỗi biên dịch gazillion vì thay đổi nhỏ tệp thuộc tính.

Tôi đã thực hiện phần chia sẻ mã của mình. Chúng rất tuyệt vời cho các trình phân tích cú pháp và trình xử lý giao thức nhưng đang đánh dấu các timebomb cho mọi trường hợp sử dụng khác mà tôi đã gặp phải sự bất hạnh khi sử dụng chúng.

+0

tôi đã sử dụng nó cho bộ chọn jQuery để kiểm tra. Tại sao bạn nghĩ đó là một ý tưởng tồi? nếu ai đó xóa bộ chọn hơn anh ta cũng nên xóa/cập nhật kiểm tra đang sử dụng tính năng đó. tôi chỉ trao đổi lỗi thời gian chạy cho các lỗi biên dịch. cộng với cách này tôi có thể easly thoát: trong selectors (nó chỉ hoạt động như \\ :). – IAdapter

+0

Tôi nghĩ rằng bạn đã có một vấn đề với điều đó bởi vì u đã không giữ các lớp học được tạo ra dưới sự kiểm soát nguồn, vì vậy khi một cái gì đó đã bị hỏng nó đã thực sự khó khăn để sửa chữa nó. – IAdapter

+0

Miễn là mã được tạo ra là tự chứa nó không phải là một vấn đề, các vấn đề bắt đầu nếu bạn bắt đầu mã hóa trong các lớp không được tạo ra đối với các hàm có chữ ký được tạo ra. Và không, các lớp được tạo ra không nằm dưới sự kiểm soát nguồn, chỉ các tệp mà từ đó chúng được tạo ra và thế hệ được thực hiện bởi hệ thống xây dựng. Nó có thể hoạt động tốt nếu mã của bạn thực sự được thử nghiệm tốt và mọi người trong nhóm phát triển và bảo trì đều biết điều đó. Trên thực tế, nó trông giống như một trường hợp sử dụng tốt: tạo ra mã "reptitive" ngu ngốc trong đó có một trường hợp sử dụng hạn chế. –

Các vấn đề liên quan