--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry kind="src" path="src"/>\r
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>\r
+ <classpathentry kind="con" path="org.jboss.ide.eclipse.jdt.aop.core.classpath.AOP_15_CONTAINER"/>\r
+ <classpathentry kind="con" path="org.jboss.ide.eclipse.jdt.ejb3.wizards.core.classpath.EJB3_CONTAINER/JBoss-4.0.4.GA"/>\r
+ <classpathentry kind="lib" path="C:/jboss-4.0.4.GA/server/default/lib/postgis_1.1.0.jar"/>\r
+ <classpathentry kind="lib" path="C:/jboss-4.0.4.GA/client/jbossws-client.jar"/>\r
+ <classpathentry kind="lib" path="C:/jboss-4.0.4.GA/client/jboss-jaxrpc.jar"/>\r
+ <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>PostGISTutorial</name>\r
+ <comment></comment>\r
+ <projects>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>org.jboss.ide.eclipse.ejb3.wizards.core.EJB3ProjectNature</nature>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+#Mon Sep 18 15:14:48 BST 2006\r
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5\r
+org.eclipse.jdt.core.compiler.compliance=1.5\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.5\r
--- /dev/null
+$Id$
+(This code was contributed by Noarman Barker <nbarker@ittvis.com>)
+
+Spatial EJB3
+
+
+Spatial EJB3 is a quick investigation to see if it is possible to integrate the
+Java 5 annotation approach to mark a property of an object as spatial and to
+delegate to the EJB3 persistence model to store and retrieve this data.
+
+The project utilises JBoss and PostGIS, future iterations will look to remove
+the dependency on JBoss and Hibernate to incorporate other Application
+Services.
+
+Since it is useful to display screenshots in a tutorial this has been written
+as a PDF and the document and source are available here.
+
--- /dev/null
+<!--\r
+ * build file\r
+ * \r
+ * PostGIS extension for PostgreSQL JDBC driver - EJB3 Support\r
+ * \r
+ * (C) 2006 Noarman Barker <nbarker@ittvis.com>\r
+ * \r
+ * This library is free software; you can redistribute it and/or modify it under\r
+ * the terms of the GNU Lesser General Public License as published by the Free\r
+ * Software Foundation, either version 2.1 of the License.\r
+ * \r
+ * This library is distributed in the hope that it will be useful, but WITHOUT\r
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more\r
+ * details.\r
+ * \r
+ * You should have received a copy of the GNU Lesser General Public License\r
+ * along with this library; if not, write to the Free Software Foundation, Inc.,\r
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at\r
+ * http://www.gnu.org.\r
+ * \r
+ * $Id$\r
+ -->\r
+<project name="PostGIS EJB3 Tutorial" default="compile" basedir=".">\r
+ <property name="build.dir" value="bin"/>\r
+ <property name="lib.dir" value="lib"/>\r
+ <property name="src.dir" value="src"/>\r
+ <property name="dist.dir" value="dist"/>\r
+ <property name="jboss.home" value="C:/jboss-4.0.4.GA"/>\r
+ <property name="jbossconf" value="jboss"/>\r
+\r
+ <path id="class.path">\r
+ <pathelement location="${build.dir}"/>\r
+ <fileset dir="${lib.dir}" includes="*.jar"/>\r
+ <fileset dir="${jboss.home}/client">\r
+ <include name="*.jar"/>\r
+ </fileset>\r
+ <fileset dir="${jboss.home}/server/default/lib" includes="hibernate3.jar"/>\r
+ </path>\r
+\r
+ <target name="clean" description="Removes all generated files">\r
+ <delete dir="${build.dir}"/>\r
+ <delete dir="${dist.dir}"/>\r
+ </target>\r
+\r
+ <target name="compile">\r
+ <mkdir dir="${build.dir}"/>\r
+ <javac destdir="${build.dir}" fork="true" classpathref="class.path" source="1.5" target="1.5">\r
+ <src path="${src.dir}"/>\r
+ </javac>\r
+ <copy todir="${build.dir}">\r
+ <fileset dir="${src.dir}"\r
+ includes="**/images/*,**/*.properties" excludes="**/.svn/*"/> \r
+ </copy>\r
+ </target>\r
+ \r
+ <target name="dist" depends="clean, compile">\r
+ <mkdir dir="${dist.dir}"/>\r
+ <jar jarfile="${dist.dir}/ingest.jar" basedir="${build.dir}" includes="**/ejb/*, **/mdb/*, **/UserBean/*, **/hibernate/*">\r
+ <metainf dir="${src.dir}/META-INF" includes="*.xml"/>\r
+ </jar>\r
+ </target>\r
+\r
+ <target name="deploy" description="deploys the service to JBoss" depends="dist">\r
+ <copy todir="${jboss.home}/server/default/deploy">\r
+ <fileset dir="${dist.dir}" includes="ingest.jar, people.war"/>\r
+ <fileset dir="${jbossconf}" includes="*.xml"/>\r
+ </copy>\r
+ </target>\r
+ \r
+</project>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<datasources>\r
+ <local-tx-datasource>\r
+ <jndi-name>GeoDataDS</jndi-name>\r
+ <connection-url>jdbc:postgresql://127.0.0.1:5432/geotest</connection-url>\r
+ <driver-class>org.postgis.DriverWrapper</driver-class>\r
+ <user-name>geo</user-name>\r
+ <password>geo</password>\r
+ <metadata>\r
+ <type-mapping>PostgreSQL 8.1</type-mapping>\r
+ </metadata>\r
+ </local-tx-datasource>\r
+</datasources>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<server>\r
+ <mbean code="org.jboss.mq.server.jmx.Queue"\r
+ name="jboss.mq.destination:service=Queue,name=ingestQueue">\r
+ <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>\r
+ </mbean>\r
+</server>
\ No newline at end of file
--- /dev/null
+<persistence>\r
+ <persistence-unit name="People">\r
+ <jta-data-source>java:/GeoDataDS</jta-data-source>\r
+ </persistence-unit>\r
+</persistence>
\ No newline at end of file
--- /dev/null
+java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
+java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
+java.naming.provider.url=localhost:1099
--- /dev/null
+/*
+ * PersonEntity.java
+ *
+ * PostGIS extension for PostgreSQL JDBC driver - EJB3 Tutorial
+ *
+ * (C) 2006 Noarman Barker <nbarker@ittvis.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at
+ * http://www.gnu.org.
+ *
+ * $Id$
+ */
+package org.postgis.ejb;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.hibernate.annotations.Type;
+import org.postgis.Geometry;
+
+@Entity
+@Table(name="people")
+@NamedQuery(name="findPerson",
+ query="SELECT DISTINCT OBJECT(p) FROM PersonEntity p WHERE ((p.name = :name) AND (p.surname = :surname)) ORDER BY p.date")
+public class PersonEntity {
+ private long id;
+ private String name;
+ private String surname;
+ private Geometry location;
+ private Date date;
+
+ @Id
+ @GeneratedValue(strategy=GenerationType.IDENTITY)
+ @Column(name="id")
+ public long getId() {
+ return id;
+ }
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ @Type(type = "org.postgis.hibernate.GeometryType")
+ @Column(name="location", columnDefinition="Geometry")
+ public Geometry getLocation() {
+ return location;
+ }
+ public void setLocation(Geometry location) {
+ this.location = location;
+ }
+
+ @Column(name="name")
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Column(name="surname")
+ public String getSurname() {
+ return surname;
+ }
+ public void setSurname(String surname) {
+ this.surname = surname;
+ }
+
+ @Column(name="ingested")
+ @Temporal(TemporalType.TIMESTAMP)
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+}
--- /dev/null
+/*
+ * UserBean.java
+ *
+ * PostGIS extension for PostgreSQL JDBC driver - EJB3 Tutorial
+ *
+ * (C) 2006 Noarman Barker <nbarker@ittvis.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at
+ * http://www.gnu.org.
+ *
+ * $Id$
+ */
+package org.postgis.ejb;
+
+import java.rmi.RemoteException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.annotation.Resource;
+import javax.annotation.security.RunAs;
+import javax.ejb.EJBException;
+import javax.ejb.Stateless;
+import javax.jms.JMSException;
+import javax.jms.MapMessage;
+import javax.jms.Queue;
+import javax.jms.QueueConnection;
+import javax.jms.QueueConnectionFactory;
+import javax.jms.QueueSender;
+import javax.jms.QueueSession;
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebResult;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+
+import org.jboss.annotation.security.SecurityDomain;
+
+@Stateless
+@WebService(
+ name = "EndpointInterface",
+ targetNamespace = "http://org.postgis/ejb/UserBean",
+ serviceName = "PeopleFinder")
+@SOAPBinding(style = SOAPBinding.Style.RPC)
+public class UserBean implements UserBeanRemote{
+ @PersistenceContext(unitName="People") private EntityManager entityManager;
+
+ @Resource(mappedName = "java:/ConnectionFactory")
+ private QueueConnectionFactory connectionFactory;
+
+ @Resource(mappedName = "queue/ingestQueue")
+ private Queue queue;
+
+
+ @WebMethod
+ public void ingest(@WebParam(name = "name") String name,@WebParam(name = "surname") String surname,@WebParam(name = "lat") double lat, @WebParam(name = "lon") double lon){
+ // place message on a queue
+ try {
+ QueueConnection qConn = connectionFactory.createQueueConnection();
+ QueueSession qSession = qConn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
+ QueueSender qSender = qSession.createSender(queue);
+
+ // create a message
+ MapMessage message = qSession.createMapMessage();
+ message.setStringProperty("MessageFormat", "Person");
+ message.setString("NAME", name);
+ message.setString("SURNAME", surname);
+ message.setDouble("LAT", lat);
+ message.setDouble("LON", lon);
+ qSender.send(message);
+ qSession.close();
+ qConn.close();
+ } catch (JMSException e) {
+ throw new EJBException(e.getMessage());
+ }
+
+ }
+
+
+ @WebMethod
+ @WebResult(name="positions")
+ public String[] findPerson(@WebParam(name = "name") String name, @WebParam(name = "surname") String surname)
+ {
+ Query query = entityManager.createNamedQuery("findPerson");
+ query.setParameter("name", name);
+ query.setParameter("surname", surname);
+ List list = query.getResultList();
+
+ if (list != null)
+ {
+ Iterator itr = list.iterator();
+ ArrayList<String> resultList = new ArrayList<String>();
+
+ while (itr.hasNext())
+ {
+ PersonEntity person = (PersonEntity) itr.next();
+ resultList.add(person.getLocation().getValue() + "," + person.getDate() + "\r\n");
+ }
+
+ String[] result = (String[])(resultList.toArray(new String[resultList.size()]));
+ return result;
+ }
+ else
+ {
+ return null;
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * UserBeanRemote.java
+ *
+ * PostGIS extension for PostgreSQL JDBC driver - EJB3 Tutorial
+ *
+ * (C) 2006 Noarman Barker <nbarker@ittvis.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at
+ * http://www.gnu.org.
+ *
+ * $Id$
+ */
+package org.postgis.ejb;
+
+import java.rmi.RemoteException;
+
+import javax.ejb.Remote;
+import javax.jws.WebParam;
+
+@Remote
+public interface UserBeanRemote {
+ public void ingest(String name, String surname, double lat, double lon) throws RemoteException;
+ public String[] findPerson(String name, String surname) throws RemoteException;
+}
--- /dev/null
+/*
+ * IngestMDB.java
+ *
+ * PostGIS extension for PostgreSQL JDBC driver - EJB3 Tutorial
+ *
+ * (C) 2006 Noarman Barker <nbarker@ittvis.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at
+ * http://www.gnu.org.
+ *
+ * $Id$
+ */
+package org.postgis.ejb.mdb;
+
+import java.util.Date;
+
+import javax.ejb.ActivationConfigProperty;
+import javax.ejb.MessageDriven;
+import javax.jms.JMSException;
+import javax.jms.MapMessage;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+import org.postgis.Point;
+import org.postgis.ejb.PersonEntity;
+
+@MessageDriven(activationConfig={
+ @ActivationConfigProperty(
+ propertyName="destinationType",
+ propertyValue="javax.jms.Queue"),
+ @ActivationConfigProperty(
+ propertyName="destination",
+ propertyValue="queue/ingestQueue"),
+ @ActivationConfigProperty(
+ propertyName="messageSelector",
+ propertyValue="MessageFormat ='Person'"),
+ @ActivationConfigProperty(
+ propertyName="acknowledgeMode",
+ propertyValue="Auto-acknowledge")
+})
+/**
+ * implements a listener interface to ingest people data
+ */
+public class IngestMDB implements MessageListener {
+
+ public static final String NAME = "NAME";
+ public static final String SURNAME = "SURNAME";
+ public static final String LATITUDE = "LAT";
+ public static final String LONGITUDE = "LON";
+
+ @PersistenceContext(unitName="People") private EntityManager entityManager;
+
+
+ /**
+ * Implements a message listener for Person ingest requests
+ * @see javax.jms.MessageListener#onMessage(javax.jms.Message)
+ */
+ public void onMessage(Message msg) {
+ if (msg instanceof MapMessage)
+ {
+ try {
+ MapMessage m = (MapMessage)msg;
+ String name = m.getString(IngestMDB.NAME);
+ String surname = m.getString(IngestMDB.SURNAME);
+ Double lat = m.getDouble(IngestMDB.LATITUDE);
+ Double lon = m.getDouble(IngestMDB.LONGITUDE);
+
+ PersonEntity person = new PersonEntity();
+ person.setName(name);
+ person.setSurname(surname);
+ person.setLocation(new Point(lon, lat));
+ person.setDate(new Date());
+ entityManager.persist(person);
+
+ // for tutorial info
+ System.out.println("INGESTED " + name + " " + surname + " into PostGIS");
+ } catch (JMSException e) {
+ e.printStackTrace();
+ }
+
+
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * GeometryType.java
+ *
+ * PostGIS extension for PostgreSQL JDBC driver - EJB3 Tutorial
+ *
+ * (C) 2006 Noarman Barker <nbarker@ittvis.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at
+ * http://www.gnu.org.
+ *
+ * $Id$
+ */
+package org.postgis.hibernate;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.sql.Blob;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.HibernateException;
+import org.hibernate.usertype.UserType;
+import java.io.InputStream;
+import org.postgis.Geometry;
+import org.postgis.binary.BinaryParser;
+import org.postgis.binary.BinaryWriter;
+
+/**
+ * @author nbarker $date 16/8/06
+ */
+public class GeometryType implements UserType {
+ private static final int[] SQL_TYPES = { Types.BLOB };
+
+
+ /**
+ * @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
+ */
+ public Object deepCopy(Object value) throws HibernateException {
+ return value;
+ }
+
+ /**
+ * @see org.hibernate.usertype.UserType#equals(java.lang.Object, java.lang.Object)
+ */
+ public boolean equals(Object x, Object y) throws HibernateException {
+ if (x == y) {
+ return true;
+ } else if (x == null || y == null) {
+ return false;
+ } else {
+ return x.equals(y);
+ }
+ }
+
+ /**
+ * @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
+ */
+ public int hashCode(Object arg0) throws HibernateException {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /**
+ * @see org.hibernate.usertype.UserType#isMutable()
+ */
+ public boolean isMutable() {
+ return false;
+ }
+
+ /**)
+ * @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], java.lang.Object)
+ */
+ public Object nullSafeGet(ResultSet resultSet,
+ String[] names, Object owner) throws HibernateException, SQLException {
+ Geometry result = null;
+ String geom = resultSet.getString(names[0]);
+ BinaryParser parser = new BinaryParser();
+ result = parser.parse(geom);
+ return result;
+ }
+
+ /**
+ * @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement, java.lang.Object, int)
+ */
+ public void nullSafeSet(PreparedStatement statement,
+ Object value, int index) throws HibernateException, SQLException {
+ if (value == null) {
+ statement.setBytes(index, null);
+ } else {
+ BinaryWriter bw = new BinaryWriter();
+
+ byte[] bytes = bw.writeBinary((Geometry)value);
+ statement.setBytes(index, bytes);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.hibernate.usertype.UserType#replace(java.lang.Object, java.lang.Object, java.lang.Object)
+ */
+ public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.hibernate.usertype.UserType#returnedClass()
+ */
+ public Class returnedClass() {
+ return Geometry.class;
+ }
+
+ /**
+ * @see org.hibernate.usertype.UserType#sqlTypes()
+ */
+ public int[] sqlTypes() {
+ return GeometryType.SQL_TYPES;
+ }
+
+ /**
+ * @see org.hibernate.usertype.UserType#assemble(java.io.Serializable, java.lang.Object)
+ */
+ public Object assemble(Serializable cached, Object owner) throws HibernateException {
+ return cached;
+ }
+
+ /**
+ * @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
+ */
+ public Serializable disassemble(Object value) throws HibernateException {
+ return (Serializable)value;
+ }
+
+}
+