Skip to content

Commit 3f55e5f

Browse files
committed
Add an example that adds custom method to all repos
1 parent f9e684a commit 3f55e5f

File tree

134 files changed

+9123
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

134 files changed

+9123
-0
lines changed

custom-method-all-repos/.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.DS_Store
2+
.gradle
3+
.idea
4+
*.iml
5+
build
6+
h2db
7+
target
8+
node_modules
9+
bower_components
10+
build

custom-method-all-repos/LICENSE

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Copyright 2015 Petri Kainulainen
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.

custom-method-all-repos/README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
This blog post is the example application of the following blog posts:
2+
3+
* [Spring Data JPA Tutorial: Getting the Required Dependencies](http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-getting-the-required-dependencies/)
4+
* [Spring Data JPA Tutorial: Configuration](http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-one-configuration/)
5+
* [Spring Data JPA Tutorial: CRUD](http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-two-crud/)
6+
* [Spring Data JPA Tutorial: Auditing, Part One](http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-auditing-part-one/)
7+
* [Spring Data JPA Tutorial: Auditing, Part Two](http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-auditing-part-two/)
8+
* [Spring Data JPA Tutorial: Adding Custom Methods Into All Repositories]() - Not published yet
9+
10+
Prerequisites
11+
=============
12+
13+
You need to install the following tools if you want to run this application:
14+
15+
Backend
16+
---------
17+
18+
* [JDK 8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)
19+
* [Maven](http://maven.apache.org/) (the application is tested with Maven 3.2.1)
20+
21+
Frontend
22+
----------
23+
24+
* [Node.js](http://nodejs.org/)
25+
* [NPM](https://www.npmjs.org/)
26+
* [Bower](http://bower.io/)
27+
* [Gulp](http://gulpjs.com/)
28+
29+
You can install these tools by following these steps:
30+
31+
1. Install Node.js by using a [downloaded binary](http://nodejs.org/download/) or a [package manager](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager).
32+
You can also read this blog post: [How to install Node.js and NPM](http://blog.nodeknockout.com/post/65463770933/how-to-install-node-js-and-npm)
33+
34+
2. Install Bower by using the following command:
35+
36+
npm install -g bower
37+
38+
3. Install Gulp by using the following command:
39+
40+
npm install -g gulp
41+
42+
43+
Running the Tests
44+
=================
45+
46+
You can run the unit tests by using the following command:
47+
48+
mvn clean test -P dev
49+
50+
You can run the integration tests by using the following command:
51+
52+
mvn clean verify -P integration-test
53+
54+
Running the Application
55+
=======================
56+
57+
You can run the application by using the following command:
58+
59+
mvn clean jetty:run -P dev
60+
61+
Credits
62+
=========
63+
64+
* Kyösti Herrala. The Gulp build script and its Maven integration are based on Kyösti's ideas.
65+
* [Techniques for authentication in AngularJS applications](https://medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-applications-7bbf0346acec)
66+
67+
Known Issues
68+
============
69+
70+
* If you refresh the login page, you aren't redirected away from it after successful login.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"directory": "bower_components"
3+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"globalstrict": true,
3+
"browser": true,
4+
"devel": true,
5+
"node": true,
6+
"esnext": true,
7+
"bitwise": true,
8+
"camelcase": true,
9+
"curly": true,
10+
"eqeqeq": true,
11+
"immed": true,
12+
"indent": 4,
13+
"latedef": true,
14+
"newcap": true,
15+
"noarg": true,
16+
"regexp": true,
17+
"undef": true,
18+
"unused": false,
19+
"strict": true,
20+
"trailing": true,
21+
"smarttabs": true,
22+
"white": true,
23+
"globals": {
24+
"describe": true,
25+
"it": true,
26+
"beforeEach": true,
27+
"afterEach": true,
28+
"angular": true,
29+
"jQuery": true,
30+
"_": true,
31+
"$": true
32+
}
33+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
'use strict';
2+
3+
var App = angular.module('app', [
4+
'angular-logger',
5+
'http-auth-interceptor',
6+
'ngLocale',
7+
'ngCookies',
8+
'ngResource',
9+
'ngSanitize',
10+
'pascalprecht.translate',
11+
'ui.bootstrap',
12+
'ui.router',
13+
'ui.utils',
14+
'angular-growl',
15+
'angularMoment',
16+
'spring-security-csrf-token-interceptor',
17+
18+
//Partials
19+
'templates',
20+
21+
//Account
22+
'app.account.config', 'app.account.directives', 'app.account.controllers', 'app.account.services',
23+
24+
//Common
25+
'app.common.config', 'app.common.controllers', 'app.common.directives', 'app.common.services',
26+
27+
//Todo
28+
'app.todo.controllers', 'app.todo.directives', 'app.todo.services',
29+
30+
//Search
31+
'app.search.controllers', 'app.search.directives', 'app.search.services'
32+
33+
]);
34+
35+
App.run(['$log', '$rootScope', '$state', 'AUTH_EVENTS', 'AuthenticatedUser', 'authService', 'AuthenticationService', 'COMMON_EVENTS',
36+
function ($log, $rootScope, $state, AUTH_EVENTS, AuthenticatedUser, authService, AuthenticationService, COMMON_EVENTS) {
37+
38+
var logger = $log.getInstance('app');
39+
40+
//This function retries all requests that were failed because of
41+
//the 401 response.
42+
function listenAuthenticationEvents() {
43+
var confirmLogin = function() {
44+
authService.loginConfirmed();
45+
};
46+
47+
$rootScope.$on(AUTH_EVENTS.loginSuccess, confirmLogin);
48+
49+
var viewLogInPage = function() {
50+
logger.info('User is not authenticated. Rendering login view.');
51+
$state.go('todo.login');
52+
};
53+
54+
$rootScope.$on(AUTH_EVENTS.notAuthenticated, viewLogInPage);
55+
56+
var viewTodoListPage = function() {
57+
logger.info("User logged out. REndering todo list view.");
58+
$state.go('todo.list', {}, {reload: true});
59+
};
60+
61+
$rootScope.$on(AUTH_EVENTS.logoutSuccess, viewTodoListPage);
62+
63+
var viewForbiddenPage = function() {
64+
logger.info('Permission was denied for user: %j', AuthenticatedUser);
65+
$state.go('todo.forbidden');
66+
};
67+
68+
$rootScope.$on(AUTH_EVENTS.notAuthorized, viewForbiddenPage);
69+
}
70+
71+
function listenCommonEvents() {
72+
73+
var view404Page = function() {
74+
logger.info('Requested page was not found.');
75+
$state.go('todo.404');
76+
};
77+
78+
$rootScope.$on(COMMON_EVENTS.notFound, view404Page);
79+
}
80+
81+
//This function ensures that anonymous users cannot access states
82+
//that marked as protected (i.e. the value of the authenticated
83+
//property is set to true).
84+
function secureProtectedStates() {
85+
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
86+
logger.trace('Moving to state: %s', toState.name);
87+
AuthenticationService.authorizeStateChange(event, toState, toParams);
88+
});
89+
}
90+
91+
$rootScope.currentUser = AuthenticatedUser;
92+
93+
listenAuthenticationEvents();
94+
listenCommonEvents();
95+
secureProtectedStates();
96+
}]);
97+
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
{
2+
"app.title.label": "Spring Data JPA Tutorial - Query Methods",
3+
"dialogs": {
4+
"delete.dialog": {
5+
"cancel.button.label": "Cancel",
6+
"delete.button.label": "Delete",
7+
"text": "Are you sure that you want to delete the todo entry with title: {{title}}?",
8+
"title": "Delete todo entry?"
9+
}
10+
},
11+
"directives": {
12+
"login.form": {
13+
"login.button": "Login",
14+
"login.failed": "Login failed!"
15+
},
16+
"log.out.link.label": "Log Out",
17+
"todo.form": {
18+
"cancel.button": "Cancel",
19+
"save.button": "Save"
20+
}
21+
},
22+
"footer.message": "Spring Data JPA example application by Petri Kainulainen",
23+
"header.brand.label": "Spring Data JPA Tutorial",
24+
"pages": {
25+
"add.page": {
26+
"title": "Add new todo entry",
27+
"link.label": "Add new todo entry"
28+
},
29+
"delete.link": "Delete",
30+
"edit.page": {
31+
"link.label": "Edit",
32+
"title": "Edit todo entry"
33+
},
34+
"forbidden.page": {
35+
"text": "Permission denied.",
36+
"title": "Forbidden"
37+
},
38+
"not.found.page": {
39+
"text": "The page that you were looking for was not found.",
40+
"title": "Not Found"
41+
},
42+
"list.page": {
43+
"title": "Things to do",
44+
"texts": {
45+
"no.todo.entries.found": "Nothing to do (yet)."
46+
}
47+
},
48+
"login.page": {
49+
"title": "Log In"
50+
},
51+
"search.results.page.title": "Search Results",
52+
"view.page": {
53+
"title": "View Todo Entry"
54+
}
55+
},
56+
"login": {
57+
"help": "Log in by using username: 'user' and password: 'password'",
58+
"username": "Username",
59+
"username.placeholder": "Enter username",
60+
"password": "Password",
61+
"password.placeholder": "Enter password"
62+
},
63+
"search": {
64+
"term.field.placeholder": "Search",
65+
"missing.characters.text": "{{missingCharCount}} characters missing"
66+
},
67+
"todo": {
68+
"created.by.prefix": "by",
69+
"creation.time": "Created at",
70+
"description": "Description",
71+
"description.placeholder": "Enter description",
72+
"messages": {
73+
"description.maxLength": "Description cannot be longer than 500 characters",
74+
"title.maxLength": "Title cannot be longer than 100 characters",
75+
"title.required": "Title is required"
76+
},
77+
"modified.by.prefix": "by",
78+
"modification.time": "Modified at",
79+
"notifications": {
80+
"add": {
81+
"error": "Adding a new todo entry failed.",
82+
"success": "A new todo entry was added."
83+
},
84+
"delete": {
85+
"error": "Deleting the todo entry failed.",
86+
"success": "Deleted the todo entry."
87+
},
88+
"edit": {
89+
"error": "Updating the information of a todo entry failed.",
90+
"success": "Updated the information of the todo entry."
91+
}
92+
},
93+
"title": "Title",
94+
"title.placeholder": "Enter title"
95+
}
96+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<h1 translate="pages.forbidden.page.title"></h1>
2+
3+
<div class="well well-lg">
4+
<p translate="pages.forbidden.page.text"></p>
5+
</div>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<div ng-if="loginFailed" class="alert alert-danger alert-dismissible">
2+
<button type="button"
3+
class="close"
4+
data-dismiss="alert"
5+
aria-label="Close">
6+
<span aria-hidden="true">&times;</span>
7+
</button>
8+
<span translate="directives.login.form.login.failed"></span>
9+
</div>
10+
11+
<form name="loginForm" role="form">
12+
<div class="form-group">
13+
<label for="username" translate="login.username"></label>:
14+
<input id="username"
15+
class="form-control"
16+
name="username"
17+
type="text"
18+
placeholder="{{'login.username.placeholder' | translate}}"
19+
ng-model="login.username"/>
20+
</div>
21+
<div class="form-group">
22+
<label for="password" translate="login.password"></label>:
23+
<input id="password"
24+
class="form-control"
25+
name="password"
26+
type="password"
27+
placeholder="{{'login.password.placeholder' | translate}}"
28+
ng-model="login.password"/>
29+
</div>
30+
<div class="action-buttons form-group">
31+
<button type="button"
32+
class="btn btn-primary"
33+
translate="directives.login.form.login.button"
34+
ng-click="submitLoginForm()"></button>
35+
</div>
36+
</form>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<h1 translate="pages.login.page.title"></h1>
2+
3+
<div class="well well-lg">
4+
<div login-form></div>
5+
<p translate="login.help"></p>
6+
</div>

0 commit comments

Comments
 (0)