##    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>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

	## The ${} below are expanded from taverna-engine pom.xml
	## by resource filtering, rather than by Velocity
	## http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
            <taverna.language.version>${taverna.language.version}</taverna.language.version>
            <taverna.osgi.version>${taverna.osgi.version}</taverna.osgi.version>
            <taverna.engine.version>${project.parent.version}</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>
