2

I am working on a project which uses multiple ontologies defined over several files. I am hoping to use Jena to generate the java classes to help with development but I can't seem to find a way to have Jena process multiple files as a maven goal.

I have never used Jena through maven before but I have used it on the command line (never for multiple ontologies at the same time).

The relevant part of my pom.xml is listed below (this was largely copied from the Jena website):

<plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>java</goal>
                    </goals>
                    <configuration>
                        <mainClass>jena.schemagen</mainClass>
                        <commandlineArgs>
                            --inference \
                            -i ${basedir}/src/main/resources/ontologies/exception.owl \
                            --package com.borwell.dstl.mexs.ontology \
                            -o ${project.build.directory}/generated-sources/java \
                        </commandlineArgs>
                        <commandlineArgs>
                            --inference \
                            -i ${basedir}/src/main/resources/ontologies/location.owl \
                            --package com.borwell.dstl.mexs.ontology \
                            -o ${project.build.directory}/generated-sources/java \
                        </commandlineArgs>
                    </configuration>
                </execution>
            </executions>
        </plugin>
</plugins>

I have had a good look around on the Jena website and other sites (my googlefoo is usually quite good) but I have been unable to find anyone else having this problem or any documentation explaining how to do this. Any help on this would be very useful.

4

3 回答 3

3

我为 Jena Schemagen 编写了一个自定义 Maven 任务,它现在是标准 Jena 发行版的一部分。请参阅此处的文档

于 2014-03-30T21:14:22.507 回答
2

编辑

这个答案现在存在,并提出了一个更标准的解决方案。即,发布者开发的schemagen-maven 插件的存在,该插件包含在标准 Jena 发行版中。

原始答案

您有两个选择,创建一个自定义的 maven 插件(实际上并不难)或使用 maven 之外的东西来满足您的需求。我过去做了一个hack,我会和你分享。它不漂亮,但效果很好。

这种方法使用Maven Ant 任务build.xmlgenerate-sourcesMaven 构建阶段调用蚂蚁。

您首先将您的修改pom.xml为包括以下内容:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.7</version>
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <target>
                            <taskdef resource="net/sf/antcontrib/antcontrib.properties"
                                classpathref="maven.runtime.classpath" />
                            <property name="runtime-classpath" refid="maven.runtime.classpath" />
                            <ant antfile="${basedir}/src/main/ant/build.xml"
                                inheritRefs="true">
                                <target name="my.generate-sources" />
                            </ant>
                        </target>
                    </configuration>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>ant-contrib</groupId>
                    <artifactId>ant-contrib</artifactId>
                    <version>1.0b3</version>
                    <exclusions>
                        <exclusion>
                            <groupId>ant</groupId>
                            <artifactId>ant</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

build.xml文件中(如您所见,该文件位于 , 中src/main/ant/build.xml,如下所示。

<?xml version="1.0" encoding = "UTF-8"?>
<!DOCTYPE project>
<project name="my" default="my.error">

    <property name="vocab.out.root" location="${basedir}/src/main/java" />
    <property name="vocab.package" value = "put something here" />
    <property name="vocab.ns" value="put something here" />

    <path id="my.vocabulary">
        <fileset dir="${basedir}/src/main/resources/put something here" casesensitive="yes" >
            <include name="**/*.owl" />
        </fileset>
    </path>

    <scriptdef language="javascript" name="make-proper">
        <attribute name="string" /> 
        <attribute name="to" />
        <![CDATA[
            var raw_string = attributes.get( "string" );
            var string_elements = raw_string.split('-');
            var nameComponents;
            var finalName = "";

            var i;
            for(i = 0; i < string_elements.length; i++){
                 var element = string_elements[i];
                 finalName += element.substr(0,1).toUpperCase() + element.substr(1);
            }

            project.setProperty( attributes.get( "to" ), finalName );
        ]]>
    </scriptdef>

    <!-- target for processing a file -->
    <target name="my.schemagen-file">

        <echo message="${vocab.file}" />

        <!-- for constructing vocab file name -->
        <local name="source.file.dir" />
        <dirname property="source.file.dir" file="${vocab.file}" />
        <local name="source.file" />
        <basename property="source.file" file="${vocab.file}" suffix=".owl" />
        <local name="vocab.name" />
        <make-proper string="${source.file}" to="vocab.name" />

        <!-- for constructing destination file name -->
        <local name="vocab.package.path" />
        <propertyregex property="vocab.package.path" input="${vocab.package}" regexp="\." replace="/" global="true" />
        <local name="dest.file" />
        <property name="dest.file" value="${vocab.out.root}/${vocab.package.path}/${vocab.name}.java" />

        <!-- Determine if we should build, then build -->       
        <outofdate>
            <sourcefiles path="${vocab.file}" />
            <targetfiles path="${dest.file}" />
            <sequential>
                <!-- Actual construction of the destination file -->
                <echo message="--inference --ontology -i ${vocab.file} -a ${vocab.ns} --package ${vocab.package} -o ${vocab.out.root} -n ${vocab.name}" />
                <java classname="jena.schemagen" classpath="${runtime-classpath}">
                    <arg line="--ontology --nostrict -i ${vocab.file} -a ${vocab.ns} --package ${vocab.package} -o ${vocab.out.root} -n ${vocab.name}" />
                </java>
            </sequential>
        </outofdate>
    </target>

    <!-- Maven antrun target to generate sources -->
    <target name="my.generate-sources">
        <foreach target="my.schemagen-file" param="vocab.file" inheritall="true">
            <path refid="my.vocabulary"/>
        </foreach>
    </target>

    <target name="my.error">
        <fail message="This is not intended to be executed from the command line. Execute generate-sources goal using maven; ex:\nmvn generate-sources" />
    </target>
</project>

带你了解整个事情。

  1. 执行我们的maven-antrun-plugin构建脚本,确保 antcontrib 和maven.runtime.classpath. 这确保了在 maven 中可用的属性在 ant 任务中也可用。
  2. 如果build.xml在没有指定任务的情况下调用,它会故意失败。这有助于防止您错误地使用它。
  3. 如果my.generate-sources目标被执行,那么我们可以使用foreachfrom antcontrib 来处理您指定目录中的每个文件。根据需要调整此文件模式。请注意,假定的扩展名在.owl其他地方使用。
  4. 对于每个 owl 文件,my.schemagen-file都会调用目标。我利用local变量来实现这个功能。
  5. 自定义 ant 任务(在 javascript 中定义,命名make-proper)有助于为您的文件生成目标文件名。我使用我的词汇文件所在的约定some-hyphenated-lowercase-structure.owl。我想要的班级名称是SomeHyphenatedLowercaseStructure.java. 您应该自定义它,但您认为合适。
  6. 对于每个派生文件名,我们测试它是否存在以及是否过期。这种便利只允许在源文件比目标文件新的情况下运行 schemagen。我们使用outofdate任务来做到这一点。
  7. 我们运行 schemagen。我使用特定于 OWL 词汇表的标志。您可以调整它,但最适合您的系统。
于 2014-03-28T19:48:36.277 回答
0

经过更广泛的搜索并感谢DB5,我发现解决方案是多次执行。我希望有一个更优雅的解决方案,但这确实有效。

归功于DB5

于 2014-03-26T15:17:41.960 回答