views:

42

answers:

2

I have a maven application that looks like this

application_name/
    module1
        src/main/resources
            file_snippet.xml
    module2
        src/main/resources
            file_snippet.xml
    module3
        src/main/resources
            file.xml

file.xml should be like this

<workflow>
  <action>
  <%= module1/src/main/resources/file_snippet.xml %>
  </action>

  <action>
  <%= module2/src/main/resources/file_snippet.xml %>
  </action>

</workflow>

I want to include the contents of file_snippet.xml from module2 and module2 into file.xml of module3 before the build. Is that possible in maven? Is there some sort of templating language or plugin I can use?

+1  A: 

I would like to know about some template engine for maven too, but maybe you don't need maven at first for that.

There is a way to include another xml file in a xml file : http://bobcat.webappcabaret.net/javachina/faq/xml_01.htm#dtd_Q408

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
    <!ENTITY xmlfrag SYSTEM "xmlfrag.txt" >

    <!ELEMENT root (tag1, tag2) >   
    <!ELEMENT tag1 (childtag) >
    <!ELEMENT tag2 (childtag) >
    <!ELEMENT childtag (#PCDATA) >
    <!ATTLIST childtag att NMTOKEN #REQUIRED >
]>
<root>
  &xmlfrag;
</root>

xmlfrag.txt(well formed xml fragment without xml decl)

<tag1>
  <childtag att="child1">text1</childtag>
</tag1>
<tag2>
  <childtag att="child2">text2</childtag>
</tag2>

else, for merging xml resources between dependencies/modules in maven, you can use maven-shade-plugin (with the resource transformer).

In your case :

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>1.4</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                  <resource>file.xml</resource>
                  <!-- Add this to enable loading of DTDs
                  <ignoreDtd>false</ignoreDtd>
                  -->
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>

to merge module1/src/main/resources/file.xml and module2/src/main/resources/file.xml (depending on dependencies) in module3/src/main/resources/file.xml.

jwinandy
A: 

This is not easy, there are two parts you need to implement.

  1. get the snippets from the other module
  2. assemble the xml file using the include

for 1. you can use the dependency:unpack mojo:

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-dependency-plugin</artifactId>
      <executions>
        <execution>
          <id>unpack</id>
          <phase>initialize</phase>
          <goals>
            <goal>unpack</goal>
          </goals>
          <configuration>
            <outputDirectory>${project.build.directory}/snippets</outputDirectory>
            <includes>snippets/*.xml</includes>
            <artifactItems>
              <artifactItem>
                <groupId>your.app</groupId>
                <artifactId>module1</artifactId>
                <version>${project.version}</version>
                <type>jar</type>
              </artifactItem>
              <artifactItem>
                <groupId>your.app</groupId>
                <artifactId>module2</artifactId>
                <version>${project.version}</version>
                <type>jar</type>
              </artifactItem>
            </artifactItems>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Now you have copied all snippets from module1.jar/snippets and module2.jar/snippets to target/snippets (this was the easier part).

For 2. you need to pick a template engine and create a main class to assemble your template with it, probably using the exec:java mojo something like this:

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.1</version>
    <executions>
      <execution>
        <goals>
          <goal>java</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <mainClass>com.yourcompany.YourTemplateParser</mainClass>
      <arguments>
        <argument>path/to/your/template</argument>
        <argument>path/to/the/snippets/folder</argument>
        <argument>target/path</argument>
      </arguments>
    </configuration>
  </plugin>

(Personally, I tend to use GMaven instead of exec:java, as you can write inline groovy scripts without creating custom java classes)

seanizer