You are on page 1of 103

GeoServer Developer Manual

Release 2.0.2

GeoServer

May 24, 2010

CONTENTS

1 2

Introduction Tools 2.1 Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Maven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Subversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Source Code 3.1 Committing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Repository structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3 Branch structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Quickstart 4.1 Check out source code . . . . . . . . . . 4.2 Build with Maven . . . . . . . . . . . . 4.3 Generate Eclipse project les with Maven 4.4 Import modules into Eclipse . . . . . . . 4.5 Run GeoServer from Eclipse . . . . . . . 4.6 Access GeoServer front page . . . . . . Maven Guide 5.1 Installing Maven . . . . . . . . . . 5.2 Running Maven . . . . . . . . . . 5.3 Building . . . . . . . . . . . . . . 5.4 Skipping tests . . . . . . . . . . . . 5.5 Building ofine . . . . . . . . . . . 5.6 Building extensions . . . . . . . . 5.7 Proles . . . . . . . . . . . . . . . 5.8 Eclipse . . . . . . . . . . . . . . . 5.9 Building the web module . . . . . . 5.10 Running the web module with Jetty

3 5 5 5 5 7 7 7 8 9 9 9 10 10 14 15 17 17 17 17 17 18 18 18 18 19 19 21 21 21 24 29 29 34 i

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

Eclipse Guide 6.1 Importing modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Running and debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3 Eclipse preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Programming Guide 7.1 OWS Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2 REST Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7.3 7.4 7.5 7.6 8

Web User Interface . . . . . . . . . Wicket Development In GeoServer Extension Points . . . . . . . . . . WPS design guide . . . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

43 48 52 52 55 55 55 55 56 56 57 57 57 58 58 60 61 61 61 64 64 64 66 69 70 73 73 73 73 73 75 78 79 79 80 80 82 83 84 84 84 85 87 87 88 89 90 92

Release Guide 8.1 Notify developer lists . . . . . . . . . . 8.2 Prerequisites . . . . . . . . . . . . . . 8.3 Update source code . . . . . . . . . . . 8.4 Update the README . . . . . . . . . 8.5 Create a release tag . . . . . . . . . . . 8.6 Update version numbers in tag . . . . . 8.7 Upgrade branch pom versions . . . . . 8.8 Set tag pom versions . . . . . . . . . . 8.9 Build release artifacts . . . . . . . . . 8.10 Build documentation . . . . . . . . . . 8.11 CITE testing . . . . . . . . . . . . . . 8.12 Hand testing . . . . . . . . . . . . . . 8.13 Deploy Artifacts . . . . . . . . . . . . 8.14 Build Windows installer . . . . . . . . 8.15 Build Mac OS X installer . . . . . . . 8.16 Release on JIRA . . . . . . . . . . . . 8.17 Upload release artifacts to SourceForge 8.18 Release on SourceForge . . . . . . . . 8.19 Create a download page . . . . . . . . 8.20 Announce the release . . . . . . . . . . Release Testing Checklist 9.1 Artifact size . . . . 9.2 Demos . . . . . . . 9.3 Sample requests . . 9.4 Map preview . . . . 9.5 KML . . . . . . . . 9.6 GeoWebCache . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

10 Cite Test Guide 10.1 Check out CITE tools 10.2 Build the CITE tools . 10.3 Run the test engine . . 10.4 Run WFS 1.0 tests . . 10.5 Run WFS 1.1 tests . . 10.6 Run WMS 1.1 tests . . 10.7 Run WCS 1.1 tests . . 10.8 Run WCS 1.0 tests . . 10.9 Command line . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

11 Policies and Procedures 11.1 Comitting . . . . . . . . . . . . . . 11.2 Code Review . . . . . . . . . . . . 11.3 Community Process . . . . . . . . 11.4 GeoServer Improvement Proposals 11.5 Community Modules . . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

ii

GeoServer Developer Manual, Release 2.0.2

Welcome to the GeoServer Developer Manual. The manual is for those who want to help with the development process, including source code, software releasing, and other administrative work.

CONTENTS

GeoServer Developer Manual, Release 2.0.2

CONTENTS

CHAPTER

ONE

INTRODUCTION

GeoServer Developer Manual, Release 2.0.2

Chapter 1. Introduction

CHAPTER

TWO

TOOLS
The following tools need to installed on the system before a GeoServer developer environment can be set up.

2.1 Java
Developing with GeoServer requires a Java Development Kit (JDK) 1.5 or greater, available from Sun Microsystems. Note: While it is possible to use a JDK other than the one provided by Sun, it is recommended that the Sun JDK be used.

2.2 Maven
GeoServer uses a tool known as Maven to build. The current recommended version of Maven is 2.1.0 and is available from Apache. While 2.1.0 is recommended any version greather than 2.0.8 should also work.

2.3 Subversion
GeoServer source code is stored and versioned in a subversion repository. There are a variety of subversion clients available for a number of different platforms. Visit http://subversion.tigris.org/getting.html for more details.

GeoServer Developer Manual, Release 2.0.2

Chapter 2. Tools

CHAPTER

THREE

SOURCE CODE
The GeoServer source code is located at http://svn.codehaus.org/geoserver. To check out the development / trunk version:
svn co http://svn.codehaus.org/geoserver/trunk geoserver

To check out the stable / branch version:


svn co http://svn.codehaus.org/geoserver/branches/1.7.x geoserver

Warning: The GeoServer repository contains a signicant amount of spatial data. Checking it out over a slow or low bandwidth connection can be costly. In such cases it may be desirable to check out only the sources:
svn co http://svn.codehaus.org/geoserver/trunk/src

3.1 Committing
In order to commit to the repository the following steps must be taken: 1. Install this subversion cong le. See additional notes below. 2. Register for commit access as described here. 3. Switch the repository to the https protocol. Example:
[root of checkout]% svn switch https://svn.codehaus.org/geoserver/trunk

3.2 Repository structure


http://svn.codehaus.org/geoserver/ branches/ spike/ tags/ trunk/

branches contains all previously stable development branches, 1.6.x, 1.7.x, etc...

GeoServer Developer Manual, Release 2.0.2

spike contains experimental projects and mock ups tags contains all previously released versions trunk is the current development branch

3.3 Branch structure


Each development branch has the following structure:
http://svn.codehaus.org/geoserver/ doc/ src/ data/

doc contains the sources for the user and developer guides src contains the java sources for GeoServer itself data contains a variety of GeoServer data directories

Chapter 3. Source Code

CHAPTER

FOUR

QUICKSTART
A step by step guide describing how to quickly get up and running with a GeoServer development environment. This guide assumes that all the necessary Tools are installed. Note: This guide is designed to get developers up and running as quick as possible. For a more comprehensive guide see the Maven Guide and the Eclipse Guide. Check out source code Build with Maven Generate Eclipse project les with Maven Import modules into Eclipse Run GeoServer from Eclipse Access GeoServer front page

4.1 Check out source code


Check out the source code from the subversion repository. Choose trunk for the latest development, or a stable branch for versions less likely to change often. Either:
svn co https://svn.codehaus.org/geoserver/trunk geoserver-trunk

Or (stable 1.7.x branch):


svn co https://svn.codehaus.org/geoserver/branches/1.7.x geoserver-1.7.x

In this example we will pretend that you checked the source out into a directory called geoserver, but a more descriptive name is recommended.

4.2 Build with Maven


Change directory to the root of the source tree and execute the maven build command:
cd geoserver/src mvn clean install

A successful build will result in something like the following output: 9

GeoServer Developer Manual, Release 2.0.2

[INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO]

-----------------------------------------------------------------------Reactor Summary: -----------------------------------------------------------------------GeoServer ............................................. SUCCESS [10.271s] GeoServer Maven Plugins ............................... SUCCESS [0.865s] Configuration Deployment PlugIn ....................... SUCCESS [3.820s] GeoServer Maven Archetypes ............................ SUCCESS [0.054s] GeoServer WFS Output Format Archetype ................. SUCCESS [0.390s] Core Platform Module .................................. SUCCESS [5.270s] Data Module ........................................... SUCCESS [4.521s] Open Web Service Module ............................... SUCCESS [2.730s] Main Module ........................................... SUCCESS [10.077s] Web Coverage Service Module ........................... SUCCESS [3.785s] Web Coverage Service 1.1.1 Module ..................... SUCCESS [5.254s] Validation Module ..................................... SUCCESS [1.131s] Web Feature Service Module ............................ SUCCESS [6.695s] Web Feature Service Module ............................ SUCCESS [1.197s] Web Map Service Module ................................ SUCCESS [8.519s] Geoserver REST Support Code ........................... SUCCESS [3.366s] GeoWebCache (GWC) Module .............................. SUCCESS [0.255s] Web Application Module ................................ SUCCESS [27.386s] Community Space ....................................... SUCCESS [0.312s] GeoServer Extensions .................................. SUCCESS [0.071s] ----------------------------------------------------------------------------------------------------------------------------------------------BUILD SUCCESSFUL ------------------------------------------------------------------------

4.3 Generate Eclipse project les with Maven


Generate the eclipse .project and .classpath les:
mvn eclipse:eclipse

4.4 Import modules into Eclipse


1. Run the Eclipse IDE 2. Open the Eclipse Preferences 3. Navigate to Java, Build Path, Classpath Variables and click New...

10

Chapter 4. Quickstart

GeoServer Developer Manual, Release 2.0.2

4. Create a classpath variable named M2_REPO and set the value to the location of the local Maven repository, and click Ok

5. Click Ok to apply the new Eclipse preferences 6. Right-click in the Package Explorer and click Import...

4.4. Import modules into Eclipse

11

GeoServer Developer Manual, Release 2.0.2

7. Select Existing Projects into Workspace and click Next

12

Chapter 4. Quickstart

GeoServer Developer Manual, Release 2.0.2

8. Navigate to the geoserver/src directory 9. Ensure all modules are selected and click Finish

4.4. Import modules into Eclipse

13

GeoServer Developer Manual, Release 2.0.2

4.5 Run GeoServer from Eclipse


1. From the Package Explorer select the web-app module (web in 1.7.x or earlier) 2. Navigate to the org.geoserver.web package (org.vfny.geoserver.jetty in 1.7.x or earlier) 3. Right-click the Start class and navigate to Run as, Java Application

14

Chapter 4. Quickstart

GeoServer Developer Manual, Release 2.0.2

4.6 Access GeoServer front page


After a few seconds, GeoServer should be accessible at: http://localhost:8080/geoserver The default admin password is geoserver.

4.6. Access GeoServer front page

15

GeoServer Developer Manual, Release 2.0.2

16

Chapter 4. Quickstart

CHAPTER

FIVE

MAVEN GUIDE
A reference for building GeoServer with Maven.

5.1 Installing Maven


See Tools.

5.2 Running Maven


Maven provides a wide range of commands used to do everything from compiling a module to generating test coverage reports. Most maven commands can be run from the root the source tree, or from a particular module. Note: When attempting to run a maven command from the root of the source tree remember to change directory from the root the checkout into the src directory. When running a command from the root of the source tree, or from a directory that contains other modules the command will be run for all modules. When running the command from a single module, it is run only for that module.

5.3 Building
The most commonly maven command used with GeoServer is the install command:
mvn clean install

While the clean command is not necessary, it is recommented. Running this command does the following: compiles source code runs unit tests installs artifacts into the local maven repository

5.4 Skipping tests


Often it is useful to skip unit tests when performing a build. Adding the ag -DskipTests to the build command will only compile unit tests, but not run them:

17

GeoServer Developer Manual, Release 2.0.2

mvn -DskipTests clean install

5.5 Building ofine


Maven operates by automatically downloading any dependencies declared by a module being built. When dealing with SNAPSHOT dependencies this can be problematic. Each time Maven performs its rst build of the day it tries to update any SNAPSHOT dependencies it occurs. This can be a problem as GeoServer depends on SNAPSHOT versions of the GeoTools library. The end result is maven downloading a lot of updates GeoTools modules and an increased built time. Which if you built geotools locally, is unecessary. This can be remedied by running maven in ofine mode:
mvn -o clean install

In ofine mode Maven will not attempt to download any external dependencies, and will not attempt to update any SNAPSHOT dependencies.

5.6 Building extensions


By default, extensions are not included in the build. They are added to the build explicitly via proles. For example the following command adds the restconfig extension to the build:
mvn clean install -P restconfig

Multiple extensions can be enabled simultaneously:


mvn clean install -P restconfig,oracle

A special prole named allExtensions enables all extensions:


mvn clean install -P allExtensions

5.7 Proles 5.8 Eclipse


The maven eclipse plugin is used to generate eclipse projects for a set of modules:
mvn eclipse:eclipse

After which the modules can be imported into an eclipse workspace. A useful feature of the plugin is the ability to download associated source code for third party dependencies. This is done with the downloadSources ag:

18

Chapter 5. Maven Guide

GeoServer Developer Manual, Release 2.0.2

mvn -DdownloadSources eclipse:eclipse

Warning: The rst time you enable the downloadSources ag the build will take a long time as it will attempt to download the sources for every single library GeoServer depends on.

5.9 Building the web module


When the web module is installed, it does so with a particular conguration built in. By default this is the minimal conguration. However this can be customized to build in any conguration via the configId and configDirectory ags. For example:
mvn clean install -DconfigId=release -DconfigDirectory=/home/jdeolive/geoserver_1.7.x/data

The above command builds the web module against the release conguration that is shipped with GeoServer. The configId is the name of the conguration directory to include, and the configDirectory is the parent directory of the conguration directory to include. The configDirectory can either be specied as an absolute path like in the above example, or it can be specied relative to the web module itself:
mvn clean install -DconfigId=release -DconfigDirectory=../../../data

The above command does the same as the rst, however references the congDirectory relative to the web module. This path, ../../../data, can be used if the GeoServer checkout has the standard layout.

5.10 Running the web module with Jetty


The maven jetty plugin can be used to run modules which are web based in an embedded Jetty container:
cd geoserver_1.7.x/src/web mvn jetty:run

Note: This command must be run from the web module, it will fail if run from elsewhere. The above command will run GeoServer with the built in data directory. To specify a different data directory the GEOSERVER_DATA_DIR ag is used:
mvn -DGEOSERVER_DATA_DIR=/path/to/datadir jetty:run

5.9. Building the web module

19

GeoServer Developer Manual, Release 2.0.2

20

Chapter 5. Maven Guide

CHAPTER

SIX

ECLIPSE GUIDE
A reference for developing GeoServer with Eclipse. Importing modules Running and debugging Setting the data directory Changing the default port for Jetty Conguring JNDI resources in Jetty Eclipse preferences Code formatting Code templates Text editors Compiler

6.1 Importing modules


See the Eclipse section of the Maven Guide.

6.2 Running and debugging


Run or debug the class org.geoserver.web.Start in the web-app module. The steps to do so are detailed in the Quickstart.

6.2.1 Setting the data directory


If unset, GeoServer will default to the minimal directory inside of the web-app module for its data directory. To change this: 1. Open Debug Configurations... from the Eclipse menu

21

GeoServer Developer Manual, Release 2.0.2

2. Select the Start conguration, select the Arguments panel and specify the -DGEOSERVER_DATA_DIR parameter, setting it to the absolute path of the data directory

6.2.2 Changing the default port for Jetty


If unset, Jetty will default to port 8080. To change this: 1. Open the Arguments panel of the Start conguration as described in the above section 2. Specify the -Djetty.port parameter, setting it to the desired port

22

Chapter 6. Eclipse Guide

GeoServer Developer Manual, Release 2.0.2

6.2.3 Conguring JNDI resources in Jetty


JNDI resources such as data sources can be congured by supplying a Jetty server conguration le named in the system property jetty.config.file, specied as a VM argument in the Arguments panel of the launch conguration for Start. The path to the conguration le is relative to the root of the web-app module, in which the launch conguration runs. For example:
-Djetty.config.file=../../../../../settings/jetty.xml

The following Jetty server conguration le congures a JNDI data source jdbc/demo that is a connection pool for an Oracle database:

<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/conf <Configure class="org.mortbay.jetty.Server"> <New class="org.mortbay.jetty.plus.naming.Resource"> <Arg>jdbc/demo</Arg> <Arg> <New class="org.apache.commons.dbcp.BasicDataSource"> <Set name="driverClassName">oracle.jdbc.driver.OracleDriver</Set> <Set name="url">jdbc:oracle:thin:@oracle.example.com:1521:demodb</Set> <Set name="username">claudius</Set> <Set name="password">s3cr3t</Set> <Set name="maxActive">20</Set> <Set name="maxIdle">10</Set> <Set name="minIdle">0</Set> <Set name="maxWait">10000</Set> <Set name="minEvictableIdleTimeMillis">300000</Set> <Set name="timeBetweenEvictionRunsMillis">300000</Set> <Set name="numTestsPerEvictionRun">20</Set>

6.2. Running and debugging

23

GeoServer Developer Manual, Release 2.0.2

<Set name="poolPreparedStatements">true</Set> <Set name="maxOpenPreparedStatements">100</Set> <Set name="testOnBorrow">true</Set> <Set name="validationQuery">SELECT SYSDATE FROM DUAL</Set> </New> </Arg> </New> </Configure>

Jetty does not mandate a reference-ref in GeoServer WEB-INF/web.xml, so there is no need to modify that le. No Jetty-specic information is required inside the GeoServer web-app module or data directory, so JNDI resources can be tested under Jetty for later deployment under Tomcat. See also the tutorial Setting up a JNDI connection pool with Tomcat in the GeoServer User Manual.

6.3 Eclipse preferences


6.3.1 Code formatting
1. Download http://svn.osgeo.org/geotools/trunk/build/eclipse/formatter.xml 2. Navigate to Java, Code Style, Formatter and click Import...

3. Select the formatter.xml le downloaded in step 1 4. Click Apply

24

Chapter 6. Eclipse Guide

GeoServer Developer Manual, Release 2.0.2

6.3.2 Code templates


1. Download http://svn.osgeo.org/geotools/trunk/build/eclipse/codetemplates.xml 2. Navigate to Java, Code Style, Formatter and click Import...

6.3. Eclipse preferences

25

GeoServer Developer Manual, Release 2.0.2

3. Select the formatter.xml le downloaded in step 1 4. Click Apply

6.3.3 Text editors


1. Navigate to General, Editors, Text Editors 2. Check Insert spaces for tabs 3. Check Show print margin and set Print margin column to 100 4. Check Show line numbers 5. Check Show whitespace characters (optional) Note: Showing whitespace characters can help insure that unecessary whitespace is not unintentionaly comitted.

6. Click Apply

26

Chapter 6. Eclipse Guide

GeoServer Developer Manual, Release 2.0.2

6.3.4 Compiler
1. Navigate to Java, Compiler, Building 2. Expand Output folder and add .svn/ to the list of Filtered resources

3. Click Apply

6.3. Eclipse preferences

27

GeoServer Developer Manual, Release 2.0.2

28

Chapter 6. Eclipse Guide

CHAPTER

SEVEN

PROGRAMMING GUIDE
7.1 OWS Services
This section provides an overview of how RESTful services work in GeoServer.

7.1.1 OWS Services Overview


TBA

7.1.2 Implementing a simple OWS service


This section explains How to Create a Simple GeoServer OWS service for Geoserver using the following scenario. The service should supply a capabilities document which advertises a single operation called sayHello. The result of a sayHello operation is the simple string Hello World. Contents Implementing a simple OWS service Setup Creating the Plug-in Trying it Out * Alternative 1: Bundling with Web Module * Alternative 2: Running from GeoServer Source

Setup The rst step in creating our plug-in is setting up a maven project for it. The project will be called hello. 1. Create a new directory called hello anywhere on your le system. 2. Add a maven pom called pom.xml to the hello directory:

<?xml version="1.0" encoding="ISO-8859-1"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instan xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion>

29

GeoServer Developer Manual, Release 2.0.2

<!-- set parent pom to community pom --> <parent> <groupId>org.geoserver</groupId> <artifactId>community</artifactId> <version>2.0.1</version> </parent> <groupId>org.geoserver</groupId> <artifactId>hello</artifactId> <packaging>jar</packaging> <version>1.0</version> <name>Hello World Service Module</name> <!-- declare depenency on geoserver main --> <dependencies> <dependency> <groupId>org.geoserver</groupId> <artifactId>main</artifactId> <version>2.0.1</version> </dependency> </dependencies> <repositories> <repository> <id>opengeo</id> <name>opengeo</name> <url>http://repo.opengeo.org</url> </repository> </repositories> </project>

1. Create a java source directory, src/main/java under the hello directory:


hello/ + pom.xml + src/ + main/ + java/

Creating the Plug-in A plug-in is a collection of extensions realized as spring beans. In this example the extension point of interest is a HelloWorld POJO (Plain Old Java Object). 1. Create a class called HelloWorld:
import import import import java.io.IOException; javax.servlet.ServletException; javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletResponse;

public class HelloWorld { public HelloWorld() { // Do nothing

30

Chapter 7. Programming Guide

GeoServer Developer Manual, Release 2.0.2

} public void sayHello(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getOutputStream().write( "Hello World".getBytes() ); } }

The service is relatively simple. It provides a method sayHello(..) which takes a HttpServletRequest, and a HttpServletResponse. The parameter list for this function is automatically discovered by the org.geoserver.ows.Dispatcher. 1. Create an applicationContext.xml declaring the above class as a bean.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd <beans> <!-- Spring will reference the instance of the HelloWorld class by the id name "helloService" --> <bean id="helloService" class="HelloWorld"> </bean> <!-- This creates a Service descriptor, which allows the org.geoserver.ows.Dispatcher to locate it. --> <bean id="helloService-1.0.0" class="org.geoserver.platform.Service"> <!-- used to reference the service in the URL --> <constructor-arg index="0" value="hello"/> <!-- our actual service POJO defined previously --> <constructor-arg index="1" ref="helloService"/> <!-- a version number for this service --> <constructor-arg index="2" value="1.0.0"/> <!-- a list of functions for this service --> <constructor-arg index="3"> <list> <value>sayHello</value> </list> </constructor-arg> </bean> </beans>

At this point the hello project should look like the following:
hello/ + pom.xml + src/ + main/ + java/ + HelloWorld.java + applicationContext.xml

Trying it Out 1. Install the hello module: 7.1. OWS Services 31

GeoServer Developer Manual, Release 2.0.2

[hello]% mvn install [hello]% mvn install

[INFO] Scanning for projects... [INFO] ---------------------------------------------------------------------------[INFO] Building Hello World Service Module [INFO] task-segment: [install] [INFO] ---------------------------------------------------------------------------[INFO] [resources:resources] [INFO] Using default encoding to copy filtered resources. [INFO] [compiler:compile] [INFO] Compiling 1 source file to /home/ak/geoserver/community/hello/target/classes [INFO] [resources:testResources] [INFO] Using default encoding to copy filtered resources. [INFO] [compiler:testCompile] [INFO] No sources to compile [INFO] [surefire:test] [INFO] No tests to run. [INFO] [jar:jar] [INFO] Building jar: /home/ak/geoserver/community/hello/target/hello-1.0.jar [INFO] [jar:test-jar {execution: default}] [WARNING] JAR will be empty - no content was marked for inclusion! [INFO] Building jar: /home/ak/geoserver/community/hello/target/hello-1.0-tests.jar [INFO] [install:install] [INFO] Installing /home/ak/geoserver/community/hello/target/hello-1.0.jar to /home/ak/.m2/repository/ [INFO] Installing /home/ak/geoserver/community/hello/target/hello-1.0-tests.jar to /home/ak/.m2/repos [INFO] -----------------------------------------------------------------------[INFO] BUILD SUCCESSFUL [INFO] -----------------------------------------------------------------------[INFO] Total time: 6 seconds [INFO] Finished at: Fri Sep 21 14:52:31 EDT 2007 [INFO] Final Memory: 27M/178M [INFO] -----------------------------------------------------------------------

1. Copy target/hello-1.0.jar into the WEB-INF/lib directory of your GeoServer install 2. Restart GeoServer 3. Visit http://<host>/geoserver/ows?request=sayHello&service=hello&version=1.0.0 request the method we dened in our service service the name we passed to the Service descriptor in the applicationContext.xml version the version we passed to the Service descriptor in the applicationContext.xml

Alternative 1: Bundling with Web Module


An alternative is to declare a dependency from the web module on the new plugin project. 1. Install the hello module as above. 2. Edit web/pom.xml and add the following dependency:
<dependency> <groupId>org.geoserver</groupId>

32

Chapter 7. Programming Guide

GeoServer Developer Manual, Release 2.0.2

<artifactId>hello</artifactId> <version>1.0</version> </dependency>

1. Install and run the web module


[web] mvn install jetty:run

1. Visit http://localhost:8080/geoserver/ows?request=sayHello&service=hello&version=1.0.0

Alternative 2: Running from GeoServer Source


As an alternative to trying the plugin: 1. Install the hello module 2. Change directory to the web module 3. Install the web module 4. Copy <hello module>/target/hello-1.0.jar to <web module>/target/geoserver/WEB-INF/lib:
[/dev/geoserver/web]% cp ~/hello/target/hello-1.0.jar target/geoserver/WEB-INF/lib

1. Run the exploded war with Jetty:


[/dev/geoserver/web]% mvn jetty6:run-exploded

1. Visit http://localhost:8080/geoserver/ows?request=sayHello&service=hello&version=1.0.0 7.1. OWS Services 33

GeoServer Developer Manual, Release 2.0.2

7.2 REST Services


This section provides an overview of how RESTful services work in GeoServer.

7.2.1 Overview
GeoServer uses a library known as Restlet for all REST related functionality. Restlet is a lightweight rest framework written in Java that integrates nicely with existing servlet based applications. REST dispatching In GeoServer, all requests under the path /rest are considered a call to a restful service. Every call of this nature is handled by a rest dispatcher. The job of the dispatcher is to route the request to the appropriate end point. This end point is known as a restlet.

Restlets are loaded from the spring context, and therefore are pluggable. Restlets A restlet is the generic entity which handles calls routed by the dispatcher, and corresponds to the class org.restlet.Restlet. One can extend this class directly to implement a service endpoint. Alternatively one can extend a subclass for a specialized purpose. Namely a nder, which is described in the next section. Finders and resources Restful services are often implemented around the concept of resources. A nder is a special kind of restlet whose job is to nd the correct resource for a particular request. The resource then serves as the nal end point and handles the request. The appropriate classes from the restlet library are org.restlet.Finder and org.restlet.resource.Resource. 34 Chapter 7. Programming Guide

GeoServer Developer Manual, Release 2.0.2

Representations A representation, commonly referred to as a format, is the state of a particular state or encoding of a resource. For instance, when a request for a particular resource comes in, a representation of that resource is returned to the client.

7.2.2 Implementing a RESTful Service


This section describes how to implement a restful service in GeoServer, using a Hello World example. The service will be extremely simple and will return the text Hello World from a GET request. Prerequisites Before being able to proceed, GeoServer must be built on the local system. See the Source Code and Quickstart sections for details. Create a new module 1. Create a new module named hello_rest somewhere on the le system. 2. Add the following pom.xml to the root of the new module:

<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.xs <modelVersion>4.0.0</modelVersion> <groupId>org.geoserver</groupId> <artifactId>hello_rest</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>hello_rest</name> <dependencies> <dependency> <groupId>org.geoserver</groupId> <artifactId>rest</artifactId> <version>2.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.geoserver</groupId> <artifactId>main</artifactId> <version>2.0-SNAPSHOT</version> <classifier>tests</classifier> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>com.mockrunner</groupId> <artifactId>mockrunner</artifactId> <version>0.3.1</version>

7.2. REST Services

35

GeoServer Developer Manual, Release 2.0.2

<scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> </plugins> </build> </project>

1. Create the directory src/main/java under the root of the new module:
[hello_rest]% mkdir -p src/main/java

Create the resource class 1. The class org.geoserver.rest.AbstractResource is a convenient base class available when creating new resources. Create a new class called HelloResource in the package org.geoserver.hellorest, which extends from AbstractResource.
package org.geoserver.hellorest; import import import import import java.util.List; org.geoserver.rest.AbstractResource; org.geoserver.rest.format.DataFormat; org.restlet.data.Request; org.restlet.data.Response;

public class HelloResource extends AbstractResource { @Override protected List<DataFormat> createSupportedFormats(Request request, Response response) { return null; } }

2. The rst method to implement is createSupportedFormats(). The purpose of this method is to create mapping from an extension, to a particular format. For now the goal will be to return the text Hello World when a .txt extension is requested by the client.
import java.util.ArrayList; import org.geoserver.rest.format.StringFormat; ... @Override protected List<DataFormat> createSupportedFormats(Request request, Response response) {

36

Chapter 7. Programming Guide

GeoServer Developer Manual, Release 2.0.2

List<DataFormat> formats = new ArrayList(); formats.add(new StringFormat( MediaType.TEXT_PLAIN )); return formats; }

3. The next step is to override the handleGet() method. This method is called when a GET request is made for the resource.
@Override public void handleGet() { //get the appropriate format DataFormat format = getFormatGet(); //transform the string "Hello World" to the appropriate response getResponse().setEntity(format.toRepresentation("Hello World")); }

The above makes use of the getFormatGet() method, whose purpose is to determine the extension being requested by the client, and look up the appropriate format for it. In this case when the client requests the .txt extension, the StringFormat setup in the previous step will be found. Create the application context 1. The next step is to create an application context that tells GeoServer about the resource created in the previous section. Create the directory src/main/resources under the root of the hello_rest module:
[hello_rest]% mkdir src/main/resources

2. Add the following applicationContext.xml le to the src/main/resources directory under the root of the hello_rest module.

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-bea <beans> <bean id="hello" class="org.geoserver.hellorest.HelloResource"/> <bean id="helloMapping" class="org.geoserver.rest.RESTMapping"> <property name="routes"> <map> <entry> <key><value>/hello.{format}</value></key> <value>hello</value> </entry> </map> </property> </bean> </beans>

There are two things to note above. The rst is the hello bean which is an instance of the HelloResource class created in the previous section. The second is the helloMapping bean, which denes a template for the uri in which the resource will be accessed. The above mapping species that the resource will be located at /rest/hello.{format} where format is the representation being requested by the client. As implemented hello.txt is the only supported representation.

7.2. REST Services

37

GeoServer Developer Manual, Release 2.0.2

Test 1. Create the directory /src/test/java under the root of the hello_rest module:
[hello_rest]% mkdir -p src/test/java

2. Create a new test class called HelloResourceTest in the package org.geoserver.hellorest, which extends from org.geoserver.test.GeoServerTestSupport:
package org.geoserver.hellorest; import org.geoserver.test.GeoServerTestSupport; public class HelloResourceTest extends GeoServerTestSupport { public void test() throws Exception { } }

3. Add a statement which makes a GET request for /rest/hello.txt and asserts it is equal to the string Hello World:
public void test() throws Exception { assertEquals( "Hello World", getAsString("/rest/hello.txt")); }

4. Build and test the hello_test module:


[hello_rest]% mvn install

7.2.3 Implementing a RESTful Service with Maps


The previous section showed how to implement a very simple restful service. This section will show how to make use of some existing base classes in order to save time when supporting additional formats for representing resources. The class used is org.geoserver.rest.MapResource. The idea with MapResource is that a resource is backed by a data structure contained by a java.util.Map. With this map, the MapResource class can automatically create representations of the resource in either XML or JSON. Prerequisites This section builds off the example in the previous section Implementing a RESTful Service. Create a new resource class 1. Create a new class called HelloMapResource in the package org.geoserver.hellorest, which extends from MapResource:
package org.geoserver.hellorest; import java.util.Map; import org.geoserver.rest.MapResource;

38

Chapter 7. Programming Guide

GeoServer Developer Manual, Release 2.0.2

public class HelloMapResource extends MapResource { @Override public Map getMap() throws Exception { return null; } }

2. The rst method to implement is getMap(). The purpose of this method is to create a map based data structure which represents the resource. For now a simple map will be created with a single key message, containing the Hello World string:
@Override public Map getMap() throws Exception { HashMap map = new HashMap(); map.put( "message", "Hello World"); return map; }

Update the application context 1. The next step is to update an application context and tell GeoServer about the new resource created in the previous section. Update the applicationContext.xml le so that it looks like the following:

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-bea <beans> <bean id="hello" class="org.geoserver.hellorest.HelloResource"/> <bean id="helloMap" class="org.geoserver.hellorest.HelloMapResource"/> <bean id="helloMapping" class="org.geoserver.rest.RESTMapping"> <property name="routes"> <map> <entry> <key><value>/hello.{format}</value></key> <!--value>hello</value--> <value>helloMap</value> </entry> </map> </property> </bean> </beans>

There are two things to note above. The rst is the addition of the helloMap bean. The second is a change to the helloMapping bean, which now maps to the helloMap bean, rather than the hello bean. Test 1. Create a new test class called HelloMapResourceTest in the package org.geoserver.hellorest, which extends from org.geoserver.test.GeoServerTestSupport:

7.2. REST Services

39

GeoServer Developer Manual, Release 2.0.2

package org.geoserver.hellorest; import org.geoserver.test.GeoServerTestSupport; public class HelloMapResourceTest extends GeoServerTestSupport { }

2. Add a test named testGetAsXML() which makes a GET request for /rest/hello.xml:
... import org.w3c.dom.Document; import org.w3c.dom.Node; ... public void testGetAsXML() throws Exception { //make the request, parsing the result as a dom Document dom = getAsDOM( "/rest/hello.xml" ); //print out the result print(dom); //make assertions Node message = getFirstElementByTagName( dom, "message"); assertNotNull(message); assertEquals( "Hello World", message.getFirstChild().getNodeValue() ); }

3. Add a second test named testGetAsJSON() which makes a GET request for /rest/hello.json:
... import net.sf.json.JSON; import net.sf.json.JSONObject; ... public void testGetAsJSON() throws Exception { //make the request, parsing the result into a json object JSON json = getAsJSON( "/rest/hello.json"); //print out the result print(json); //make assertions assertTrue( json instanceof JSONObject ); assertEquals( "Hello World", ((JSONObject)json).get( "message" ) ); }

4. Build and test the hello_test module:


[hello_rest]% mvn clean install -Dtest=HelloMapResourceTest

40

Chapter 7. Programming Guide

GeoServer Developer Manual, Release 2.0.2

7.2.4 Implementing a RESTful Service with Reection


The previous section showed how to save some effort when implementing a RESTful service by taking advantage of the MapResource base class. This section will show how to make use of a different base class, but for a similar purpose. The class used is org.geoserver.rest.ReflectiveResource. The idea with ReflectiveResource is that a resource is backed by an arbitrary object. The ReflectiveResource class uses reection to automatically create representations of the resource as XML or JSON. Prerequisites This section builds off the example in the previous section Implementing a RESTful Service with Maps. Create a new java bean 1. The use of ReflectiveResource requires we have an underlying object to to work with. Create a class named Hello in the package org.geoserver.hellorest:
package org.geoserver.hellorest; public class Hello { String message; public Hello( String message ) { this.message = message; } public String getMessage() { return message; } }

Create a new resource class 1. Create a new class called HelloReflectiveResource in the package org.geoserver.hellorest, which extends from ReflectiveResource:
package org.geoserver.hellorest; import org.geoserver.rest.ReflectiveResource; public class HelloReflectiveResource extends ReflectiveResource { @Override protected Object handleObjectGet() throws Exception { return null; } }

2. The rst method to implement is handleObjectGet(). The purpose of this method is to return the underlying object representing the resource. In this case, an instance of the Hello class created in the previous step.

7.2. REST Services

41

GeoServer Developer Manual, Release 2.0.2

@Override protected Object handleObjectGet() throws Exception { return new Hello( "Hello World" ); }

Update the application context 1. The next step is to update an application context and tell GeoServer about the new resource created in the previous section. Update the applicationContext.xml le so that it looks like the following:

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-bea <beans> <bean id="hello" class="org.geoserver.hellorest.HelloResource"/> <bean id="helloMap" class="org.geoserver.hellorest.HelloMapResource"/> <bean id="helloReflective" class="org.geoserver.hellorest.HelloReflectiveResource"/> <bean id="helloMapping" class="org.geoserver.rest.RESTMapping"> <property name="routes"> <map> <entry> <key><value>/hello.{format}</value></key> <!--value>hello</value--> <!--value>helloMap</value--> <value>helloReflective</value> </entry> </map> </property> </bean> </beans>

There are two things to note above. The rst is the addition of the helloReflective bean. The second is a change to the helloMapping bean, which now maps to the helloReflective bean. Test 1. Create a new test class called HelloReflectiveResourceTest in the package org.geoserver.hellorest, which extends from org.geoserver.test.GeoServerTestSupport:
package org.geoserver.hellorest; import org.geoserver.test.GeoServerTestSupport; public class HelloReflectiveResourceTest extends GeoServerTestSupport { }

2. Add a test named testGetAsXML() which makes a GET request for /rest/hello.xml:
... import org.w3c.dom.Document;

42

Chapter 7. Programming Guide

GeoServer Developer Manual, Release 2.0.2

import org.w3c.dom.Node; ... public void testGetAsXML() throws Exception { //make the request, parsing the result as a dom Document dom = getAsDOM( "/rest/hello.xml" ); //print out the result print(dom); //make assertions Node message = getFirstElementByTagName( dom, "message"); assertNotNull(message); assertEquals( "Hello World", message.getFirstChild().getNodeValue() ); }

3. Add a second test named testGetAsJSON() which makes a GET request for /rest/hello.json:
... import net.sf.json.JSON; import net.sf.json.JSONObject; ... public void testGetAsJSON() throws Exception { //make the request, parsing the result into a json object JSON json = getAsJSON( "/rest/hello.json"); //print out the result print(json); //make assertions assertTrue( json instanceof JSONObject ); JSONObject hello = ((JSONObject) json).getJSONObject( "org.geoserver.hellorest.Hello" ); assertEquals( "Hello World", hello.get( "message" ) ); }

4. Build and test the hello_test module:


[hello_rest]% mvn clean install -Dtest=HelloMapReflectiveResourceTest

7.3 Web User Interface


7.3.1 Overview
GeoServer uses a web application framework known as Wicket for its user interface. Wicket differs from most Java web frameworks in that it is component based rather than JSP template based. This makes Wicket a more natural web framework for many Java programmers who are more familiar with Swing programming than web programming.

7.3. Web User Interface

43

GeoServer Developer Manual, Release 2.0.2

Plug-ins Because of its component based nature Wicket components can be loaded from the classpath. Which means that web applications can be built in a modular fashion, rather than in a monolithic fashion. GeoServer takes this concept one step further to provide a pluggable user interface, in which Wicket components can be plugged in via Spring and the regular GeoServer plug-in mechanism. Each component that is plugged in is described by a component descriptor. A component descriptor is an instance of the org.geoserver.web.ComponentInfo class:
public abstract class ComponentInfo<C extends Component> implements Serializable { /** * the id of the component */ String id; /** * the title of the component */ String title; /** * The description of the component */ String description; /** * the class of the component */ Class<C> componentClass; }

A ComponentInfo instance contains meta information about the component being plugged in such as its title and description, as well as the class which implements the component. Each subclass of ComponentInfo represents a specic extension point. For instance the class org.geoserver.web.MenuPageInfo represents the extension point for main pages, ie pages that are linked to from the main menu of the application.

7.3.2 Implementing a Wicket UI Extension


This section describes how to implement an extension to the GeoServer Wicket user interface. The extension will be extremely simple and will be a basic page that is linked from the main menu and displays the message Hello World. Prerequisites Before being able to proceed, GeoServer must be built on the local system. See the Source Code and Quickstart sections for details. Create a new module 1. Create a new module named hello_web somewhere on the le system 2. Add the following pom.xml to the root of the new module:

44

Chapter 7. Programming Guide

GeoServer Developer Manual, Release 2.0.2

<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.xs <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.geoserver</groupId> <artifactId>web2</artifactId> <version>2.0-SNAPSHOT</version> </parent> <groupId>org.geoserver</groupId> <artifactId>hello_web</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>hello_web</name> <dependencies> <dependency> <groupId>org.geoserver.web</groupId> <artifactId>web-core</artifactId> <version>2.0-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> </plugins> </build> </project>

3. Create the directory src/main/java under the root of the new module:
[hello_web]% mkdir -p src/main/java

Create the page class 1. The class org.geoserver.web.GeoServerBasePage is the base class for all pages in GeoServer. Create a new class called HelloPage in the package org.geoserver.helloweb, which extends from GeoServerBasePage:
package org.geoserver.helloweb; import org.geoserver.web.GeoServerBasePage; public class HelloPage extends GeoServerBasePage {

7.3. Web User Interface

45

GeoServer Developer Manual, Release 2.0.2

2. The rst task is to implement the constructor. In Wicket a page or component builds itself in its constructor. This page is basic and will simply create a label which has the value Hello World!:
import org.apache.wicket.markup.html.basic.Label; ... public HelloPage() { add( new Label( "hellolabel", "Hello World!") ); }

In the above code, an instance of Label is created. The rst argument to its constructor is the component id. In Wicket every component must have an id. In the next section this id will be used to bind the component to its HTML presentation. The second argument to the Label constructor is the value of the world, in this case the string Hello World! Create the page presentation 1. With the page completed, the next step is to create the HTML presentation for the page. To do this create a le named HelloPage.html in the same directory as the HelloPagejava class:
<html> <body> <wicket:extend> <div wicket:id="hellolabel"></div> </wicket:extend> </body> </html>

There are few things to note about the HTML. The rst is the use of the <wicket:extend> element. This tells wicket that HelloPage is an extension of another page, in this case GeoServerBasePage, and it should inherit presentation from that page. The second thing to note is the attribute wicket:id on the <div> element. This is what binds the <div> tag to the Label component created in the previous section. The value of wicket:id must match the id given to the component, in this case hellolabel. Create the i18n le With Wicket (and any web application framework), any string that appears in the web application should be interationalized. In GeoServer, this is performed by creating an internationalization (i18n) le named GeoServerApplication.properties. 1. Create the (i18n) le GeoServerApplication.properties in the src/main/java directory:
HelloPage.page.title=Hello HelloPage.page.description=A page to say hello

The above i18n le declares two keys, one for the title of the page and one for the description of the page.

46

Chapter 7. Programming Guide

GeoServer Developer Manual, Release 2.0.2

Create the application context 1. The nal step is to create an application context which tells GeoServer about the page created in the previous section. Create the directory src/main/resources under the root of the hello_web module:
[hello_web]% mkdir src/main/resources

2. Add the following applicationContext.xml le to the src/main/resources directory, under the root of the hello_rest module:

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-bea <beans> <bean id="helloPage" class="org.geoserver.web.MenuPageInfo"> <property name="id" value="helloPage"/> <property name="titleKey" value="HelloPage.page.title"/> <property name="descriptionKey" value="HelloPage.page.description"/> <property name="componentClass" value="org.geoserver.helloweb.HelloPage"/> </bean> </beans>

The above bean declaration declares an instance of the MenuPageInfo class which is a descriptor for pages linked from the main page of the GeoServer web application. The property titleKey is the title of the page and it receives the value of the title i18n key created in the previous section. Similar for the the descriptionKey property. Test the extension At this point, the hello_web module should look like the following:
hello_web/ pom.xml src/main/java applicationContext.xml GeoServerApplication.properties org/geoserver/helloweb/ HelloPage.java HelloPage.html

1. Build the hello_web module:


[hello_web]% mvn install

2. Copy the hello_web-1.0-SNAPSHOT.jar le from the hello_web/target directory into the WEB-inf/lib directory of a GeoServer installation:

[hello_web]% cp target/hello-1.0-SNAPSHOT.jar /home/bob/geoserver-2.0/webapps/geoserver/WEB-INF/

3. Start or restart GeoServer 4. Navigate to http://localhost:8080/geoserver/web Upon success a link titled Hello should appear in the menu on the left side of the main GeoServer page. Following the link brings up the HelloPage

7.3. Web User Interface

47

GeoServer Developer Manual, Release 2.0.2

7.4 Wicket Development In GeoServer


This page explains the steps to follow in creating a page for the Wicket-based conguration interface in GeoServer 2. For more information on Wicket, check out the project site at http://wicket.apache.org/.

7.4.1 Adding a Page


In Wicket, each page has one corresponding Java class. To add a page, you need to create a new class that extends org.geoserver.web.GeoServerBasePage. You will also want to create a link somewhere that brings the user to your page. (In general, Wicket pages do not have reliable URLs, so you must explicitly create a link in an existing page and let Wicket generate the proper URL.) In the case where your class does not require arguments to its constructor, you can insert a link using Spring. Creating links in Spring requires that your page link text be internationalizable. Well discuss internationalization in more depth later. The simplest possible Wicket extension for GeoServer involves 3 les. There is a Java class denition (this would be in src/main/java/org/geoserver/web/example/MyPage.java).

48

Chapter 7. Programming Guide

GeoServer Developer Manual, Release 2.0.2

package org.geoserver.web.example; import org.geoserver.web.GeoServerBasePage; public class MyPage extends GeoServerBasePage{ // We will fill in the rest later, for now the page can just be blank }

There would also need to be a Spring application context document (src/main/java/applicationContext.xml):


<bean class="org.geoserver.web.MenuPageInfo" id="myPageLink"> <!-- An internal identifier for the link component --> <property name="id" value="mypage"/> <!-- The i18n key for the link title --> <property name="titleKey" value="org.geoserver.web.example.MyPage.page.title"/> <!-- The i18n key for a longer description of the page --> <property name="descriptionKey" value="org.geoserver.web.example.MyPage.page.description"/> <!-- The fully qualified name of the page class --> <property name="componentClass" value="org.geoserver.web.example.MyPage"/> <!-- Optional, an icon to display alongside the link. --> <property name="icon" value="imgs/some-image.png"/> <!-- Optional, the category in which the link should be grouped. --> <property name="category" ref="someCategory"/> <!-- Optional, a key used to order the links in the menu. --> <property name="order" value="100"/> </bean>

The third necessary le is the default dictionary src/main/java/GeoServerApplication.properties:

for

internationalized

strings,

at

org.geoserver.web.example.MyPage.page.title=My Example Page org.geoserver.web.example.MyPage.page.description=An example page for developers trying to extend the

If you create a jar with these three les and add it to the GeoServer classpath, you should see the new link in the left-hand menu.

7.4.2 Adding to a Page


At this point youve added a page to the UI, but its not very interesting. In Wicket, pages provide their content with an HTML le stored with the same name as the Java code except for the extension. There are a few details about these les that differ from standard HTML; for one thing, they must be valid XML for Wickets parser to work. In addition, Wicket uses a few special elements to specify where the Java code should hook into the HTML. The following are used quite extensively in the GeoServer administrative console.

7.4. Wicket Development In GeoServer

49

GeoServer Developer Manual, Release 2.0.2

Wicket Element <foo wicket:id="bar"></foo> <wicket:child/>

Purpose A wicket:id attribute tells Wicket the name to be used for an element when attaching Wicket Components Requires no contents, but species that classes extending this page can insert content at this position. <wicket:extend></wicket:extend> Species that the enclosed content will be inserted into a parent page at the point indicated by <wicket:child/> <wicket:panel></wicket:panel>imilar to wicket:extend, but used in creating custom components S rather than extending pages. <wicket:head></wicket:head> Indicates a section (like a CSS or JavaScript include) that should be added to the header of pages that include this markup (can be used for pages or panels). <wicket:link></wicket:link> Encloses sections in which Wicket will rewrite links to pages, CSS les, and other resources that it manages. (This lets you refer to resources using paths relative to the Java source and not the rendered HTML.) <wicket:message Tells Wicket to look up a string in the internationalization database and key="i18nKey"> Default replace the provided text if one is found. Text </wicket:message> Wicket provides quite a few components, of which several can be seen in the Wicket Component Reference. In general, Wicket components require a Model object which handles the getting, setting, and conversion to/from String of the value associated with a component. For the purposes of this example, we will focus on one of the simplest, the Label, which simply replaces the contents of the element it is bound to with a value provided at runtime. Continuing the example from above, we can pass a String to the Labels constructor and it is transparently converted to a Model:
package org.geoserver.web.example; import org.geoserver.web.GeoServerBasePage; import org.apache.wicket.markup.html.basic.Label; public class MyPage extends GeoServerBasePage{ public MyPage(){ add(new Label("label", "Hello World")); } }

The corresponding HTML source would live at src/main/java/org/geoserver/web/example/MyPage.html:

<html> <head></head> <body> <wicket:extend> Greetings, GeoServer User! My message for you is <span wicket:id="label"> thanks for using GeoSer </wicket:extend> </body> </html>

Of course, there are much more complicated (and useful) things we can do with Wicket, but this example demonstrates the most common usage; just adding some behavior to an HTML element.

7.4.3 Adding a Link Outside the Navigation Menu


Of course, we cant have everything in the sidebar menu; for one thing, it denes only a static set of links while GeoServer is bound to contain lots of resources that vary from conguration to conguration. For another, some pages need to have arguments to their constructors. If you want to add a custom link to some page, you can use

50

Chapter 7. Programming Guide

GeoServer Developer Manual, Release 2.0.2

a Wicket Link component and customize the onClick behavior to call the appropriate constructor. (You can use setResponsePage in other methods that handle user input as well, such as on form submits. Check the Wicket documentation for more information.) An example:
//... import org.apache.wicket.markup.html.link.Link; //... add(new Link("link"){ public void onClick(){ setResponsePage(new MyPage()); } });

The corresponding HTML would look like:


Follow this lovely <a href="#" wicket:id="link">link</a>.

7.4.4 Making it Internationalizable


In the GeoServer UI, we use a customized resource lookup utility within Wicket to allow any module to provide resource strings. All you need to do is include your I 18 N (Internationalization) values in a Java Properties le named GeoServerApplication.properties in the root of your src directory (ie, project/src/main/java/GeoServerApplication.properties). The <wicket:message> element makes it quite easy to make text internationalizable, but in the event that you need to insert a value into a sentence at a position that changes dependent on the language, youll need to use something more complicated. In Wicket, I 18 N value strings can dene parameters which provide the ability to place dynamic values into internationalized strings. See Also: http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/model/StringResourceModel.html details. for

7.4.5 Adding Resources


Often in HTML, you will need to include assets such as CSS les, JavaScript libraries, or images to include in your page. Wicket allows you to specify URLs to these relative to your Java source le, using relative paths enclosed in <wicket:link> tags. Wicket will rewrite these links at runtime to use the correct path. However, such resources are not inherited from parent classes, so if you need to include a resource in multiple packages you will need to extract the functionality that uses it to a new class that can be shared between the two. See the XMLEditor component in the core module of GeoServers UI for an example of a component that does this.

7.4.6 UI Design Guidelines


A brief listing of UI design guidelines for Wicket pages in GeoServer follows. Forms In forms, group each eld as an item in an unordered list with a label and a form eld. For radio buttons and checkboxes, the label should come after the eld; for all others the label should precede the eld. For example:

7.4. Wicket Development In GeoServer

51

GeoServer Developer Manual, Release 2.0.2

<ul> <li> <label for="foo"><wicket:message key="foo"> Foo </wicket:message> <input wicket:id="foo" type="text"></input> </li> </ul>

Avoid requiring special knowledge from the user. For example, where a list of values is required, provide a widget that allows manipulating the list one element at a time rather than expecting a commaseparated list of values. Custom Components We recommend creating a reusable Wicket component for any complex values that might need to be edited by users, such as a bounding box or a list of free strings. By extracting this into a component, it is much simpler to provide consistent, rich editing for users.

7.5 Extension Points 7.6 WPS design guide


This guide serves as an introduction to the WPS module. As such, it does not contain: a primer to the WPS protocol, that can be found in the WPS specication (the module implements the WPS 1.0 specication). it does not repeat again what can be already found in the classes javadocs it does not explain how to implement a OWS service using the GeoServer OWS framework, that is left to its dedicated guide. In short, it provides a global vision of how the module ts togheter, leaving the details to other information sources.

7.6.1 General architecture


Note: We really need to publish the Javadocs somewhere so that this document can link to them The module is based on the usual GeoServer OWS framework application: a set of KVP parsers and KVP readers to parse the HTTP GET requests, org.geoserver.wps.kvp package found in the

a set of XML parsers to parse the HTTP POST requests, found int the org.geoserver.wps.xml and org.geoserver.wps.xml.v1_0_0 a service object interface and implementations responding to the various WPS methods, in particular org.geoserver.wps.DefaultWebProcessingService, which in turn delegates most of the work to the GetCapabilities, DescribeProcess and ExecuteProcess classes a set of output transformers taking the results generated by DefaultWebProcessingService and turning them into the appropriate response (usually, XML). You can nd some of those in the org.geoserver.wps.response package, whilst some others are generic ones that have been parametrized and declared in the Spring context (see the applicationContext.xml le). The module uses extensively the following GeoTools modules:

52

Chapter 7. Programming Guide

GeoServer Developer Manual, Release 2.0.2

net.opengis.wps which contains EMF models of the various elements and types described in the WPS schemas. Those objects are usually what ows between the KVP parsers, XML decoders, the service implementation, and the output transformers gt-xsd-wps and gt-xsd, used for all XML encoding and decoding needs gt-process that provides the concept of a process, with the ability to self describe its inputs and outputs, and of course execute and produce results

7.6.2 The processes


The module relies on gt-process SPI based plugin mechanism to lookup and use the processes available in the classpath. Implementing a new process boils down to: creating a ProcessFactory implementation creating one or more Process implementations registering the ProcessFactory in SPI by adding the factory META-INF/services/org.geotools.process.ProcessFactory le class name in the

The WPS module shows an example of the above by bridging the Sextante API to the GeoTools process one, see the org.geoserver.wps.sextante package. This also means its possible to rely on libraries of existing processes provided they are wrapped into a GeoTools process API container.

7.6.3 Bridging between objects and I/O formats


The WPS specication is very generic. Any process can take as input pretty much anything, and return anything. It basically means WPS is a complex, XML based RPC protocol. Now, this means WPS can trade vector data, raster data, plain strings and numbers, spreadsheets or word processor and whatever else the imagination can lead one to. Also, given a single type of data, say a plain geometry, there are many useful ways to represent it: it could be GML2, or GML3, or WKT, WKB, or a one row shapele. Different clients will nd some formats easier than others to use, meaning the WPS should try to offer as many option as possible for both input and output. The classes stored in the org.geoserver.wps.ppio serve exactly this purpose: turning a representation format into an in memory object and vice versa. A new subclass of ProcessParameterIO (PPIO) is needed each time a new format for a known parameter type is desired, or when a process requires a new kind of parameter, and it then needs to be registered in the Spring contex so that ProcessParameterIO.find(Parameter, ApplicationContext) can nd it. Both the XML reader and the XML encoders do use the PPIO dynamically: the WPS document structure is made so that parameters are actually xs:Any, so bot The code providing the description of the various processes also scans the available ProcessParameterIO implementations so that each parameter can be matched with all formats in which it can be represented.

7.6.4 Implementation level


At the moment the WPS is pretty much bare bones protocol wise, it implements only the required behaviour leaving off pretty much everything else. In particulat: - GetCapabilities and DescribeProcess are supported in both GET and POST form, but Execute is implemented only as a POST request - there is no raster data I/O support there is no asynch support, no process monitoring, no output storage abilities. - there is no integration whatsoever with the WMS to visualize the results of an analysis (this will require output storage and per session catalog extensions) the vector processes are not using any kind of disk buffering, meaning everything is kept just in memory (wont scale

7.6. WPS design guide

53

GeoServer Developer Manual, Release 2.0.2

to bigger data amounts) - there is no set of demo requests nor a GUI to build a request. That is considered fundamental to reduce the time spent trying to gure out how to build a proper request so it will be tackled sooner rather than later.

7.6.5 The transmute package


The org.geoserver.wps.transmute package is an earlier attempt at doing what PPIO is doing. It is attempting to also provide a custom schema for each type of input/output, using subsetted schemas that do only contain one type (e.g., GML Point) but that has to reference the full schema denition anyways. Note: This package is a leftover, should be completely removed and replaced with PPIO usage instead. At the moment only the DescribeProcess code is using it.

54

Chapter 7. Programming Guide

CHAPTER

EIGHT

RELEASE GUIDE
This guide details the process of performing a GeoServer release.

8.1 Notify developer lists


It is good practice to notify the GeoServer developer list of the intention to make the release a few days in advance, even though the release date has been agreed upon before hand. GeoServer releases are usually made in conjunction with GeoTools releases, so the GeoTools developer list should also be notied of the associated GeoTools release a few days in advance. On the day the release is being made is it also good practice to send a warning to the list asking that developers refrain from committing until the release tag has been created.

8.2 Prerequisites
The following are necessary to perform a GeoServer release: 1. Commit access to GeoServer svn 2. Edit access to the GeoServer wiki 3. Administration rights to the GeoServer bug tracker (JIRA) 4. Write access to GeoServer Maven Repository For steps 2 through 4 above you may also ask someone on the developer list to perform the associated steps. If a parallel GeoTools release is being preformed, see the GeoTools Release Guide. Alternatively you can (nicely) ask one of the GeoTools developers to perform the release for you.

8.3 Update source code


1. Update or check out the branch to be released from. 2. Ensure that svn status yields no local modications.

55

GeoServer Developer Manual, Release 2.0.2

8.4 Update the README


1. Add an entry to release/README.txt using the following template:
GeoServer [VERSION] ( [DATE] ) ============================== [Short paragraph describing release] [List of notable features / improvements / bug fixes] The entire changelog can be found at: [link to JIRA changelog] This release is based on [GeoTools version].

Example:
GeoServer 1.7.1 (December 08, 2008) ----------------------------------The second release of the 1.7.1 series includes some great KML and Google Earth improvements, along with other new features and bug fixes. The new and note worthy for this release includes: * * * * * * KML Super Overlay and Regionating Support KML Extrude Support KML Reflector Improvements Mac OS X Installer New SQL Server DataStore Extension Improved Oracle DataStore Extension

And much more. The entire changelog can be found at : http://jira.codehaus.org/browse/GEOS/fixforversion/14502 This release is based on GeoTools 2.5.2.

Note: The xforversion number for the JIRA changelog can be found by exploring the GeoServer JIRA before or after building the changelog. See the links to the various unreleased versions. 2. Commit changes to the README:
svn commit -m "Updating README for [VERSION]" release/README.txt

8.5 Create a release tag


1. Create a tag for the release:

svn copy -m "Create tag for release [VERSION]" https://svn.codehaus.org/geoserver/[BRANCH] https

2. Checkout the release tag:

56

Chapter 8. Release Guide

GeoServer Developer Manual, Release 2.0.2

svn co https://svn.codehaus.org/geoserver/tags/[VERSION]

Warning: svn switch may also be used to switch to the release tag but caution must be taken to switch back to the branch after the release has been performed.

8.6 Update version numbers in tag


1. Upgrade the version number in the following les:
src/release/installer/win/GeoServerEXE.nsi src/release/installer/win/wrapper.conf src/release/installer/mac/GeoServer.app/Contents/Info.plist src/release/bin.xml src/release/doc.xml src/release/src.xml src/web/src/main/java/ApplicationResources* doc/en/user/source/conf.py doc/en/developer/source/conf.py

Example (using sed):


sed -i s/1.7.1/1.7.2/g src/release/installer/win/GeoServerEXE.nsi

2. Commit changes:
svn commit -m "Updated version numbers for [VERSION]" release web/src/main/java

8.7 Upgrade branch pom versions


1. Update branch (not in the newly-created tag!) pom version numbers to include the next version with a SNAPSHOT sufx:
find . -name pom.xml -exec sed -i s/[VERSION]-SNAPSHOT/[NEWVERSION]-SNAPSHOT/g {} \;

Example:
find . -name pom.xml -exec sed -i s/1.7.1-SNAPSHOT/1.7.2-SNAPSHOT/g {} \;

2. Commit changes:
svn commit -m "Upgrading pom version to [NEWVERSION]-SNAPSHOT" .

8.8 Set tag pom versions


1. Set tag pom version numbers to the correct version number (and removing the -SNAPSHOT sufx):

8.6. Update version numbers in tag

57

GeoServer Developer Manual, Release 2.0.2

find . -name pom.xml -exec sed -i s/[VERSION]-SNAPSHOT/[VERSION]/g {} \;

Example:
find . -name pom.xml -exec sed -i s/1.7.1-SNAPSHOT/1.7.1/g {} \;

2. Commit changes:
svn commit -m "Setting pom versions to [VERSION]" .

8.9 Build release artifacts


Warning: All operations for the remainder of this guide must be performed from the release tag, not the branch. 1. Compile from the root of the source tree with the following command:
mvn clean install -P release

2. Build javadocs:
mvn javadoc:javadoc

3. Build artifacts:
mvn assembly:attached

At this point the release artifacts will be located in target/release. Note: Due to an issue with the version of the maven assembly plugin currently used, the source artifact contains target directories containing compiled classes and jars for each module, which increases its size signicantly. The source artifact should be unpacked, the directories removed, and re-archived:
unzip geoserver-1.7.1-src.zip rm geoserver-1.7.1-src.zip cd geoserver-1.7.1 find . -name target -exec rm -rf {} \; cd .. zip -r geoserver-1.7.1-src.zip geoserver-1.7.1

8.10 Build documentation


Note: Building the GeoServer documentation requires the following be installed: Sphinx, version 0.6 or greater It is also helpful to have make installed, although it is not required. For Windows users a make.bat les exists that performs the same function.

58

Chapter 8. Release Guide

GeoServer Developer Manual, Release 2.0.2

8.10.1 HTML
1. Change to the root of the documentation directory, or check it out (if you dont already have it) from https://svn.codehaus.org/geoserver/tags/[VERSION]/doc 2. Change directory to doc/user. 3. Build HTML les for the User Manual. Option 1: Run the make command:
make html

Option 2: Run the sphinx-build command:


sphinx-build -b html . build/html

Note: You may need to create the build/html directory. 4. Change directory to build/html and archive its contents:
cd build/html zip -r geoserver-[VERSION]-htmldoc.zip *

5. Go back to the root of the documentation tree, and change directory to doc/developer. 6. Build HTML les for the Developer Manual. Option 1: Run the make command:
make html

Option 2: Run the sphinx-build command:


sphinx-build -b html . build/html

Note: You may need to create the build/html directory. 7. Change directory to build/html 8. Move the zip created for the user manual (in step 4) into this directory. 9. Add the contents of the current directory to the existing zip:
zip -r geoserver-[VERSION]-htmldoc.zip *

Note: When done, the zip le should contain two folders, one called user containing the HTML output for the User Manual, and one called developer containing the HTML output for the Developer Manual.

8.10.2 PDF
Note: Building PDF les from Sphinx is a two step process. First, it is necessary to create LaTeX les from Sphinx. Next, convert the LaTeX le to PDF using pdatex. Note: Building PDF les, in addition to Sphinx, requires the pdatex utility. 1. Change to the root of the documentation directory. 2. Change directory to doc/user.

8.10. Build documentation

59

GeoServer Developer Manual, Release 2.0.2

3. Build LaTeX les for the User Manual. Option 1: Run the make command:
make latex

Option 2: Run the sphinx-build command:


sphinx-build -b latex . build/latex

Note: You may need to create the build/latex directory. 4. Change directory to build/latex. 5. Convert the .tex le to .pdf:
pdflatex GeoServerUserManual.tex GeoServerUserManual.pdf

6. Go back to the root of the documentation tree, and change directory to doc/developer. 7. Build LaTeX les for the Developer Manual. Option 1: Run the make command:
make latex

Option 2: Run the sphinx-build command:


sphinx-build -b latex . build/latex

Note: You may need to create the build/latex directory. 8. Change directory to build/latex 9. Convert the .tex le to .pdf pdatex GeoServerDeveloperManual.tex GeoServerDeveloperManual.pdf 10. Move the PDF created for the User Manual into this directory. 11. Create a zip containing the two PDF les:
zip -r geoserver-[VERSION]-pdfdoc.zip *.pdf

8.11 CITE testing


1. Change directory to src/target/release and unzip the binary package:
cd target/release unzip geoserver-*-bin.zip

2. Execute the GeoServer CITE tests as described in the Cite Test Guide. 3. Unzip the war package and deploy the war in a servlet container such as Tomcat:
unzip geoserver-*-war.zip cp geoserver.war /opt/tomcat5/webapps

60

Chapter 8. Release Guide

GeoServer Developer Manual, Release 2.0.2

4. Re-run GeoServer CITE tests with the war package.

8.12 Hand testing


Start GeoServer with the release data directory and test by hand. A checklist of things to test can be found in the Release Testing Checklist.

8.13 Deploy Artifacts


Deploy artifacts to the maven repository using the following command:
mvn deploy

8.14 Build Windows installer


Note: This step requires a Windows machine. 1. Download and install NSIS. 2. Install the NSIS Access Control plugin. The simplest way to do this is to download the zip, extract the two .DLL les (AccessControl.dll and AccessControlW.dll) and copy them to the NSIS plugins directory (usually C:\Program Files\NSIS\Plugins). 3. Unzip the binary GeoServer package:
unzip geoserver-[VERSION]-bin.zip

4. Copy the les from src/release/installer/win to the root of the unpacked archive (the same directory level as the start.jar):
GeoServerEXE.nsi gs.ico header.bmp side_left.bmp splash.bmp wrapper.conf wrapper.dll wrapper.exe wrapper.jar wrapper-server-license.txt

5. Right-click on the installer script GeoServerEXE.nsi and select Compile Script. After successfully compiling the script, an installer named geoserver-[VERSION].exe will be located in the root of the unpacked archive.

8.12. Hand testing

61

GeoServer Developer Manual, Release 2.0.2

62

Chapter 8. Release Guide

GeoServer Developer Manual, Release 2.0.2

8.14. Build Windows installer

63

GeoServer Developer Manual, Release 2.0.2

8.15 Build Mac OS X installer


Note: This step requires a Macintosh machine. Change directory to src/release/installer/mac and follow the instructions in README.txt.

8.16 Release on JIRA


Note: This step requires administrative privileges in JIRA. 1. Log into GeoServer JIRA. 2. Click the Administer Project link on the left hand side of the page.

3. Click the Manage link on the right hand side of the page. 4. Find the row for the version being released and click the Release link located on the right. 5. Move back any open issues to the next version, and click the Release button.

8.17 Upload release artifacts to SourceForge


All of the artifacts generated so far need to be uploaded to the SourceForce File release System. There are various ways to do so, consult the documentation to nd out the one better suited for you. 64 Chapter 8. Release Guide

GeoServer Developer Manual, Release 2.0.2

8.17. Upload release artifacts to SourceForge

65

GeoServer Developer Manual, Release 2.0.2

The simplest way for developers working under a Unix like system is to use scp:
scp *.zip username@frs.sourceforge.net:uploads

The same can be accomplished in Windows using WinSCP.

8.18 Release on SourceForge


Note: This step requires administrative privileges in SourceForge.

8.18.1 Primary artifacts


1. Log in to SourceForge. 2. Go to the GeoServer SourceForge page. 3. Under the Project admin tab select Feature Settings. 4. Click Manage in the File Release System row

5. Click Add Release next to the GeoServer package.

6. Enter the release version and click the Create This Release button.

7. Copy the contents of the README (from previous step) into the Release Notes text box. 8. Generate the change log from JIRA (text format) and copy the contents into the Change Log text box.

66

Chapter 8. Release Guide

GeoServer Developer Manual, Release 2.0.2

9. Click the Preserve my pre-formatted text check box. 10. Click the Submit/Refresh button.

11. Scroll down to the Add Files To This Release section and check off all the primary artifacts. Warning: Be sure not to include the extension/plugin artifacts in this step! 12. Click the Add Files and/or Refresh View button. 13. Scroll down to the Edit Files In This Release section. 14. For the .dmg artifact set the Processor to i386 and the File Type to .dmg. 8.18. Release on SourceForge 67

GeoServer Developer Manual, Release 2.0.2

68

Chapter 8. Release Guide

GeoServer Developer Manual, Release 2.0.2

15. For the .exe artifacts set the Processor to i386 and the File Type to .exe. 16. For the src artifact set the Processor to Platform-Independent and the File Type to Source .zip. 17. For all other artifacts set the Processor to Platform-Independent and the File Type to .zip. Note: The processor and le type must be set one artifact at a time, clicking the the Update/Refresh button at each step.

8.18.2 Extension artifacts


Following steps from the previous section create a release of the GeoServer Extensions package consisting of all the plugin artifacts. A few things to note: The release version is the same as the primary artifact release. The Release Notes and Change Log may be omitted. Each plugin artifact is Platform-Independent and of File Type .zip.

8.19 Create a download page


1. Go to http://geoserver.org/display/GEOS/Stable and log in. Note: If creating an experimental release, navigate instead to http://geoserver.org/display/GEOS/Latest 2. Click the Add Page link under the Page Operations menu. 3. Name the page GeoServer [VERSION]. 4. Click the Select a page template link.

5. Select Download and click the Next button. 6. Fill out the elds for the following variables:
VERSION DATE JIRA_VERSION SF_RELEASE_ID

Note: The SF_RELEASE_ID is the release number assigned by SourceForge for the release created in the previous step. 7. Click the Insert Variables button.

8.19. Create a download page

69

GeoServer Developer Manual, Release 2.0.2

8. Click the Save button.

8.20 Announce the release


8.20.1 Mailing lists
Send an email to both the developers list and users list announcing the release. The message should be relatively short. The following is an example:
Subject: GeoServer 1.7.1 Released The GeoServer team is happy to announce the release of GeoServer 1.7.1. The release is available for download from: http://geoserver.org/display/GEOS/GeoServer+1.7.1 This release comes with some exciting new features. The new and noteworthy include: * * * * * * * * * KML Super Overlay and Regionating Support KML Extrude Support KML Reflector Improvements Mac OS X Installer Dutch Translation Improved Style for Web Admin Interface New SQL Server DataStore Extension Improved Oracle DataStore Extension Default Templates per Namespace

Along with many other improvements and bug fixes. The entire change log for the 1.7.1 series is available in the issue tracker: http://jira.codehaus.org/browse/GEOS/fixforversion/14502 A very special thanks to all those who contributed bug fixes, new features, bug reports, and testing to this release. -The GeoServer Team

8.20.2 SourceForge
1. Log in to SourceForge. 2. Edit the release, and scroll down to the bottom of the page. 3. Check the Im sure check box, and click the Send Notice button. 4. Repeat for the extension release.

8.20.3 GeoServer Blog


Note: This step requires an account on http://blog.geoserver.org

70

Chapter 8. Release Guide

GeoServer Developer Manual, Release 2.0.2

1. Log into the GeoServer Blog. 2. Create a new post. The post should be more colorful than the average announcement. It is meant to market and show off any and all new features. Examples of previous posts: http://blog.geoserver.org/2008/12/09/geoserver-171-released/ http://blog.geoserver.org/2008/10/27/geoserver-170-released/ 3. Do not publish the post. Instead present it to the GeoServer outreach team for review, and they will publish it.

8.20.4 SlashGeo
Note: This step requires an account on http://slashgeo.org 1. Go to http://slashgeo.org, and log in, creating an account if necessary. 2. Click the Submit Story link on the left hand side of the page. Examples of previous stories: http://technology.slashgeo.org/technology/08/12/09/1745249.shtml http://industry.slashgeo.org/article.pl?sid=08/10/27/137216

8.20.5 FreeGIS
Send an email to bjoern dot broscheit at uni-osnabrueck dot de. Example:
Subject: GeoServer update for freegis GeoServer 1.7.1 has been released with some exciting new features. The big push for this release has been improved KML support. The new and noteworthy include: * * * * * * * * * KML Super Overlay and Regionating Support KML Extrude Support KML Reflector Improvements Mac OS X Installer Dutch Translation Improved Style for Web Admin Interface New SQL Server DataStore Extension Improved Oracle DataStore Extension Default Templates per Namespace

Along with many other improvements and bug fixes. The entire change log for the 1.7.1 series is available in the issue tracker: http://jira.codehaus.org/browse/GEOS/fixforversion/14502

8.20. Announce the release

71

GeoServer Developer Manual, Release 2.0.2

8.20.6 FreshMeat
Note: This step requires an account on http://freshmeat.net/ 1. Go to http://freshmeat.net/ and log in. 2. Search for geoserver and click the resulting link. 3. Click the add release link at the top of the page. 4. Choose the Default branch 5. Enter the version and choose the appropriate Release focus. Note: The release focus is usually 4,5,6, or 7. Choose which ever is appropriate. 6. Enter a succinct description (less than 600 characters) of the Changes. 7. Update the links to the following elds: Zip OS X package Changelog 8. Click the Step 3 button. 9. Click the Finish button.

72

Chapter 8. Release Guide

CHAPTER

NINE

RELEASE TESTING CHECKLIST


A checklist of things to manually test for every release.

9.1 Artifact size


The binary release of GeoServer should be somehere around 45 - 46 megabytes.

9.2 Demos
To do the demo page, http://localhost:8080/geoserver/demo.do, and test all of the demos. This includes: WFS-T demo GeoRSS demo with Google Maps, Virtual Earth, and Yahoo Maps WMS Overlay demo WMS Example

9.3 Sample requests


Go to the sample request page, http://localhost:8080/geoserver/demoRequest.do, and execute every sample request, ensuring the correct response for each request.

9.4 Map preview


1. Go to the map preview page, http://localhost:8080/geoserver/mapPreview.do 2. Click the OpenLayers link next to nurc:ArcSample

73

GeoServer Developer Manual, Release 2.0.2

3. Go back to the map preview and click the GeoRSS link next to topp:states

4. Go back to the map preview and click the OpenLayers link next to topp:states. 5. Enable the options toolbar and specify the CQL lter:
STATE_ABBR EQ TX

74

Chapter 9. Release Testing Checklist

GeoServer Developer Manual, Release 2.0.2

9.5 KML
1. Go back to the map preview and click the KML link next to topp:states 2. Open the result in Google Earth 3. Zoom out as far as possible and notice the smaller states (on the east coast) disappear.

4. Close Google Earth Warning: If you do not shut down Google Earth it will cache information and throw off the next steps. 5. Go to the feature type editor page for the topp:states feature type

9.5. KML

75

GeoServer Developer Manual, Release 2.0.2

6. Change the KML Regionating Attribute to SAMP_POP and change the KML Regionating Strategy to external-sorting:
.. image:: states_kml_config.png

7. Submit and Apply changes 8. Go back to the map preview page and again click the KML link next to topp:states, opening the result in Google Earth 9. Zoom out as far as possible and notice the smaller population states (green) disappear

10. Go back to the map preview page and click the KML link next to nurc:Img_Sample, opening the result in Google Earth

76

Chapter 9. Release Testing Checklist

GeoServer Developer Manual, Release 2.0.2

11. Zoom in and notice tiles load 12. Follow the link http://localhost:8080/geoserver/wms/kml?layers=topp:states&mode=refresh , opening the result in Google Earth 13. Notice the KML reload every time the camera is stopped 14. Edit the description template for the states layer as follows:
This is the state of ${STATE_NAME.value}.

<img src="http://www.netstate.com/states/symb/flags/images/${STATE_ABBR.value?lower_case}_fi.gif <br> For more information visit <a href="http://en.wikipedia.org/wiki/${STATE_NAME.value}">Wikipedia<

15. Refresh the KML by moving the camera and click on a placemark

16. Append the parameter kmscore=0 to the above link and open the result in Google Earth 17. Notice the rasterized version of the KML

18. Follow the link http://localhost:8080/geoserver/wms/kml?layers=topp:states&mode=download , saving the result to disk. 19. Examine the le on disk and notice a raw dump of all placemarks for the layer.

9.5. KML

77

GeoServer Developer Manual, Release 2.0.2

9.6 GeoWebCache
1. Go the geowebcache demo page, http://localhost:8080/geoserver/gwc/demo 2. Click the EPSG:4326" link for topp:states 3. Zoom in and notice the tiles load. 4. Repeat steps 2 to 3 for EPSG:900913

78

Chapter 9. Release Testing Checklist

CHAPTER

TEN

CITE TEST GUIDE


A step by step guide to the GeoServer Compliance Interoperability Test Engine (CITE). Contents Cite Test Guide Check out CITE tools Build the CITE tools Run the test engine Run WFS 1.0 tests Run WFS 1.1 tests Run WMS 1.1 tests Run WCS 1.1 tests Run WCS 1.0 tests Command line

10.1 Check out CITE tools


1. Check out the cite tools from subversion:
svn co http://svn.codehaus.org/geoserver/trunk/community/cite cite

2. From the cite directory check out the test engine:


cd cite svn co -r 402 http://teamengine.svn.sourceforge.net/svnroot/teamengine/branches/team2 engine

3. Patch the engine sources:


patch -p0 < engine.patch

Note: This step is necessary if the engine is to be run as a web application in Jetty. 4. From the cite directory check out the sources for legacy cite testing component:
mkdir cite1 svn co https://svn.opengeospatial.org:8443/ogc-projects/cite/components/cite1/trunk cite1

5. From the cite directory check out the test sources for each test suite that is to be run:

79

GeoServer Developer Manual, Release 2.0.2

mkdir tests svn co -r 2740 https://svn.opengeospatial.org:8443/ogc-projects/cite/scripts/wfs/1.0.0/trunk te svn co -r 2740 https://svn.opengeospatial.org:8443/ogc-projects/cite/scripts/wfs/1.1.0/trun svn co -r 2740 https://svn.opengeospatial.org:8443/ogc-projects/cite/scripts/wms/1.1.1/trunk tes svn co -r 2740 https://svn.opengeospatial.org:8443/ogc-projects/cite/scripts/wcs/1.0.0/trunk svn co -r 2740 https://svn.opengeospatial.org:8443/ogc-projects/cite/scripts/wcs/1.1.1/trunk

Warning: To check out the test sources an account on the OGG portal is required. If you do not have one ask on the developer list for someone to check out the tests for you.

10.2 Build the CITE tools


From the cite directory execute the following command:
mvn clean install

A successful build should result in the following output:

[INFO] [compiler:testCompile] [INFO] No sources to compile [INFO] [surefire:test] [INFO] No tests to run. [INFO] [jar:jar] [WARNING] JAR will be empty - no content was marked for inclusion! [INFO] Building jar: /Users/jdeolive/Devel/geoserver/trunk/trunk/src/community/cite/target/cite-1.0.j [INFO] [install:install] [INFO] Installing /Users/jdeolive/Devel/geoserver/trunk/trunk/src/community/cite/target/cite-1.0.jar [INFO] -----------------------------------------------------------------------[INFO] BUILD SUCCESSFUL [INFO] -----------------------------------------------------------------------[INFO] Total time: 27 seconds [INFO] Finished at: Mon Jul 20 10:43:13 EST 2009 [INFO] Final Memory: 20M/36M [INFO] ------------------------------------------------------------------------

10.3 Run the test engine


Note: The engine can be run in one of two ways: 1. As a web application as described in this section 2. From the command line as described here 1. Change to the engine directory and execute the following command:
cd engine mvn jetty:run-exploded

If successful, Jetty should be started:

80

Chapter 10. Cite Test Guide

GeoServer Developer Manual, Release 2.0.2

[INFO] [jetty:run-exploded] [INFO] Configuring Jetty for project: Compliance + Interopability Testing + Evaluation (CITE) Mo [INFO] Context path = /teamengine [INFO] Tmp directory = determined at runtime [INFO] Web defaults = org/mortbay/jetty/webapp/webdefault.xml [INFO] Web overrides = none [INFO] Starting jetty 6.1.8 ... 2009-07-20 10:45:03.551::INFO: jetty-6.1.8 2009-07-20 10:45:03.707::INFO: No Transaction manager found - if your webapp requires one, plea 2009-07-20 10:45:09.893::INFO: Started SelectChannelConnector@0.0.0.0:9090 [INFO] Started Jetty Server

2. In a web browser navigate to http://localhost:9090/teamengine Note: By default the engine is congured to run on port 9090. This can be changed by editing the engine/pom.xml le. 3. Click the Start Testing link. geoserver. When prompted for a username and password use geoserver and

4. Click the Create a new session link

10.3. Run the test engine

81

GeoServer Developer Manual, Release 2.0.2

5. Choose the test suite to run from the drop down lists and provide a name for the session

6. Click the Start a new test session button Warning: The engine uses a pop-up window to display the status of the test suite. The pop-up will need to be unblocked by the browser and javascript must be enabled for it to work.

10.4 Run WFS 1.0 tests


Note: Running WFS 1.0 tests require PostGIS to be installed on the system.

82

Chapter 10. Cite Test Guide

GeoServer Developer Manual, Release 2.0.2

1. Create a PostGIS user named cite:


createuser cite

2. Create a PostGIS databased named cite, owned by the cite user:


createdb -T template_postgis -U cite cite

3. Change directory to the citewfs-1.0 data directory and execute the script cite_data.sql:
psql -U cite cite < cite_data.sql

4. Start GeoServer with the citewfs-1.0 data directory. Example:


cd <root of geoserver install> export GEOSERVER_DATA_DIR=<root of geoserver sources>/data/citewfs-1.0 ./bin/startup.sh

5. Create a new wfs-1.0.0 session in teamengine and congure it with the following parameters: (a) Capabilities URL:
http://localhost:8080/geoserver/wfs?request=getcapabilities&service=wfs&version-1.0.0

(b) All tests included

10.5 Run WFS 1.1 tests


Note: Running the wfs 1.0 test suite requires that GeoServer is running with the H2 extension enabled. If you are running from eclipse you can simply use the h2 prole:
mvn eclipse:eclipse -P h2

If you are running an actual release install the H2 extension available from the download page. 1. Change directory to the citewfs-1.1-h2 data directory and Unpack the H2 database:
cd <root of geoserver sources/data/citewfs-1.1-h2 unzip cite.db.zip

2. Start GeoServer with the citewfs-1.1-h2 data directory. 3. Create a new wfs-1.1.0 session in teamengine and congure it with the following parameters: (a) Capabilities URL:
http://localhost:8080/geoserver/wfs?service=wfs&request=getcapabilities&version=1.1.0

(b) Supported Conformance Classes: Ensure WFS-Transaction is checked Ensure WFS-Xlink is unchecked (c) GML Simple Features: SF-0

10.5. Run WFS 1.1 tests

83

GeoServer Developer Manual, Release 2.0.2

10.6 Run WMS 1.1 tests


1. Start GeoServer with the citewms-1.1 data directory. 2. Create a new wms-1.1.1 session in teamengine and congure it with the following parameters: (a) Capabilities URL:
http://localhost:8080/geoserver/wms?&service=wms&request=getcapabilities

(b) UpdateSequence Values: Ensure Automatic is selected 2 for value that is lexically higher 0 for value that is lexically lower (c) Certification Profile : QUERYABLE (d) Optional Tests: Ensure Recommendation Support is checked Ensure GML FeatureInfo is checked Ensure Fees and Access Constraints is checked For BoundingBox Constraints ensure Either is selected (e) Click OK

10.7 Run WCS 1.1 tests


1. Start GeoServer with the citewcs-1.1 data directory. 2. Create a new wcs-1.1.0 session in teamengine and congure it with the following parameters: (a) Capabilities URL:
http://localhost:8080/geoserver/wcs?service=wcs&request=getcapabilities&version=1.1.1

Click Next 3. Accept the default values and click Submit

10.8 Run WCS 1.0 tests


Warning: The WCS specication does not allow a cite compliant WCS 1.0 and 1.1 version to co-exist. To successfully run the WCS 1.0 cite tests the wms1_1-<VERSION>.jar must be removed from the geoserver WEB-INF/lib directory. 1. Remove the wcs1_1-<VERSION>.jar from WEB-INF/lib directory. 2. Start GeoServer with the citewcs-1.0 data directory. 3. Create a new wcs-1.0.0 session in teamengine and congure it with the following parameters:

84

Chapter 10. Cite Test Guide

GeoServer Developer Manual, Release 2.0.2

(a) Capabilities URL:


http://localhost:8080/geoserver/wcs?service=wcs&request=getcapabilities&version=1.0.0

(b) MIME Header Setup: image/tiff (c) Update Sequence Values: 2 for value that is lexically higher 0 for value that is lexically lower (d) Grid Resolutions: 0.1 for RESX 0.1 for RESY (e) Options: Ensure Verify that the server supports XML encoding is checked Ensure Verify that the server supports range set axis is checked (f) Schemas: Ensure that original schemas is selected (g) Click OK

10.9 Command line


10.9.1 Running a test suite
To run the engine from the command line execute the run.sh script from the cite directory:
cd cite sh run.sh <testsuite>

Where testsuite is <service>-<version> identier for the test suite. Example: wfs-1.1.0. Note: When running from the command line the engine uses a Swing pop-up dialog to congure a test session. If you are running Linux and get a blank window, try export AWT_TOOLKIT="MToolkit" before executing run.sh.

10.9.2 Logging results of a test run


To log the results of a test run execute the log.sh script from the cite directory:
cd cite sh log.sh <testsuite>

The above command will output all the tests run as part of the test suite. For each test the log will report if it passed or failed. For example, to list all the wfs-1.1.0 tests that failed:
sh log.sh wfs-1.1.0 | grep "wfs:wfs-1.1.0" | grep "Failed"

Note: The intermediate grep for wfs:wfs-1.1.0 will lter out all subtests that failed. The output of the above command will be something like: 10.9. Command line 85

GeoServer Developer Manual, Release 2.0.2

Test wfs:wfs-1.1.0-LockFeature-tc1.1 (wfs-1.1.0/d39e32742_1/d39e728_1/d39e29904_1/d39e28567_1) Passed Test wfs:wfs-1.1.0-LockFeature-tc2.1 (wfs-1.1.0/d39e32742_1/d39e728_1/d39e29904_1/d39e28580_1) Passed Test wfs:wfs-1.1.0-LockFeature-tc3.1 (wfs-1.1.0/d39e32742_1/d39e728_1/d39e29904_1/d39e28585_1) Passed

The long string in parantheses beside the test name is the test id. To log information about a specic test append its test id as a parameter to the run.sh script. Example:
sh run.sh wfs-1.1.0 wfs-1.1.0/d39e32742_1/d39e728_1/d39e29904_1/d39e28567_1

86

Chapter 10. Cite Test Guide

CHAPTER

ELEVEN

POLICIES AND PROCEDURES


11.1 Comitting
11.1.1 Getting commit access
There are two stages of commit access: 1. community module or extension commit access 2. core commit access The rst stage of access allows a developer to commit only to the community module or extension for which they are the maintainer. This stage of access can be obtained quite easily. The second allows a developer to make commits to the core modules of geoserver. Being granted this stage of access takes time, and is obtained only after the developer has gained the trust of the other core comitters. Community commit access The process of getting community commit access is as follows: 1. Email the developer list This rst step is all about communication. In order to grant commit access the other developers on the project must rst know what the intention is. Therefore any developer looking for commit access must rst describe what they want to commit (usually a community module), and what it does. 2. Join the project on CodeHaus After a developer has stated intentions via the email list, a PSC member will approve the request for commit access. At which point the developer must: (a) Create a Codehaus account by visiting http://xircles.codehaus.org/signup Note: If you already have a JIRA (bug tracker) or Conuence (wiki) account it is best to use the same userid for the Codehaus account. (b) Visit http://xircles.codehaus.org/projects/geoserver (c) Click the Apply to join as a developer link

87

GeoServer Developer Manual, Release 2.0.2

3. Notify the developer list After a developer has signed up on Codehaus they must notify the developer list. A project despot will then approve the request to join the project. Core commit access The process of obtaining core commit access is far less mechanical than the one to obtain community commit access. It is based soley on trust. To obtain core commit access a developer must rst obtain the trust of the other core commiters. The way this is typically done is through continuous code review of patches. After a developer has submitted enough patches that have been met with a postitive response, and those patches require little modications, the developer will be granted core commit access. There is no magic number of patches that make the criteria, it is based mostly on the nature of the patches, how in depth the they are, etc... Basically it boils down the developer being able to show that they understand the code base well enough to not seriously break anything.

11.2 Code Review


Reviewing code is an invaluble process that is used to ensure that the highest quality code possible gets comitted into GeoServer at all times. There is no hard policy relating to code review such that every line of code needs to be reviewed but the unofcial practice which has been adopted over time by GeoServer developers is summed up as follows: if the change is to a core module and the developer does not have core commit access it requires review if the change is non-trivial and to a core module, it should be reviewed if the change is local to a module the developer maintains it usually does not require a review

88

Chapter 11. Policies and Procedures

GeoServer Developer Manual, Release 2.0.2

The above guidelines are not rules. In general code review is always welcome and if there is a question as to if a change should be reviewed or not, always heir on the side of getting it reviewed.

11.3 Community Process


This document describes the process that the GeoServer community uses to handle contributions and additions to the project. This process is used to manage new features and additions to the project, as well as for short and long term project planning. The GeoServer community process adheres to the following guidelines to ensure that it retains open development practices: Transparency Project decisions are made in an open and transparent way. When a decision is made it is clear as to why it was made. Balance Every member of the developer community has an equal voice. Project decisions are made by the community as a whole, and not subject to the whims of any one single developer or organizations.

11.3.1 Road map


The GeoServer road map is the center of all project planning. It communicates to the community what is being worked on and when it is planned to be released. More specically the road map is a timeline of planned releases. Each release has a date attached to it and contains a list of features and critical bug-xes/improvements that will be implemented for that release. The road map is structured into thee parts: short term, medium term, and long term. The short term road map is made up of features scheduled for the next two releases. The medium term road map is made up of features scheduled for the remainder the current stable development branch. The long term road map consists of features scheduled against the next/unstable development branch. Short term road map The short term road map is the most important part of the overall road map as it pertains specically to what is going to be released in the near future. This road map is updated on a weekly basis. Items on the short term road map are described in JIRA as new features, improvements, or high priority bug xes. Medium term road map The medium term road map is a higher level view of what is to come in the current unstable development branch (trunk). It is much less ner grained than the short term road map. Items on the short term road map may or may not show up in JIRA. Medium term road map items usually take the form of a GSIP in progress, or one being discussed, or just a community module being developed. Long term road map The long term road map is the highest level view of the road map and describes what is to come in future development branches. Items on the long term road map are more or less just ideas or future plans. Long term road map items are usually described on a RnD page until they become a reality.

11.3. Community Process

89

GeoServer Developer Manual, Release 2.0.2

Maintaining the short term road map Being the most important part of the road map, the process for maintaining and updating the short term road map is well dened. Road map updates occur weekly and take place on the developer list as follows: 1. At the beginning of the week an email is sent to the developer list with the subject line #roadmap update <DATE>. This email is more or less an quick overview of the current state of the road map and contains: The next scheduled release date A list of the unresolved road map items 2. Developers (or any community members) may reply to the initial email and provide progress updates on road map items assigned to them. Developers may also propose changes and updates to the road map. Examples of such updates include proposing: new features to be added to the road map, see Adding features features which need to be moved back to a future release due to lack of resourcing features which need to be moved back to a future release due to other issues a change to the scheduled release date 3. Developers and community members discuss the proposed changes on the list. Those updates which are agreed upon are factored into the road map and it is updated. Adding features During the road map update developers propose new features and improvements to be added to the road map. The following are the prerequisites for proposing a new feature: 1. The feature has a sponsor. This means either a developer willing to carry out the work or a customer who is paying for it 2. The feature has has gone through the GSIP process if necessary. Whether a feature requires a GSIP is decided by the community when the feature is proposed After a feature has met the above prerequisites it is assigned to a release on the road map. The determining factor for what release a feature should be assigned to is based on the estimate of the time to implement the feature, and the current Release cycle for the branch the feature is being implemented on. If the time to implement the feature does not allow it to be assigned to the next release it is scheduled accordingly into a future release. Release cycle GeoServer follows a regular release cycle. Usually this cycle is a release every month. However once a development branch has become stable the release cycle drops off to every few months. Similarly on an unstable development branch the release cycle can be every few months, until the branch becomes stable enough for monthly releases.

11.4 GeoServer Improvement Proposals


GeoServer Improvements Proposals (GSIP) are the formal mechanism used to manage any sort of major change to GeoServer. Examples of changes which are managed by the GSIP process include: major features code re-architecture

90

Chapter 11. Policies and Procedures

GeoServer Developer Manual, Release 2.0.2

community process improvements intellectual property

11.4.1 How a GSIP works


The typical life cycle of a GSIP is as follows: 1. Developer has an intent to perform a major change 2. Developer communicates with the community about the change 3. Developer goes off and implements the change 4. Developer writes a GSIP and presents it to the community for feedback 5. The PSC votes on the GSIP 6. Developer commits changes upon receiving a positive vote

11.4.2 Voting on a GSIP


One of the duties of the GeoServer Project Steering Committee is to vote on GSIPs. The voting process works as follows: Each PSC member gets a single vote, which can be one of +1, -1, 0 Any PSC member that votes negatively against a proposal must provide a reasonable explanation as to why Any PSC member that votes negatively against a proposal has a limited time to provide constructive feedback as to how the vote can be turned The GSIP author must incorporate any reasonable feedback into the proposal Any negative vote is reviewed to determine if criteria has been met to turn it to a positive vote The proposal is considered successful after a majority of positive votes is a achieved and all feedback from any negative votes has been addressed

11.4.3 Implementing a GSIP


GSIPs are written up on the wiki. To make a GSIP: 1. Navigate to the proposals under discussion page 2. Log in to the wiki and click the Add Page link 3. Use the Proposal template to create the new page 4. Name the new page GSIP ## - <TITLE> where: (a) ## is the number of the GSIP (b) <TITLE> is the title of the GSIP 5. Fill in the information in the page template, and click Save when complete.

11.4. GeoServer Improvement Proposals

91

GeoServer Developer Manual, Release 2.0.2

11.4.4 GSIP FAQ


Q. When do I need to make a GSIP? A: Generally you will make a GSIP when you want something major done in GeoServer and need feedback from others. GSIPs are needed for things that will have an impact on other community members, and thus should be talked about. GSIPs are not intended to be a way to get feedback on experimental work. There are alternate mechanisms for this such as creating an R&D page on the wiki, svn branches and spikes, etc... Often once the idea is formalized through experimentation it can be turned in to an ofcial GSIP. Q. Who can comment on a GSIP? A: Anyone and everyone can comment on a GSIP including regular users, and it is encouraged. Comments an take place on the email lists, or as comments on the wiki page for the GSIP itself. Feedback from the user community is denitely desired so that the developers do not just making decisions in a vacuum. If you speak up your voice will be heard. Q. Who can vote on a GSIP? A: Only PSC members can ofcially vote on a GSIP. But more often than not this vote is based on general feedback from the user community. Q: What happens if I propose a GSIP but I dont have the time to implement it? A: If a proposal is made but is not completed then it will be taken from a release schedule and live as a deferred proposal. A deferred proposal can be picked up by the original developer or another developer, or it can live in limbo until it ofcially gets rejected. Q: If I am a PSC member and I make a GSIP, do I still vote on it? A: Yes.

11.5 Community Modules


This document describes the GeoServer community module process. It is a guide that describes how the GeoServer project takes in contributions from the community. In GeoServer a module can fall into one of three classes: core, those modules which GeoServer requires to function and are distributed with the main GeoServer distribution extension, plug-ins available as separate artifacts from the main distribution community, experimental or unstable modules which are not part of the release process Every module added to GeoServer has its origin as a community module. If the module becomes stable enough it will eventually become part of the main GeoServer distribution either as a core module, or as an extension.

92

Chapter 11. Policies and Procedures

GeoServer Developer Manual, Release 2.0.2

11.5.1 Creating a community module


Requirements The single requirement for adding a community module is the approval of one Project Steering Committee member. Process The following outlines the steps to be taken in order to add a new community module. 1. Get approval The rst step is to get approval to add the community module. This involves rst explaining to the rest of the GeoServer community the purpose and function of the extension to be added. The two best ways to do this are: (a) send an email to the developers list, or (b) participate in a weekly IRC meeting After explaining the intention, the approval of at least one Project Steering Committee member is needed before proceeding. Getting approval is easy as long as it is explained that the extension will be useful to other users or developers. 2. Get version control access The next step is to create the community module in the subversion repository. To do this it is necessary to be granted commit status. The process for signing up for version control access is dened in the Comitting section. 3. Add a new module Once commit access is obtained the module can be added. All community modules live under the directory community, directly under the root of the source tree. The community modules on trunk can be found here. For example, from the root of the GeoServer source tree:
[geoserver]% cd community [geoserver/community]% svn mkdir myCommunityModule [geoserver/community]% svn commit -m "adding my community module" myCommunityModule

4. Add a Maven POM Every module in the build requires a maven pom le, pom.xml. Use the following as a template:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSc <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.geoserver</groupId> <artifactId>geoserver</artifactId> <version>1.7.0-SNAPSHOT</version> <!-- change this to the proper GeoServer version --> </parent> <groupId>org.geoserver</groupId> <artifactId>myCommunityModule</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>My Community Module</name> <dependencies> <!-- add any dependencies your module has here -->

11.5. Community Modules

93

GeoServer Developer Manual, Release 2.0.2

</dependencies> </project>

Add the le to the root of the new community module, myCommunityModule/pom.xml 5. Add a build prole The nal step involves adding the new module to the maven build, and in particular adding a build prole for it. To do this: (a) Edit community/pom.xml and add the following inside of the <profiles> element:
<profiles> ... <profile> <id>myComunityModule</id> <modules> <module>myCommunityModule</module> </modules> </profile> </profiles>

(b) Edit web/pom.xml and add the following inside of the <profiles> element:
<profiles> ... <profile> <id>myCommunityModule</id> <dependencies> <dependency> <groupId>org.geoserver</groupId> <artifactId>myCommuityModule</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </profile> </profiles> .. warning:: If the community module depends on any other community modules, they too should be included in the profile definition. .. warning:: Ensure that the name of the profile matches the name of the community module

11.5.2 Promoting a community module


Once a community modules becomes stable, it may be promoted to a core or extension module. Which depends on the nature of the community module. If the module is plug-in based (ie. it provides functionality that some users may want, but others may not) then it should become an extension. Otherwise it should become a core module.

94

Chapter 11. Policies and Procedures

GeoServer Developer Manual, Release 2.0.2

Requirements The following properties must hold true in order to promote a community module: 1. The module has at least a handful of users In order to avoid cluttering the main code base, only those community modules which are of interest to at least 3 users (this may include the maintainer) are promoted. 2. The module has a designated and active maintainer Every core and extension module requires a module maintainer. The job of the maintainer is to x bugs and address issues which arise with the module. If a community module is promoted and the maintainer drops off, the module is in danger of being demoted back to community status. 3. The module is considered stable by the majority of the PSC A module will only be promoted if it is deemed stable by the majority of the PSC. Those PSC members deeming it unstable must provide a reasonable justication for the assertion. 4. The module maintains 40% test coverage A minimum of 40% test coverage must be maintained by the module in order to be promoted. Of course higher coverage is encouraged. The more test coverage a community module the more credibility it gets. 5. The module has no IP violations The module must not contain any code with a license or copyright that violates the GPL. 6. The module has a page in the user manual Each module needs a page in the user manual documenting its function and usage. Tutorials and walk-throughs are encouraged. 7. The maintainer has signed the GeoServer Contributor Agreement The Open Planning Project (TOPP) retains all copyright on code released as part of GeoServer. Since core and extension modules are released along with the rest of GeoServer, the maintainer of said modules must agree to assign copyright of code to TOPP. Process 1. Submit a GeoServer Improvement Proposal To promote a community module the contributor must create a GeoServer Improvement Proposals (GSIP). The proposal must then go through the regular feedback and voting process. 2. Move the module Once the proposal is accepted, the next step is to move the module out of the community space. Where the module ends up depends on wether it is being promoted to a core module, or an extension. Core modules Core modules live under the root of the source tree:

[geoserver]% svn move community/myCommunityModule . [geoserver]% svn commit -m "promoting my community module to a core module" myCommunityModule co

Extensions Extension modules live under the extension directory, under the root of the source tree:

11.5. Community Modules

95

GeoServer Developer Manual, Release 2.0.2

[geoserver]% svn move community/myCommunityModule extension [geoserver]% svn commit -m "promoting my community module to an extension" extension community

3. Update the build Once the module has been moved, the maven build must be updated. Core modules (a) Edit community/pom.xml and remove the prole for the community module (b) Edit pom.xml under the root of the source tree and add a module enty:
<modules> ... <module>myCommunityModule</module> </modules>

(a) Edit web/pom.xml and move the dependency on the community module into the main dependencies section of the pom. Then remove the prole Extensions (a) Copy the prole for the community module from community/pom.xml to extension/pom.xml (b) Remove the prole from community/pom.xml 4. Update the release process The next step is to include the new module in the release process. Core modules (a) Edit release/src.xml and add an <include> for the module:
... <moduleSets> <moduleSet> ... <include>org.geoserver:myCommunityModule</include> </moduleSet> </moduleSets> ...

Extensions (a) Create a new directory under release/extensions which matches the name of the extension (b) Add the following to the new directory: i. A license called <module>-LICENSE.txt which contains the license for the extension ii. A readme called <module>-README.txt which contains instructions on how to install the extension Warning: Dont skip this step. iii. Any static les that are required by the extension (example would be a proprietary driver not available for download via maven) (c) Create a release descriptor called ext-<module>.xml under the release directory which follows the following structure (where %module% is the name of the module):

96

Chapter 11. Policies and Procedures

GeoServer Developer Manual, Release 2.0.2

<assembly> <id>%module%</id> <formats> <format>zip</format> </formats> <includeBaseDirectory>false</includeBaseDirectory> <fileSets> <fileSet> <directory>release/extensions/%module%</directory> <outputDirectory></outputDirectory> <includes> <include>*</include> </includes> </fileSet> <fileSet> <directory>release/target/dependency</directory> <outputDirectory></outputDirectory> <includes> <include>%module%-*.jar</include> </includes> </fileSet> <fileSet> <directory>release/extensions</directory> <outputDirectory></outputDirectory> <includes> <include>LICENSE.txt</include> </includes> </fileSet> </fileSets> </assembly> * Add the * Add the additional include elements in the second fileSet for jar dependencies of the module additional include elements in the third fileSet for static file dependencies of the module

(d) Add a dependency from release/pom.xml to the extension module:


<dependencies> ... <dependency> <groupId>org.geoserver.extension</groupId> <artifactId>%module%</artifactId> <version>%version%</version> </dependency> ... </dependencies>

(e) Add an entry for the release descriptor to the root pom.xml of the source tree (ie. one step up from the release directory):
<!-- artifact assembly --> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.1</version> <configuration> <descriptors>

11.5. Community Modules

97

GeoServer Developer Manual, Release 2.0.2

<descriptor>release/src.xml</descriptor> <descriptor>release/war.xml</descriptor> <descriptor>release/javadoc.xml</descriptor> <descriptor>release/bin.xml</descriptor> <descriptor>release/doc.xml</descriptor> ... <descriptor>release/ext-%module%.xml</descriptor> </descriptors> </configuration> </plugin>

(a) Update the documentation Add a page to the user manual for the new module. Todo Finish this by linking somwhere... (b) Download the contributor agreement The nal step in the process is to download and ll out the contributor agreement form. Follow the instructions on the form to submit it.

11.5.3 Demoting a community module


For one reason or another a module is neglected and becomes unmaintained. When this happens the GeoServer PSC essentially becomes the maintainer and may decide to do one of two things: 1. Assume maintainership In this case someone (may be more than one person) on the PSC agrees to take on maintainership duties responsibilities for the module, such as bug xing 2. Demote the module If no one steps up to maintain the module it may be demoted back to community status. If and when a module is demoted depends on the circumstances. If the module is relatively quiet in that it just works and not many bug reports arise from it, it may be left alone and not demoted. Requirements The following properties must hold true in order to demote a module back to community status: 1. The module has no designated maintainer The module maintainer has stepped down or is unreachable and has not been active for a number of weeks. 2. The module is problematic The module contains one or more issues with blocker status, or contains a handful of issues with high priority. Process The following outlines the steps to demote a module to community status:

98

Chapter 11. Policies and Procedures

GeoServer Developer Manual, Release 2.0.2

1. Call for a maintainer Before demoting the module rst try to nd a new maintainer for it. Send an email to both the developer and user list advertising the module is in danger of getting pushed back to community status. Wait a few days to see if anyone steps up to take on maintainership. 2. Move the module and update the build If no one steps up to take on the maintainer role, reverse the steps described here, taken to promote the module. In summary: (a) Move the module back to the community directory (b) Disable any of the modules release artifacts (c) Move the prole for the module from extension/pom.xml to community/pom.xml in the case of an extension module

11.5.4 Stepping down from module maintainership


Often a module maintainer does not have the time or resources to continue to maintain a contribution. This is understood and is a fact of life in the open source software world. However, to relieve the burden on the project and PSC, the following steps taken by any maintainer stepping down are highly appreciated. 1. Give notice The more time you can give to the project in lieu of your departure the better. Send an email to the developers list as soon as you know you will be dropping off 2. Find a new maintainer While often not possible, any attempt to nd a new maintainer for the module is greatly appreciated.

11.5. Community Modules

99

You might also like