##    Licensed to the Apache Software Foundation (ASF) under one or more
##    contributor license agreements.  See the NOTICE file distributed with
##    this work for additional information regarding copyright ownership.
##    The ASF licenses this file to You under the Apache License, Version 2.0
##    (the "License"); you may not use this file except in compliance with
##    the License.  You may obtain a copy of the License at
##
##    http://www.apache.org/licenses/LICENSE-2.0
##
##    Unless required by applicable law or agreed to in writing, software
##    distributed under the License is distributed on an "AS IS" BASIS,
##    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
##    See the License for the specific language governing permissions and
##    limitations under the License.
##
## Note: Above Velocity comment should NOT be included in generated
## pom.xml from the archetype
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>${groupId}</groupId>
	<artifactId>${artifactId}</artifactId>
	<version>${version}</version>
	<packaging>pom</packaging>
	<name>${classPrefix} Taverna project</name>

	<properties>
            <taverna.language.version>0.15.1-incubating</taverna.language.version>
            <taverna.osgi.version>0.2.1-incubating</taverna.osgi.version>
            <taverna.engine.version>3.1.0-incubating-SNAPSHOT</taverna.engine.version>
						<taverna.workbench.version>3.1.0-incubating-SNAPSHOT</taverna.workbench.version>
	</properties>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-source-plugin</artifactId>
				<executions>
					<execution>
						<goals>
							<goal>jar</goal>
							<goal>test-jar</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
			<plugin>
				<artifactId>maven-jar-plugin</artifactId>
				<executions>
					<execution>
						<goals>
							<goal>test-jar</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
			<plugin>
				<artifactId>maven-surefire-plugin</artifactId>
				<configuration>
					<skip>false</skip>
					<systemProperties>
						<property>
							<name>java.awt.headless</name>
							<value>true</value>
						</property>
					</systemProperties>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-bundle-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.apache.taverna.osgi</groupId>
				<artifactId>taverna-maven-plugin</artifactId>
				<version>${taverna.osgi.version}</version>
				<extensions>true</extensions>
			</plugin>
		</plugins>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.felix</groupId>
					<artifactId>maven-bundle-plugin</artifactId>
					<version>2.5.4</version>
					<extensions>true</extensions>
				</plugin>
				<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
				<plugin>
					<groupId>org.eclipse.m2e</groupId>
					<artifactId>lifecycle-mapping</artifactId>
					<version>1.0.0</version>
					<configuration>
						<lifecycleMappingMetadata>
							<pluginExecutions>
								<pluginExecution>
									<pluginExecutionFilter>
										<groupId>org.apache.taverna.orgi</groupId>
										<artifactId>taverna-maven-plugin</artifactId>
										<versionRange>[${taverna.osgi.version},)</versionRange>
										<goals>
											<goal>plugin-generate</goal>
										</goals>
									</pluginExecutionFilter>
									<action>
										<ignore />
									</action>
								</pluginExecution>
							</pluginExecutions>
						</lifecycleMappingMetadata>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.4</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<repositories>
    <repository>
        <id>apache.snapshots</id>
        <name>Apache Snapshot Repository</name>
        <url>http://repository.apache.org/snapshots</url>
        <releases>
            <enabled>false</enabled>
        </releases>
    </repository>

		<repository>
			<!-- The repository that your jars are deployed to -->
			<id>my-repository</id>
			<name>My Repository</name>
			<url>http://www.example.com/maven/repository</url>
		</repository>
		<repository>
			<!-- The repository that your snapshot jars are deployed to -->
			<releases>
				<enabled>false</enabled>
			</releases>
			<snapshots />
			<id>my-snapshot-repository</id>
			<name>My snapshot Repository</name>
			<url>file:///tmp/test-plugins/</url>
		</repository>
	</repositories>


	<!-- The location of your plugin site -->
	<distributionManagement>
		<repository>
			<id>my-plugin-site</id>
			<name>My Plugin Site</name>
			<url>scpexe://example.com/www/taverna/plugins/</url>
		</repository>
		<snapshotRepository>
			<id>my-test-plugin-site</id>
			<name>My Test Plugin Site</name>
			<url>file:///tmp/test-plugins/</url>
		</snapshotRepository>
	</distributionManagement>

</project>
