Skip to content

Commit

Permalink
First cut of application on PlayFramework.
Browse files Browse the repository at this point in the history
  • Loading branch information
Khaless committed Apr 15, 2012
1 parent 58bc717 commit abfcfc4
Show file tree
Hide file tree
Showing 41 changed files with 12,024 additions and 26 deletions.
19 changes: 19 additions & 0 deletions README 100644 → 100755
Expand Up @@ -2,3 +2,22 @@ This is your new Play 2.0 application
=====================================

This file will be packaged with your application, when using `play dist`.


Credits & Licence List
======================

http://loopj.com/jquery-tokeninput/ => MIT Licence
http://code.google.com/p/jquery-geolocation/ => MIT Licence


Yahoo YQL to get Geography Bounding Box locations. e.g.
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20geo.places%20where%20text%3D%22Australia%22&diagnostics=true

PostGIS Geometry Information:
http://workshops.opengeo.org/postgis-intro/geography.html

Country Border Information:
http://www.gelib.com/world-borders.htm

http://gis.stackexchange.com/questions/11567/spatial-clustering-with-postgis
120 changes: 120 additions & 0 deletions app/Global.java
@@ -0,0 +1,120 @@
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import models.Country;
import play.Application;
import play.GlobalSettings;
import play.Logger;
import play.Play;
import play.db.DB;

import com.avaje.ebean.Ebean;

public class Global extends GlobalSettings {

public void onStart(Application app) {

Logger.info("Application has started");

/*
* Turn on SQL logging in the development environment.
*/
if (Play.isDev()) {
Ebean.getServer(null).getAdminLogging().setDebugGeneratedSql(true);
}

/*
* Since we cannot insert initial data using evolutions & we have to
* work around some STORED PROCEDURE definition issues (see evolution
* 1.sql).
*
* We define an InitialData insert routine that sets up the remainder of
* our database on initialization.
*/
InitialData.checkAndDoInitialization(app);

}

public void onStop(Application app) {
Logger.info("Application shutdown...");
}

static class InitialData {

public static void checkAndDoInitialization(Application app) {

Logger.info("Checking Database...");

/*
* No countries means our database is not yet initialised
*/
if (Ebean.find(Country.class).findRowCount() == 0) {

Logger.info("Not Initialised. Now Initializing Database...");

/*
* We initialise stored procedures and data here.
*
* This is because Play Evolutions currently has a bug that
* prevents us from declaring our stored procedures in them.
*
* See:
* https://play.lighthouseapp.com/projects/82401/tickets/212
* -evolutions-break-on-semicolons
*/

Connection conn = DB.getConnection();
try {
Statement stmt = conn.createStatement();

/*
* Stored procedure workaround.
*/

stmt.execute("CREATE OR REPLACE FUNCTION update_point_from_lat_lng()"
+ " RETURNS TRIGGER AS $$"
+ " BEGIN"
+ " NEW.point = ST_GeogFromText('SRID=4326;Point(' || CAST(NEW.longitude AS DECIMAL(15,6) ) || ' ' || CAST(NEW.latitude AS DECIMAL(15,6) ) || ')');"
+ " RETURN NEW;"
+ " END;"
+ "$$ language 'plpgsql';");

stmt.execute("DROP TRIGGER IF EXISTS update_geotags_point ON geotags;");
stmt.execute("CREATE TRIGGER update_geotags_point BEFORE INSERT OR UPDATE"
+ " ON geotags FOR EACH ROW EXECUTE PROCEDURE"
+ " update_point_from_lat_lng();");

/*
* Insert required data
*/
BufferedReader in = new BufferedReader(new FileReader("conf/initial-data.sql"));
conn.setAutoCommit(false); /* Turn off auto commit so the below are done as one transaction */
String line;
while((line = in.readLine()) != null) {
Logger.info(line);
stmt.executeUpdate(line);
}
in.close();
conn.commit();

Logger.info("Database is initialized.");

} catch (SQLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}

else {
Logger.info("Database is initialized.");
}
}
}

}
33 changes: 27 additions & 6 deletions app/controllers/Application.java 100644 → 100755
@@ -1,14 +1,35 @@
package controllers;

import java.util.Arrays;
import java.util.Date;
import java.util.Set;

import models.GeoTag;
import models.Tag;
import models.Country;
import models.User;
import play.data.Form;
import play.data.validation.Constraints.Pattern;
import play.data.validation.Constraints.Required;
import play.db.ebean.Transactional;
import play.mvc.Controller;
import play.mvc.Result;

import com.avaje.ebean.Ebean;
import com.avaje.ebean.SqlQuery;

import play.*;
import play.mvc.*;

import views.html.*;

public class Application extends Controller {

public static Result index() {
return ok(index.render("Your new application is ready."));
}


public static Result index() {
return ok(index.render());
}

public static Result about() {
return ok(about.render());
}

}
17 changes: 17 additions & 0 deletions app/controllers/Countries.java
@@ -0,0 +1,17 @@
package controllers;

import models.Country;
import java.util.List;
import play.*;
import play.mvc.*;
import views.html.*;
import static play.libs.Json.toJson;

public class Countries extends Controller {

public static Result tags(String query) {
List<Country> tags = Country.find.where().ilike("name", "%" + query + "%").findList();
return ok(toJson(tags));
}

}
116 changes: 116 additions & 0 deletions app/controllers/Geotag.java
@@ -0,0 +1,116 @@
package controllers;

import java.util.Arrays;
import java.util.Date;
import java.util.Set;

import models.Country;
import models.GeoTag;
import models.Tag;
import models.User;
import play.api.libs.json.JsValue;
import play.api.libs.json.Json;
import play.data.Form;
import play.data.validation.Constraints.Pattern;
import play.data.validation.Constraints.Required;
import play.db.ebean.Transactional;
import play.mvc.Controller;
import play.mvc.Result;

import play.*;
import play.mvc.*;
import views.html.*;


public class Geotag extends Controller {

public static class TagIn {

/*
* Enterprise ID as submitted by user
*/
@Required
public String enterprise_id;

/*
* Latitude,Longitude string
*/
@Required
@Pattern(value = "[0-9.-]+,[0-9.-]+", message = "A valid location (Lat/Long) is required")
public String location;

/*
* CSV field of tag_id
*/
@Required
@Pattern(value = "[0-9,]+", message = "A valid set of tags must be supplied")
public String tags;

public String newtags;

public Set<Tag> getTagObjects() {
return Tag.find.where().idIn(Arrays.asList(this.tags.split(",")))
.findSet();
}

public double getLatitude() {
return Double.parseDouble(location.split(",")[0]);
}

public double getLongitude() {
return Double.parseDouble(location.split(",")[1]);
}

}

final static Form<TagIn> tagInForm = form(TagIn.class);

public static Result tagIn() {
return ok(tagin.render(tagInForm));

}

@Transactional
public static Result doTagIn() {

Form<TagIn> submittedForm = tagInForm.bindFromRequest();
if (submittedForm.hasErrors()) {
return badRequest(tagin.render(submittedForm));
} else {

User user = User.find.where()
.eq("enterprise_id", submittedForm.get().enterprise_id)
.findUnique();
if (user == null) {
user = new User();
user.enterprise_id = submittedForm.get().enterprise_id;
user.save();
}

GeoTag gt = new GeoTag();
gt.tags = submittedForm.get().getTagObjects();
gt.user = user;
gt.latitude = submittedForm.get().getLatitude();
gt.longitude = submittedForm.get().getLongitude();
gt.date_time = new Date();

/*
* An optimisation -- resolve the country @ tag time.
*/
Country country = Country.findCountryByLatLng(gt.latitude, gt.longitude).findUnique();
if(country != null) {
gt.country = country;
}

/*
* Ebean.save() does not work well with ManyToMany associations, so
* in addition to .save(), we also call
* .saveManyToManyAssociations()
*/
gt.save();
gt.saveManyToManyAssociations("tags");

return ok(tagin.render(submittedForm));
}
}
}
13 changes: 13 additions & 0 deletions app/controllers/Map.java
@@ -0,0 +1,13 @@
package controllers;

import play.*;
import play.mvc.*;
import views.html.*;

public class Map extends Controller {

public static Result index() {
return ok(map.render());
}

}

0 comments on commit abfcfc4

Please sign in to comment.