Skip to content
This repository has been archived by the owner on Jun 29, 2020. It is now read-only.

Commit

Permalink
initial entry
Browse files Browse the repository at this point in the history
  • Loading branch information
analytically committed Apr 11, 2012
0 parents commit aac3875
Show file tree
Hide file tree
Showing 73 changed files with 15,010 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .gitignore
@@ -0,0 +1,7 @@
logs
project/project
project/target
target
tmp
.history
dist
4 changes: 4 additions & 0 deletions README
@@ -0,0 +1,4 @@
This is your new Play 2.0 application
=====================================

This file will be packaged with your application, when using `play dist`.
150 changes: 150 additions & 0 deletions app/Global.java
@@ -0,0 +1,150 @@
import actors.ProcessCodePointOpenCsv;
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.actor.UntypedActorFactory;
import com.google.code.morphia.logging.MorphiaLoggerFactory;
import com.google.code.morphia.logging.slf4j.SLF4JLogrImplFactory;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.inject.*;
import com.yammer.metrics.Metrics;
import com.yammer.metrics.core.Counter;
import com.yammer.metrics.reporting.ConsoleReporter;
import models.PostcodeUnit;
import models.csv.CodePointOpenCsvEntry;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.dataformat.BindyType;
import org.joda.time.LocalDateTime;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import play.Application;
import play.GlobalSettings;
import play.Logger;
import play.libs.Akka;
import play.mvc.Controller;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
* @author Mathias Bogaert
*/
public class Global extends GlobalSettings {
private final List<Module> modules = Lists.newArrayList();

private Injector injector;
private CamelContext camelContext;

static {
MorphiaLoggerFactory.reset();
MorphiaLoggerFactory.registerLogger(SLF4JLogrImplFactory.class);
}

@Override
public void beforeStart(final Application application) {
final Reflections reflections = new Reflections(new ConfigurationBuilder()
.addUrls(ClasspathHelper.forPackage("modules", application.classloader()))
.addScanners(
new SubTypesScanner(),
new TypeAnnotationsScanner()
));

Set<Class<? extends AbstractModule>> guiceModules = reflections.getSubTypesOf(AbstractModule.class);
for (Class<? extends Module> moduleClass : guiceModules) {
try {
if (!moduleClass.isAnonymousClass()) {
modules.add(moduleClass.newInstance());
}
} catch (InstantiationException | IllegalAccessException e) {
throw Throwables.propagate(e);
}
}

modules.add(new AbstractModule() {
@Override
protected void configure() {
bind(Application.class).toInstance(application);
bind(Reflections.class).toInstance(reflections);

for (Class<? extends Controller> controller : reflections.getSubTypesOf(Controller.class)) {
requestStaticInjection(controller);
}
}
});
}

@Override
public void onStart(Application app) {
Logger.info("Creating injector with " + modules.size() + " modules.");
injector = Guice.createInjector(Stage.PRODUCTION, modules);

ConsoleReporter.enable(1, TimeUnit.MINUTES);

final ActorRef processActorRef = Akka.system().actorOf(new Props(new UntypedActorFactory() {
public ProcessCodePointOpenCsv create() {
return injector.getInstance(ProcessCodePointOpenCsv.class);
}
}), "process-codepoint-open-csv-entry");

camelContext = injector.getInstance(CamelContext.class);
try {
camelContext.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {

from("file://codepointopen/")
.unmarshal().bindy(BindyType.Csv, "models.csv")
.split(body())
.process(new Processor() {
@SuppressWarnings("unchecked")
@Override
public void process(Exchange exchange) throws Exception {
Object body = exchange.getIn().getBody();

if (body instanceof Map) {
Map<String, CodePointOpenCsvEntry> csvEntryMap = (Map<String, CodePointOpenCsvEntry>) body;

for (CodePointOpenCsvEntry entry : csvEntryMap.values()) {
processActorRef.tell(entry);
}
} else {
throw new RuntimeException("something went wrong; message body is no map!");
}
}
});
}
});
} catch (Exception e) {
Logger.error(e.getMessage(), e);
}

try {
camelContext.start();
} catch (Exception e) {
Logger.error("Exception starting Apache Camel context: " + e.getMessage(), e);

throw Throwables.propagate(e);
}
}

@Override
public void onStop(Application app) {
if (camelContext != null) {
try {
camelContext.stop();
} catch (Exception e) {
Logger.error("Exception stopping Apache Camel context: " + e.getMessage(), e);

throw Throwables.propagate(e);
}
}
}
}
93 changes: 93 additions & 0 deletions app/actors/ProcessCodePointOpenCsv.java
@@ -0,0 +1,93 @@
package actors;

import akka.actor.UntypedActor;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import com.google.common.base.CharMatcher;
import com.google.common.base.Throwables;
import com.mongodb.MongoException;
import com.yammer.metrics.Metrics;
import com.yammer.metrics.core.Counter;
import com.yammer.metrics.core.Timer;
import com.yammer.metrics.core.TimerContext;
import models.CartesianLocation;
import models.Location;
import models.PostcodeUnit;
import models.csv.CodePointOpenCsvEntry;
import org.geotools.geometry.GeneralDirectPosition;
import org.geotools.measure.AngleFormat;
import org.geotools.referencing.ReferencingFactoryFinder;
import org.geotools.referencing.operation.DefaultCoordinateOperationFactory;
import org.opengis.geometry.DirectPosition;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CRSAuthorityFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.CoordinateOperation;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

/**
* @author Mathias Bogaert
*/
public class ProcessCodePointOpenCsv extends UntypedActor {
private CoordinateOperation coordinateOperation;

private final Counter postcodesProcessed = Metrics.newCounter(ProcessCodePointOpenCsv.class, "postcodes-processed");
private final Timer latLongTransform = Metrics.newTimer(ProcessCodePointOpenCsv.class, "latitude-longitude-transform", TimeUnit.MILLISECONDS, TimeUnit.MILLISECONDS);
private final Timer savePostcodeUnit = Metrics.newTimer(ProcessCodePointOpenCsv.class, "save-postcode-unit-mongodb", TimeUnit.MILLISECONDS, TimeUnit.MILLISECONDS);

@Override
public void preStart() {
CRSAuthorityFactory crsFac = ReferencingFactoryFinder.getCRSAuthorityFactory("EPSG", null);

try {
CoordinateReferenceSystem wgs84crs = crsFac.createCoordinateReferenceSystem("4326");
CoordinateReferenceSystem osgbCrs = crsFac.createCoordinateReferenceSystem("27700");

coordinateOperation = new DefaultCoordinateOperationFactory().createOperation(osgbCrs, wgs84crs);
} catch (FactoryException e) {
throw Throwables.propagate(e);
}
}

@Override
public void onReceive(Object message) throws Exception {
if (message instanceof CodePointOpenCsvEntry) {
CodePointOpenCsvEntry entry = (CodePointOpenCsvEntry) message;

PostcodeUnit unit = new PostcodeUnit(CharMatcher.WHITESPACE.removeFrom(entry.getPostcode()));
unit.pqi = entry.getPositionalQualityIndicator();
unit.cartesianLocation = new CartesianLocation(Integer.parseInt(entry.getEastings()), Integer.parseInt(entry.getNorthings()));

final TimerContext latLongCtx = latLongTransform.time();
try {
DirectPosition eastNorth = new GeneralDirectPosition(Integer.parseInt(entry.getEastings()), Integer.parseInt(entry.getNorthings()));
DirectPosition latLng = coordinateOperation.getMathTransform().transform(eastNorth, eastNorth);

unit.location = new Location(round(latLng.getOrdinate(0), 7), round(latLng.getOrdinate(1), 7));
} finally {
latLongCtx.stop();
}

final TimerContext saveCtx = savePostcodeUnit.time();
try {
unit.save();

postcodesProcessed.inc();
} catch (MongoException.DuplicateKey e) {
// ignore
} finally {
saveCtx.stop();
}
}
}

public static double round(double valueToRound, int numberOfDecimalPlaces) {
double multipicationFactor = Math.pow(10, numberOfDecimalPlaces);
double interestedInZeroDPs = valueToRound * multipicationFactor;
return Math.round(interestedInZeroDPs) / multipicationFactor;
}
}
28 changes: 28 additions & 0 deletions app/assets/stylesheets/accordion.less
@@ -0,0 +1,28 @@
// ACCORDION
// ---------


// Parent container
.accordion {
margin-bottom: @baseLineHeight;
}

// Group == heading + body
.accordion-group {
margin-bottom: 2px;
border: 1px solid #e5e5e5;
.border-radius(4px);
}
.accordion-heading {
border-bottom: 0;
}
.accordion-heading .accordion-toggle {
display: block;
padding: 8px 15px;
}

// Inner needs the styles because you can't animate properly with any styles on the element
.accordion-inner {
padding: 9px 15px;
border-top: 1px solid #e5e5e5;
}
58 changes: 58 additions & 0 deletions app/assets/stylesheets/alerts.less
@@ -0,0 +1,58 @@
// ALERT STYLES
// ------------

// Base alert styles
.alert {
padding: 8px 35px 8px 14px;
margin-bottom: @baseLineHeight;
text-shadow: 0 1px 0 rgba(255,255,255,.5);
background-color: @warningBackground;
border: 1px solid @warningBorder;
.border-radius(4px);
color: @warningText;
}
.alert-heading {
color: inherit;
}

// Adjust close link position
.alert .close {
position: relative;
top: -2px;
right: -21px;
line-height: 18px;
}

// Alternate styles
// ----------------

.alert-success {
background-color: @successBackground;
border-color: @successBorder;
color: @successText;
}
.alert-danger,
.alert-error {
background-color: @errorBackground;
border-color: @errorBorder;
color: @errorText;
}
.alert-info {
background-color: @infoBackground;
border-color: @infoBorder;
color: @infoText;
}

// Block alerts
// ------------------------
.alert-block {
padding-top: 14px;
padding-bottom: 14px;
}
.alert-block > p,
.alert-block > ul {
margin-bottom: 0;
}
.alert-block p + p {
margin-top: 5px;
}

0 comments on commit aac3875

Please sign in to comment.