├── src
├── main
│ ├── webapp
│ │ ├── META-INF
│ │ │ └── MANIFEST.MF
│ │ ├── index.html
│ │ └── WEB-INF
│ │ │ ├── appengine-web.xml
│ │ │ └── web.xml
│ ├── sproutcore
│ │ ├── apps
│ │ │ └── oeffi_npc
│ │ │ │ ├── resources
│ │ │ │ ├── templates
│ │ │ │ │ ├── network_plan.handlebars
│ │ │ │ │ ├── oeffi_npc.handlebars
│ │ │ │ │ └── entry.handlebars
│ │ │ │ ├── images
│ │ │ │ │ ├── linz.png
│ │ │ │ │ ├── linz_bw.png
│ │ │ │ │ ├── bonn_schnellverkehr.png
│ │ │ │ │ └── bonn_schnellverkehr_bw.png
│ │ │ │ ├── stylesheets
│ │ │ │ │ └── oeffi_npc.css
│ │ │ │ └── main_page.js
│ │ │ │ ├── statechart
│ │ │ │ ├── statechart.js
│ │ │ │ ├── loading_state.js
│ │ │ │ ├── show_network_plans_state.js
│ │ │ │ └── show_network_state_state.js
│ │ │ │ ├── models
│ │ │ │ ├── record_status_mixin.js
│ │ │ │ ├── network_plan_model.js
│ │ │ │ └── network_plan_entry_model.js
│ │ │ │ ├── oeffi_npc.js
│ │ │ │ ├── controllers
│ │ │ │ ├── network_plan_controller.js
│ │ │ │ ├── network_plans_controller.js
│ │ │ │ ├── network_plan_entry_controller.js
│ │ │ │ ├── network_plan_entries_controller.js
│ │ │ │ └── network_plan_view_controller.js
│ │ │ │ ├── tests
│ │ │ │ └── controllers
│ │ │ │ │ ├── network_plan_test.js
│ │ │ │ │ ├── network_plans_test.js
│ │ │ │ │ ├── network_plan_entry_test.js
│ │ │ │ │ └── network_plan_entries_test.js
│ │ │ │ ├── views
│ │ │ │ ├── image_view.js
│ │ │ │ ├── magnifier_view.js
│ │ │ │ └── network_plan_view.js
│ │ │ │ ├── fixtures
│ │ │ │ ├── network_plan_fixtures.js
│ │ │ │ └── network_plan_entry_fixtures.js
│ │ │ │ └── data_sources
│ │ │ │ └── rest_data_source.js
│ │ ├── README
│ │ └── Buildfile
│ ├── resources
│ │ ├── com
│ │ │ └── pangratz
│ │ │ │ └── oeffinpc
│ │ │ │ └── template.tfl
│ │ ├── META-INF
│ │ │ ├── persistence.xml
│ │ │ └── jdoconfig.xml
│ │ ├── logging.properties
│ │ └── log4j.properties
│ └── java
│ │ └── com
│ │ └── pangratz
│ │ └── oeffinpc
│ │ ├── model
│ │ ├── PMF.java
│ │ ├── NetworkPlan.java
│ │ ├── NetworkPlanEntry.java
│ │ └── ModelUtils.java
│ │ ├── rest
│ │ ├── OeffiNetworkPlanCuratorApplication.java
│ │ ├── NetworkPlansResource.java
│ │ ├── OeffiNpcServerResource.java
│ │ ├── NetworkPlanEntryResource.java
│ │ ├── NetworkPlanEntriesResource.java
│ │ └── NetworkPlanResource.java
│ │ └── util
│ │ └── CsvUtils.java
└── test
│ ├── java
│ └── com
│ │ └── pangratz
│ │ └── oeffinpc
│ │ ├── util
│ │ └── CsvUtilTest.java
│ │ ├── rest
│ │ └── PostFileTest.java
│ │ └── model
│ │ └── ModelUtilsTest.java
│ └── resources
│ ├── bonn_schnellverkehr.csv
│ └── berlin_tram.csv
├── .gitignore
├── README.md
├── run_server.js
├── run_dev_server.js
├── gae-deploy.sh
└── pom.xml
/src/main/webapp/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Class-Path:
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/resources/templates/network_plan.handlebars:
--------------------------------------------------------------------------------
1 | {{networkId}}
--------------------------------------------------------------------------------
/src/main/webapp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | öffi Networkplan Curator
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | target
3 |
4 | .project
5 | .classpath
6 | .settings
7 |
8 | src/main/sproutcore/tmp
9 |
10 | node_modules/
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/resources/images/linz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pangratz/oeffi-networkplan-curator/dev/src/main/sproutcore/apps/oeffi_npc/resources/images/linz.png
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/resources/images/linz_bw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pangratz/oeffi-networkplan-curator/dev/src/main/sproutcore/apps/oeffi_npc/resources/images/linz_bw.png
--------------------------------------------------------------------------------
/src/main/resources/com/pangratz/oeffinpc/template.tfl:
--------------------------------------------------------------------------------
1 | <#list entries as planEntry>
2 | ${networkPlan.networkId}|${planEntry.stationId}|${planEntry.name}|${networkPlan.planId}|${planEntry.x?c}|${planEntry.y?c}
3 | #list>
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/resources/images/bonn_schnellverkehr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pangratz/oeffi-networkplan-curator/dev/src/main/sproutcore/apps/oeffi_npc/resources/images/bonn_schnellverkehr.png
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/resources/images/bonn_schnellverkehr_bw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pangratz/oeffi-networkplan-curator/dev/src/main/sproutcore/apps/oeffi_npc/resources/images/bonn_schnellverkehr_bw.png
--------------------------------------------------------------------------------
/src/main/sproutcore/README:
--------------------------------------------------------------------------------
1 | ==========================================================================
2 | Project: OeffiNpc
3 | Copyright: @2011 My Company, Inc.
4 | ==========================================================================
5 |
6 | TODO: Describe Your Project
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 | This webapp lets you create and edit the csv files of networkplans which are needed by [Öffi](http://oeffi.schildbach.de/) to make the network plans interactive. The idea for this webapp was born by [this](http://twitter.com/oeffi/status/83913809521164289) Tweet.
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/resources/stylesheets/oeffi_npc.css:
--------------------------------------------------------------------------------
1 | /* ==========================================================================
2 | * Project: OeffiNpc
3 | * Copyright: @2011 My Company, Inc.
4 | * ==========================================================================
5 | */
6 |
7 | /*.sc-view {
8 | position: relative;
9 | overflow: visible;
10 | }*/
11 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/statechart/statechart.js:
--------------------------------------------------------------------------------
1 | /*globals OeffiNpc*/
2 |
3 | OeffiNpc.statechart = SC.Statechart.create({
4 |
5 | trace: YES,
6 | initialState: 'loading',
7 |
8 | loading: SC.State.plugin('OeffiNpc.LoadingState'),
9 | showNetworkPlans: SC.State.plugin('OeffiNpc.ShowNetworkPlansState'),
10 | showNetworkPlan: SC.State.plugin('OeffiNpc.ShowNetworkPlanState')
11 |
12 | });
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/resources/templates/oeffi_npc.handlebars:
--------------------------------------------------------------------------------
1 | {{#view SC.LabelView valueBinding="OeffiNpc.networkPlansController.numberOfNetworkPlans"}}{{/view}}
2 |
3 | {{#view SC.LabelView valueBinding="OeffiNpc.networkPlanController"}}{{/view}}
4 |
5 | {{#view SC.LabelView valueBinding="OeffiNpc.networkPlanEntriesController.length"}}{{/view}}
6 |
7 | {{#view SC.ListView contentBinding="OeffiNpc.networkPlansController" }}{{/view}}
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/models/record_status_mixin.js:
--------------------------------------------------------------------------------
1 | /*globals OeffiNpc*/
2 | /**
3 |
4 | A mixin which adds a `recordStatusString` method to a SC.Record, and which returns
5 | a readable representation of a record's status. This is quite handy during developing.
6 |
7 | */
8 | OeffiNpc.RecordStatusMixin = {
9 |
10 | recordStatusString: function(){
11 | return this.statusString();
12 | }.property('status')
13 |
14 | };
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/resources/templates/entry.handlebars:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Name: {{entry.name}}
4 |
5 |
6 |
_id: {{entry._id}}
7 |
8 |
9 |
Status: {{entry.status}}
10 |
11 |
12 |
Id: {{entry.stationId}}
13 |
14 |
17 |
20 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/statechart/loading_state.js:
--------------------------------------------------------------------------------
1 | /*globals OeffiNpc*/
2 |
3 | OeffiNpc.LoadingState = SC.State.extend({
4 |
5 | enterState: function() {
6 | var query = SC.Query.local(OeffiNpc.NetworkPlan, {
7 | orderBy: 'networkId ASC'
8 | });
9 | var networkPlans = OeffiNpc.store.find(query);
10 | OeffiNpc.networkPlansController.set('content', networkPlans);
11 |
12 | this.gotoState('showNetworkPlans');
13 | }
14 |
15 | });
--------------------------------------------------------------------------------
/src/main/java/com/pangratz/oeffinpc/model/PMF.java:
--------------------------------------------------------------------------------
1 | package com.pangratz.oeffinpc.model;
2 |
3 | import javax.jdo.JDOHelper;
4 | import javax.jdo.PersistenceManagerFactory;
5 |
6 | public final class PMF {
7 | private static final PersistenceManagerFactory pmfInstance = JDOHelper
8 | .getPersistenceManagerFactory("transactions-optional");
9 |
10 | public static PersistenceManagerFactory get() {
11 | return pmfInstance;
12 | }
13 |
14 | private PMF() {
15 | }
16 | }
--------------------------------------------------------------------------------
/src/main/sproutcore/Buildfile:
--------------------------------------------------------------------------------
1 | # ==========================================================================
2 | # Project: OeffiNpc
3 | # Copyright: @2011 My Company, Inc.
4 | # ==========================================================================
5 |
6 | # Add initial buildfile information here
7 | config :all,
8 | :required => [:sproutcore, "sproutcore/statechart"]
9 |
10 | proxy '/static', :to => 'oeffinpc.appspot.com'
11 | proxy '/', :to => 'localhost:3000'
12 |
13 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/oeffi_npc.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc */
6 |
7 | OeffiNpc = SC.Application.create({
8 | store: SC.Store.create({commitRecordsAutomatically: YES}).from('OeffiNpc.RestDataSource')
9 | });
10 |
11 | SC.ready(function() {
12 | OeffiNpc.statechart.initStatechart();
13 | });
14 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/appengine-web.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | oeffinpc
6 | test
7 |
8 |
9 |
10 |
11 |
12 | true
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/controllers/network_plan_controller.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.networkPlanController
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc */
6 |
7 | /** @class
8 |
9 | (Document Your Controller Here)
10 |
11 | @extends SC.Object
12 | */
13 | OeffiNpc.networkPlanController = SC.ObjectController.create(
14 | /** @scope OeffiNpc.networkPlanController.prototype */ {
15 |
16 | contentBinding: 'OeffiNpc.networkPlansController.selection'
17 |
18 | });
19 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/tests/controllers/network_plan_test.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.networkPlanController Unit Test
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc module test ok equals same stop start */
6 |
7 | module("OeffiNpc.networkPlanController");
8 |
9 | // TODO: Replace with real unit test for OeffiNpc.networkPlanController
10 | test("test description", function() {
11 | var expected = "test";
12 | var result = "test";
13 | equals(result, expected, "test should equal test");
14 | });
15 |
16 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/models/network_plan_model.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.NetworkPlan
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc */
6 |
7 | /** @class
8 |
9 | (Document your Model here)
10 |
11 | @extends SC.Record
12 | @version 0.1
13 | */
14 | OeffiNpc.NetworkPlan = SC.Record.extend(
15 | /** @scope OeffiNpc.NetworkPlan.prototype */ {
16 |
17 | primaryKey: 'key',
18 | networkId: SC.Record.attr(String),
19 | planId: SC.Record.attr(String),
20 | imageUrl: SC.Record.attr(String)
21 |
22 | }) ;
23 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/tests/controllers/network_plans_test.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.networkPlansController Unit Test
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc module test ok equals same stop start */
6 |
7 | module("OeffiNpc.networkPlansController");
8 |
9 | // TODO: Replace with real unit test for OeffiNpc.networkPlansController
10 | test("test description", function() {
11 | var expected = "test";
12 | var result = "test";
13 | equals(result, expected, "test should equal test");
14 | });
15 |
16 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/tests/controllers/network_plan_entry_test.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.networkPlanEntryController Unit Test
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc module test ok equals same stop start */
6 |
7 | module("OeffiNpc.networkPlanEntryController");
8 |
9 | // TODO: Replace with real unit test for OeffiNpc.networkPlanEntryController
10 | test("test description", function() {
11 | var expected = "test";
12 | var result = "test";
13 | equals(result, expected, "test should equal test");
14 | });
15 |
16 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/tests/controllers/network_plan_entries_test.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.networkPlanEntriesController Unit Test
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc module test ok equals same stop start */
6 |
7 | module("OeffiNpc.networkPlanEntriesController");
8 |
9 | // TODO: Replace with real unit test for OeffiNpc.networkPlanEntriesController
10 | test("test description", function() {
11 | var expected = "test";
12 | var result = "test";
13 | equals(result, expected, "test should equal test");
14 | });
15 |
16 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/views/image_view.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.ImageView
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc */
6 |
7 | /** @class
8 |
9 | (Document Your View Here)
10 | */
11 | OeffiNpc.ImageViewMixin = {
12 |
13 | scale: 1.0,
14 |
15 | _imageChanged: function(){
16 | var image = this.get('image');
17 | if (image) {
18 | var layout = {
19 | width: this.scale * image.width,
20 | height: this.scale * image.height
21 | };
22 | this.set('layout', layout);
23 | }
24 | }.observes('image')
25 |
26 | };
27 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/controllers/network_plans_controller.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.networkPlansController
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc */
6 |
7 | /** @class
8 |
9 | (Document Your Controller Here)
10 |
11 | @extends SC.Object
12 | */
13 | OeffiNpc.networkPlansController = SC.ArrayController.create(
14 | /** @scope OeffiNpc.networkPlansController.prototype */ {
15 |
16 | content: [],
17 | allowsMultipleSelection: YES,
18 |
19 | numberOfNetworkPlans: function(){
20 | return this.get('length') + ' network plans';
21 | }.property('length')
22 |
23 | });
24 |
--------------------------------------------------------------------------------
/src/main/java/com/pangratz/oeffinpc/rest/OeffiNetworkPlanCuratorApplication.java:
--------------------------------------------------------------------------------
1 | package com.pangratz.oeffinpc.rest;
2 |
3 | import org.restlet.Application;
4 | import org.restlet.Restlet;
5 | import org.restlet.routing.Router;
6 |
7 | public class OeffiNetworkPlanCuratorApplication extends Application {
8 |
9 | @Override
10 | public Restlet createInboundRoot() {
11 | Router router = new Router(getContext());
12 | router.attach("/networkplans", NetworkPlansResource.class);
13 | router.attach("/networkplans/{networkPlanId}", NetworkPlanResource.class);
14 | router.attach("/networkplans/{networkPlanId}/_entries", NetworkPlanEntriesResource.class);
15 | router.attach("/networkplanentries/{stationId}", NetworkPlanEntryResource.class);
16 | return router;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/controllers/network_plan_entry_controller.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.networkPlanEntryController
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc */
6 |
7 | /** @class
8 |
9 | (Document Your Controller Here)
10 |
11 | @extends SC.Object
12 | */
13 | OeffiNpc.networkPlanEntryController = SC.ObjectController.create(
14 | /** @scope OeffiNpc.networkPlanEntryController.prototype */ {
15 |
16 | contentBinding: 'OeffiNpc.networkPlanEntriesController.selection',
17 |
18 | networkEntryDidChange: function(){
19 | OeffiNpc.statechart.sendEvent('networkEntrySelected');
20 | }.observes('content')
21 |
22 | });
23 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/controllers/network_plan_entries_controller.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.networkPlanEntriesController
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc */
6 |
7 | /** @class
8 |
9 | (Document Your Controller Here)
10 |
11 | @extends SC.Object
12 | */
13 | OeffiNpc.networkPlanEntriesController = SC.ArrayController.create(
14 | /** @scope OeffiNpc.networkPlanEntriesController.prototype */ {
15 |
16 | isEditable: YES,
17 | destroyOnRemoval: YES,
18 | allowsMultipleSelection: NO,
19 | content: [],
20 |
21 | numberOfNetworkPlanEntries: function(){
22 | return this.get('length') + ' entries';
23 | }.property('length')
24 |
25 | });
26 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/persistence.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/models/network_plan_entry_model.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.NetworkPlanEntry
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc */
6 |
7 | /** @class
8 |
9 | (Document your Model here)
10 |
11 | @extends SC.Record
12 | @version 0.1
13 | */
14 | sc_require('models/record_status_mixin');
15 |
16 | OeffiNpc.NetworkPlanEntry = SC.Record.extend(OeffiNpc.RecordStatusMixin,
17 | /** @scope OeffiNpc.NetworkPlanEntry.prototype */ {
18 |
19 | primaryKey: 'key',
20 | stationId: SC.Record.attr(String),
21 | name: SC.Record.attr(String),
22 | x: SC.Record.attr(Number),
23 | y: SC.Record.attr(Number),
24 | networkPlanKey: SC.Record.attr(String)
25 |
26 | });
27 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/statechart/show_network_plans_state.js:
--------------------------------------------------------------------------------
1 | /*globals OeffiNpc*/
2 |
3 | OeffiNpc.ShowNetworkPlansState = SC.State.extend({
4 |
5 | enterState: function(){
6 | this.set('pane', OeffiNpc.getPath('mainPage.listNetworkPlansPane').append());
7 | },
8 |
9 | exitState: function(){
10 | this.get('pane').remove();
11 | },
12 |
13 | networkPlanSelected: function() {
14 | var key = OeffiNpc.networkPlanController.get('id');
15 | if (key) {
16 | var query = SC.Query.local(OeffiNpc.NetworkPlanEntry, {
17 | orderBy: 'name',
18 | conditions: "networkPlanKey = '" + key + "'",
19 | parameters: {
20 | networkPlanKey: key
21 | }
22 | });
23 | var entries = OeffiNpc.store.find(query);
24 | OeffiNpc.networkPlanEntriesController.set('content', entries);
25 |
26 | this.gotoState('showNetworkPlan');
27 | }
28 | }
29 |
30 | });
--------------------------------------------------------------------------------
/src/test/java/com/pangratz/oeffinpc/util/CsvUtilTest.java:
--------------------------------------------------------------------------------
1 | package com.pangratz.oeffinpc.util;
2 |
3 | import java.io.InputStream;
4 | import java.util.List;
5 |
6 | import junit.framework.TestCase;
7 |
8 | import com.pangratz.oeffinpc.model.NetworkPlanEntry;
9 |
10 | public class CsvUtilTest extends TestCase {
11 |
12 | private CsvUtils csvUtils;
13 |
14 | public void testReadCsv() {
15 | InputStream inputStream = CsvUtilTest.class.getResourceAsStream("/bonn_schnellverkehr.csv");
16 | List entries = this.csvUtils.readCsv(inputStream);
17 | assertNotNull(entries);
18 | assertTrue(entries.size() > 0);
19 | }
20 |
21 | @Override
22 | protected void setUp() throws Exception {
23 | super.setUp();
24 | this.csvUtils = CsvUtils.getInstance();
25 | }
26 |
27 | @Override
28 | protected void tearDown() throws Exception {
29 | super.tearDown();
30 | this.csvUtils = null;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/fixtures/network_plan_fixtures.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.NetworkPlan Fixtures
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc */
6 |
7 | sc_require('models/network_plan_model');
8 |
9 | OeffiNpc.NetworkPlan.FIXTURES = [
10 |
11 | {
12 | guid: 'linz',
13 | networkId: 'linz',
14 | planId: 'linz',
15 | imageUrl: 'http://oeffi.schildbach.de/plans/linz.png',
16 | imageWidth: 1114,
17 | imageHeight: 1618,
18 | entries: ['schumpeterstrasse', 'taubenmarkt']
19 | },
20 |
21 | {
22 | guid: 'bonn',
23 | networkId: 'bonn',
24 | planId: 'bonn',
25 | imageUrl: 'http://oeffi.schildbach.de/plans/bonn_schnellverkehr.png',
26 | imageWidth: 2338,
27 | imageHeight: 1653,
28 | entries: ['landesmuseum', 'innsbruck_hauptbahnhof']
29 | }
30 |
31 | ];
32 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/jdoconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/controllers/network_plan_view_controller.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.networkPlanViewController
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc */
6 |
7 | /** @class
8 |
9 | (Document Your Controller Here)
10 |
11 | @extends SC.Object
12 | */
13 | OeffiNpc.networkPlanViewController = SC.ObjectController.create(
14 | /** @scope OeffiNpc.networkPlanViewController.prototype */ {
15 |
16 | cursorPosition: {
17 | x: undefined,
18 | y: undefined
19 | },
20 | zoom: NO,
21 | zoomScale: 2.0,
22 |
23 | scrollPosition: {
24 | x: undefined,
25 | y: undefined
26 | },
27 |
28 | cursorPositionString: function() {
29 | var pos = this.get('cursorPosition');
30 | if (pos) {
31 | return '%@1/%@2'.fmt(pos.x, pos.y);
32 | }
33 | return undefined;
34 | }.property('cursorPosition')
35 |
36 | });
37 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/views/magnifier_view.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.MagnifierView
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc */
6 |
7 | /** @class
8 |
9 | (Document Your View Here)
10 |
11 | @extends SC.View
12 | */
13 | OeffiNpc.MagnifierView = SC.ImageView.extend(OeffiNpc.ImageViewMixin,
14 | /** @scope OeffiNpc.MagnifierView.prototype */ {
15 |
16 | scale: 0.5,
17 |
18 | positionChanged: function(){
19 | var pos = this.get('position');
20 | if (pos) {
21 | var scrollView = this.get('parentView').get('parentView');
22 | var parentLayout = scrollView.get('layout');
23 | var scrollTo = {
24 | x: this.scale * pos.x - (parentLayout.width / 2),
25 | y: this.scale * pos.y - (parentLayout.height / 2)
26 | };
27 | scrollView.scrollTo(scrollTo);
28 | }
29 | }.observes('position')
30 |
31 | });
32 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 | RestletServlet
9 | org.restlet.ext.servlet.ServerServlet
10 |
11 | org.restlet.application
12 | com.pangratz.oeffinpc.rest.OeffiNetworkPlanCuratorApplication
13 |
14 |
15 |
16 |
17 |
18 | RestletServlet
19 | /*
20 |
21 |
22 |
23 | static/oeffi_npc/en/build/index.html
24 |
25 |
--------------------------------------------------------------------------------
/src/main/resources/logging.properties:
--------------------------------------------------------------------------------
1 | # A default java.util.logging configuration.
2 | # (All App Engine logging is through java.util.logging by default).
3 | #
4 | # To use this configuration, copy it into your application's WEB-INF
5 | # folder and add the following to your appengine-web.xml:
6 | #
7 | #
8 | #
9 | #
10 | #
11 |
12 | # Set the default logging level for all loggers to WARNING
13 | .level = WARNING
14 |
15 | # Set the default logging level for ORM, specifically, to WARNING
16 | DataNucleus.JDO.level=WARNING
17 | DataNucleus.Persistence.level=WARNING
18 | DataNucleus.Cache.level=WARNING
19 | DataNucleus.MetaData.level=WARNING
20 | DataNucleus.General.level=WARNING
21 | DataNucleus.Utility.level=WARNING
22 | DataNucleus.Transaction.level=WARNING
23 | DataNucleus.Datastore.level=WARNING
24 | DataNucleus.ClassLoading.level=WARNING
25 | DataNucleus.Plugin.level=WARNING
26 | DataNucleus.ValueGeneration.level=WARNING
27 | DataNucleus.Enhancer.level=WARNING
28 | DataNucleus.SchemaTool.level=WARNING
29 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/fixtures/network_plan_entry_fixtures.js:
--------------------------------------------------------------------------------
1 | // ==========================================================================
2 | // Project: OeffiNpc.NetworkplanEntry Fixtures
3 | // Copyright: @2011 My Company, Inc.
4 | // ==========================================================================
5 | /*globals OeffiNpc */
6 |
7 | sc_require('models/network_plan_entry_model');
8 |
9 | OeffiNpc.NetworkPlanEntry.FIXTURES = [
10 |
11 | {
12 | guid: 'schumpeterstrasse',
13 | stationId: 491115,
14 | name: 'Linz/Donau Schumpeterstrasse',
15 | x: 200,
16 | y: 50,
17 | networkPlan: 'linz'
18 | },
19 |
20 | {
21 | guid: 'taubenmarkt',
22 | stationId: 491106,
23 | name: 'Linz/Donau Taubenmarkt',
24 | x: 50,
25 | y: 150,
26 | networkPlan: 'linz'
27 | },
28 |
29 | {
30 | guid: 'landesmuseum',
31 | stationId: 123,
32 | name: 'Innsbruck Landesmuseum',
33 | x: 40,
34 | y: 50,
35 | networkPlan: 'innsbruck'
36 | },
37 |
38 | {
39 | guid: 'innsbruck_hauptbahnhof',
40 | stationId: 456,
41 | name: 'Innsbruck Hauptbahnhof',
42 | x: 10,
43 | y: 15,
44 | networkPlan: 'innsbruck'
45 | }
46 |
47 | ];
48 |
--------------------------------------------------------------------------------
/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | # A default log4j configuration for log4j users.
2 | #
3 | # To use this configuration, deploy it into your application's WEB-INF/classes
4 | # directory. You are also encouraged to edit it as you like.
5 |
6 | # Configure the console as our one appender
7 | log4j.appender.A1=org.apache.log4j.ConsoleAppender
8 | log4j.appender.A1.layout=org.apache.log4j.PatternLayout
9 | log4j.appender.A1.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n
10 |
11 | # tighten logging on the DataNucleus Categories
12 | log4j.category.DataNucleus.JDO=WARN, A1
13 | log4j.category.DataNucleus.Persistence=WARN, A1
14 | log4j.category.DataNucleus.Cache=WARN, A1
15 | log4j.category.DataNucleus.MetaData=WARN, A1
16 | log4j.category.DataNucleus.General=WARN, A1
17 | log4j.category.DataNucleus.Utility=WARN, A1
18 | log4j.category.DataNucleus.Transaction=WARN, A1
19 | log4j.category.DataNucleus.Datastore=WARN, A1
20 | log4j.category.DataNucleus.ClassLoading=WARN, A1
21 | log4j.category.DataNucleus.Plugin=WARN, A1
22 | log4j.category.DataNucleus.ValueGeneration=WARN, A1
23 | log4j.category.DataNucleus.Enhancer=WARN, A1
24 | log4j.category.DataNucleus.SchemaTool=WARN, A1
25 |
--------------------------------------------------------------------------------
/src/main/java/com/pangratz/oeffinpc/util/CsvUtils.java:
--------------------------------------------------------------------------------
1 | package com.pangratz.oeffinpc.util;
2 |
3 | import java.io.InputStream;
4 | import java.io.InputStreamReader;
5 | import java.io.Reader;
6 | import java.util.LinkedList;
7 | import java.util.List;
8 |
9 | import au.com.bytecode.opencsv.CSVReader;
10 |
11 | import com.pangratz.oeffinpc.model.NetworkPlanEntry;
12 |
13 | public class CsvUtils {
14 |
15 | private static final CsvUtils instance = new CsvUtils();
16 |
17 | public static CsvUtils getInstance() {
18 | return instance;
19 | }
20 |
21 | public List readCsv(InputStream inStream) {
22 | Reader reader = new InputStreamReader(inStream);
23 | CSVReader csvReader = new CSVReader(reader, '|');
24 | String[] next = null;
25 | List entries = new LinkedList();
26 | try {
27 | while ((next = csvReader.readNext()) != null) {
28 | if (next != null && next.length == 6 && !next[0].startsWith("#")) {
29 | NetworkPlanEntry entry = new NetworkPlanEntry();
30 | entry.setStationId(next[1]);
31 | entry.setName(next[2]);
32 | entry.setX(Integer.parseInt(next[4]));
33 | entry.setY(Integer.parseInt(next[5]));
34 | entries.add(entry);
35 | }
36 | }
37 | } catch (Exception e) {
38 | throw new IllegalStateException(e);
39 | }
40 | return entries;
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/pangratz/oeffinpc/model/NetworkPlan.java:
--------------------------------------------------------------------------------
1 | package com.pangratz.oeffinpc.model;
2 |
3 | import javax.jdo.annotations.IdGeneratorStrategy;
4 | import javax.jdo.annotations.PersistenceCapable;
5 | import javax.jdo.annotations.Persistent;
6 | import javax.jdo.annotations.PrimaryKey;
7 |
8 | import org.json.JSONObject;
9 | import org.json.JSONString;
10 |
11 | @PersistenceCapable(detachable = "true")
12 | public class NetworkPlan implements JSONString {
13 |
14 | @PrimaryKey
15 | @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
16 | private Long key;
17 |
18 | @Persistent
19 | private String networkId;
20 |
21 | @Persistent
22 | private String planId;
23 |
24 | @Persistent
25 | private String imageUrl;
26 |
27 | public String getImageUrl() {
28 | return imageUrl;
29 | }
30 |
31 | public Long getKey() {
32 | return key;
33 | }
34 |
35 | public String getNetworkId() {
36 | return networkId;
37 | }
38 |
39 | public String getPlanId() {
40 | return planId;
41 | }
42 |
43 | public void setImageUrl(String imageUrl) {
44 | this.imageUrl = imageUrl;
45 | }
46 |
47 | public void setKey(Long key) {
48 | this.key = key;
49 | }
50 |
51 | public void setNetworkId(String networkId) {
52 | this.networkId = networkId;
53 | }
54 |
55 | public void setPlanId(String planId) {
56 | this.planId = planId;
57 | }
58 |
59 | @Override
60 | public String toJSONString() {
61 | return new JSONObject(this).toString();
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/sproutcore/apps/oeffi_npc/statechart/show_network_state_state.js:
--------------------------------------------------------------------------------
1 | /*globals OeffiNpc*/
2 |
3 | OeffiNpc.ShowNetworkPlanState = SC.State.extend({
4 |
5 | enterState: function(){
6 | this.set('pane', OeffiNpc.getPath('mainPage.mainPane').append());
7 | },
8 |
9 | exitState: function(){
10 | this.get('pane').remove();
11 | },
12 |
13 | backToNetworkPlans: function(){
14 | this.gotoState('showNetworkPlans');
15 | },
16 |
17 | clickedOnNetworkPlan: function(point) {
18 | OeffiNpc.networkPlanEntryController.set('x', point.x);
19 | OeffiNpc.networkPlanEntryController.set('y', point.y);
20 | },
21 |
22 | networkEntrySelected: function(){
23 | var x = OeffiNpc.networkPlanEntryController.get('x');
24 | var y = OeffiNpc.networkPlanEntryController.get('y');
25 | OeffiNpc.networkPlanViewController.set('scrollPosition', {
26 | x: x,
27 | y: y
28 | });
29 | },
30 |
31 | addEntry: function(){
32 | var networkPlanId = OeffiNpc.networkPlanController.get('id');
33 | var newEntry = OeffiNpc.store.createRecord(OeffiNpc.NetworkPlanEntry, {
34 | name: 'new entry',
35 | stationId: '',
36 | networkPlanKey: networkPlanId
37 | });
38 | },
39 |
40 | removeEntry: function(){
41 | OeffiNpc.networkPlanEntryController.destroy();
42 | },
43 |
44 | zPressed: function(){
45 | var zoom = OeffiNpc.networkPlanViewController.get('zoom');
46 | OeffiNpc.networkPlanViewController.set('zoom', !zoom);
47 | },
48 |
49 | numberPressed: function(nr) {
50 | var scale = nr * 0.5;
51 | OeffiNpc.networkPlanViewController.set('zoomScale', scale);
52 | }
53 |
54 | });
55 |
--------------------------------------------------------------------------------
/src/test/java/com/pangratz/oeffinpc/rest/PostFileTest.java:
--------------------------------------------------------------------------------
1 | package com.pangratz.oeffinpc.rest;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.InputStream;
5 |
6 | import junit.framework.TestCase;
7 |
8 | import org.apache.commons.httpclient.HttpClient;
9 | import org.apache.commons.httpclient.methods.PostMethod;
10 | import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
11 | import org.apache.commons.httpclient.methods.multipart.FilePart;
12 | import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
13 | import org.apache.commons.httpclient.methods.multipart.Part;
14 | import org.apache.commons.httpclient.methods.multipart.PartSource;
15 |
16 | public class PostFileTest extends TestCase {
17 |
18 | public void testUploadFile() {
19 | try {
20 | HttpClient httpClient = new HttpClient();
21 | String csvFileName = "/berlin_tram.csv";
22 | InputStream stream = PostFileTest.class.getResourceAsStream(csvFileName);
23 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
24 | byte[] buff = new byte[1024];
25 | while (stream.read(buff) != -1) {
26 | baos.write(buff);
27 | }
28 | PartSource fileSource = new ByteArrayPartSource(csvFileName, baos.toByteArray());
29 |
30 | PostMethod post = new PostMethod("http://localhost:8080/networkplans/3011");
31 | FilePart filePart = new FilePart(csvFileName, fileSource);
32 | filePart.setTransferEncoding("utf-8");
33 | Part[] parts = { filePart };
34 | post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
35 |
36 | httpClient.executeMethod(post);
37 | byte[] responseBody = post.getResponseBody();
38 | System.out.println(new String(responseBody));
39 | } catch (Exception ex) {
40 | ex.printStackTrace();
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/pangratz/oeffinpc/model/NetworkPlanEntry.java:
--------------------------------------------------------------------------------
1 | package com.pangratz.oeffinpc.model;
2 |
3 | import javax.jdo.annotations.IdGeneratorStrategy;
4 | import javax.jdo.annotations.PersistenceCapable;
5 | import javax.jdo.annotations.Persistent;
6 | import javax.jdo.annotations.PrimaryKey;
7 |
8 | import org.json.JSONObject;
9 | import org.json.JSONString;
10 |
11 | @PersistenceCapable(detachable = "true")
12 | public class NetworkPlanEntry implements JSONString {
13 |
14 | @PrimaryKey
15 | @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
16 | private Long key;
17 |
18 | @Persistent
19 | private Long networkPlanKey;
20 |
21 | @Persistent
22 | private String stationId;
23 |
24 | @Persistent
25 | private String name;
26 |
27 | @Persistent
28 | private int x;
29 |
30 | @Persistent
31 | private int y;
32 |
33 | public Long getKey() {
34 | return key;
35 | }
36 |
37 | public String getName() {
38 | return name;
39 | }
40 |
41 | public Long getNetworkPlanKey() {
42 | return networkPlanKey;
43 | }
44 |
45 | public String getStationId() {
46 | return stationId;
47 | }
48 |
49 | public int getX() {
50 | return x;
51 | }
52 |
53 | public int getY() {
54 | return y;
55 | }
56 |
57 | public void setKey(Long key) {
58 | this.key = key;
59 | }
60 |
61 | public void setName(String name) {
62 | this.name = name;
63 | }
64 |
65 | public void setNetworkPlanKey(Long networkPlanKey) {
66 | this.networkPlanKey = networkPlanKey;
67 | }
68 |
69 | public void setStationId(String stationId) {
70 | this.stationId = stationId;
71 | }
72 |
73 | public void setX(int x) {
74 | this.x = x;
75 | }
76 |
77 | public void setY(int y) {
78 | this.y = y;
79 | }
80 |
81 | @Override
82 | public String toJSONString() {
83 | return new JSONObject(this).toString();
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/pangratz/oeffinpc/rest/NetworkPlansResource.java:
--------------------------------------------------------------------------------
1 | package com.pangratz.oeffinpc.rest;
2 |
3 | import java.util.List;
4 |
5 | import org.json.JSONArray;
6 | import org.json.JSONObject;
7 | import org.restlet.data.MediaType;
8 | import org.restlet.data.Method;
9 | import org.restlet.data.Status;
10 | import org.restlet.ext.json.JsonRepresentation;
11 | import org.restlet.representation.Representation;
12 | import org.restlet.representation.Variant;
13 | import org.restlet.resource.ResourceException;
14 |
15 | import com.pangratz.oeffinpc.model.NetworkPlan;
16 |
17 | public class NetworkPlansResource extends OeffiNpcServerResource {
18 |
19 | @Override
20 | protected void doInit() throws ResourceException {
21 | super.doInit();
22 |
23 | getVariants(Method.GET).add(new Variant(MediaType.APPLICATION_JSON));
24 | getVariants(Method.POST).add(new Variant(MediaType.APPLICATION_JSON));
25 | }
26 |
27 | @Override
28 | protected Representation get(Variant variant) throws ResourceException {
29 | List networkPlans = mModelUtils.getNetworkPlans();
30 | if (networkPlans.isEmpty()) {
31 | setStatus(Status.CLIENT_ERROR_NOT_FOUND);
32 | return null;
33 | }
34 |
35 | JSONArray arr = new JSONArray(networkPlans);
36 | return new JsonRepresentation(arr);
37 | }
38 |
39 | @Override
40 | protected Representation post(Representation entity, Variant variant) throws ResourceException {
41 | JsonRepresentation represent;
42 | try {
43 | represent = new JsonRepresentation(entity);
44 | JSONObject json = represent.getJsonObject();
45 |
46 | NetworkPlan networkPlan = new NetworkPlan();
47 | networkPlan.setImageUrl(json.getString("imageUrl"));
48 | networkPlan.setNetworkId(json.getString("networkId"));
49 | networkPlan.setPlanId(json.getString("planId"));
50 |
51 | mModelUtils.storeNetworkPlan(networkPlan);
52 |
53 | return createResourceCreatedRepresentation(networkPlan);
54 | } catch (Exception e) {
55 | e.printStackTrace();
56 | setStatus(Status.SERVER_ERROR_INTERNAL, e);
57 | }
58 |
59 | return createErrorRepresentation("error while storing NetworkPlan");
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/com/pangratz/oeffinpc/rest/OeffiNpcServerResource.java:
--------------------------------------------------------------------------------
1 | package com.pangratz.oeffinpc.rest;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import org.restlet.data.MediaType;
7 | import org.restlet.data.Reference;
8 | import org.restlet.data.Status;
9 | import org.restlet.ext.json.JsonRepresentation;
10 | import org.restlet.representation.Representation;
11 | import org.restlet.representation.StringRepresentation;
12 | import org.restlet.representation.Variant;
13 | import org.restlet.resource.ResourceException;
14 | import org.restlet.resource.ServerResource;
15 |
16 | import com.pangratz.oeffinpc.model.ModelUtils;
17 | import com.pangratz.oeffinpc.model.NetworkPlan;
18 | import com.pangratz.oeffinpc.model.NetworkPlanEntry;
19 |
20 | public abstract class OeffiNpcServerResource extends ServerResource {
21 |
22 | protected ModelUtils mModelUtils;
23 |
24 | public OeffiNpcServerResource() {
25 | super();
26 |
27 | getVariants().add(new Variant(MediaType.APPLICATION_JSON));
28 | }
29 |
30 | protected Representation createErrorRepresentation(String errorMsg) {
31 | Map