Jena schemagen在maven处理多个本体

时间:2014-03-26 13:58:10

标签: java maven jena ontology schemagen

我正在开发一个项目,该项目使用多个文件定义的多个本体。我希望使用Jena生成java类来帮助开发,但我似乎找不到让Jena将多个文件作为maven目标进行处理的方法。

我之前从未使用过Jena,但我在命令行中使用过它(从不同时使用多个本体)。

下面列出了我的pom.xml的相关部分(这很大程度上是从耶拿网站复制的):

<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>

我在Jena网站和其他网站上看了一下(我的googlefoo通常非常好),但我一直无法找到其他人遇到此问题或任何解释如何执行此操作的文档。 对此的任何帮助都非常有用。

3 个答案:

答案 0 :(得分:3)

我为Jena Schemagen编写了一个自定义Maven任务,该任务现在是标准Jena发行版的一部分。见the documentation here

答案 1 :(得分:2)

编辑

This Answer现在存在,并提出了一个更标准的解决方案。也就是说,海报开发的schemagen-maven plugin的存在,包含在标准的耶拿分发中。

原始答案

你有两个选择,创建一个自定义maven插件(实际上并不那么困难)或者在maven外部发布一些东西以满足你的需求。我过去做了一个黑客,我将与你分享。它不漂亮,但效果很好。

此方法使用Maven Ant Tasks从maven构建的build.xml阶段内调出一个蚂蚁generate-sources

首先修改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目标,那么我们可以使用antcontrib中的foreach来处理指定目录中的每个文件。根据需要调整此文件模式。请注意,.owl的假定扩展名用于其他地方。
  4. 对于每个owl文件,调用my.schemagen-file目标。我使用local variables来制作此功能。
  5. 自定义ant任务(在javascript中定义,名为make-proper)有助于生成文件的目标文件名。我使用的惯例是我的词汇表文件在some-hyphenated-lowercase-structure.owl。我想要的班级名称是SomeHyphenatedLowercaseStructure.java。你应该根据自己的需要自定义它。
  6. 对于每个派生文件名,我们测试它是否存在以及它是否已过期。如果源文件比目标文件新,则此方便性仅允许schemagen运行。我们使用outofdate task来执行此操作。
  7. 我们运行schemagen。我使用特定于OWL词汇表的标志。您可以调整此选项,但最适合您的系统。

答案 2 :(得分:0)

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

归功于DB5