├── .editorconfig ├── .gitignore ├── .travis.yml ├── README.md ├── app ├── index.js └── templates │ └── base-project │ ├── _.gitignore │ ├── _.travis.yml │ ├── _Gruntfile.js │ ├── _README.md │ ├── _bower.json │ ├── _package.json │ ├── _pom.xml │ ├── _web.xml │ └── src │ ├── main │ ├── java │ │ └── package │ │ │ ├── controller │ │ │ └── ApplicationController.java │ │ │ └── service │ │ │ └── ApplicationService.java │ ├── resources │ │ ├── log4j2.xml │ │ └── spring │ │ │ ├── application-config.xml │ │ │ └── mvc-config.xml │ └── webapp │ │ ├── app │ │ ├── app.js │ │ ├── components │ │ │ ├── core │ │ │ │ └── directives │ │ │ │ │ └── directives.js │ │ │ └── main │ │ │ │ ├── controllers │ │ │ │ └── main.js │ │ │ │ └── services │ │ │ │ └── main.js │ │ ├── config.js │ │ └── routes.js │ │ ├── config │ │ └── config.properties │ │ ├── index.html │ │ ├── style │ │ └── style.css │ │ └── templates │ │ ├── header.html │ │ └── main │ │ └── main.html │ └── test │ ├── java │ └── package │ │ ├── controller │ │ └── ApplicationControllerTest.java │ │ └── service │ │ └── ApplicationServiceTest.java │ └── resources │ ├── config │ └── config.test.properties │ └── spring │ └── mvc-config.test.xml ├── package.json └── test └── test-app.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | bower_components/ 4 | test/temp/ 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' 4 | before_script: 5 | - shopt -s dotglob 6 | - git config --global user.email "travis@dardenne.fr" 7 | - git config --global user.name "Travis CI bot - (Mathieu Dardenne)" 8 | after_success: 9 | - cd test 10 | - git clone https://${GH_REF} 11 | - cd sample-angular-spring 12 | - cp -R .git ../ 13 | - git rm -r * --ignore-unmatch 14 | - rm -rf * 15 | - mv ../.git/ . 16 | - cp -R ../temp/* . 17 | - git add --all . && git status && git commit -a -m 'Lastest test built' 18 | - git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master > /dev/null 2>&1 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # angular-spring generator 2 | [![Build Status](https://secure.travis-ci.org/madtrax/generator-angular-spring.png?branch=master)](https://travis-ci.org/madtrax/generator-angular-spring) [![Dependency Status](https://david-dm.org/madtrax/generator-angular-spring.svg)](https://david-dm.org/madtrax/generator-angular-spring.svg) 3 | ## Getting Started 4 | 5 | ### What is angular-spring generator? 6 | 7 | I realized I usually spend more time removing all the unecessary libraries and extra stuff when I use existing generators, so here is a lightweight and clean generator to bootstrap a project which doesn't require lunar load balancing, 64 clustered oracle instances and 782 hadoop nodes (you can add that yourself afterwards!). 8 | 9 | angular-spring generator is a [Yeoman](http://yeoman.io) generator which create a solid base project using Java Spring MVC & AngularJS and can be quickly deployed on Tomcat. The following tools will be included [Maven](http://maven.apache.org), [Grunt](http://gruntjs.com) & [Bower](http://bower.io). 10 | 11 | IF YOU WISH, the generator can add extra stuff like: [FontAwesome](http://fortawesome.github.io/Font-Awesome/) and [AngularStrap](http://mgcrea.github.io/angular-strap/). 12 | (@TODO: [Compass](http://compass-style.org/), WebSocket) 13 | 14 | The AngularJS style is based on [@john_papa style guide](https://github.com/johnpapa/angularjs-styleguide) 15 | 16 | If you do not have Yeoman on your computer, please install it first using the command below: 17 | 18 | ```bash 19 | npm install -g yo 20 | ``` 21 | 22 | ## Use angular-spring generator 23 | ### Install 24 | To install the generator you can use npm 25 | 26 | ```bash 27 | npm install -g generator-angular-spring 28 | ``` 29 | 30 | You can also clone the project and link it to your local npm 31 | 32 | ```bash 33 | git clone https://github.com/madtrax/generator-angular-spring.git && cd ./generator-angular-spring && sudo npm link 34 | ``` 35 | 36 | ### Launch 37 | Finally, launch the generator: 38 | 39 | ```bash 40 | yo angular-spring 41 | ``` 42 | 43 | ## Generated application [![Build Status](https://travis-ci.org/madtrax/sample-angular-spring.svg?branch=master)](https://travis-ci.org/madtrax/sample-angular-spring) 44 | ### Start application 45 | Once you ran the generator, execute the following commands to compile and run the web application. 46 | 47 | Install dependencies: 48 | ```bash 49 | npm install && bower install 50 | ``` 51 | Start: 52 | ```bash 53 | grunt && mvn tomcat7:run 54 | ``` 55 | 56 | Once everything is done you can open you web browser: http://localhost:8080/your-project-name/ 57 | 58 | ![Image](http://imagizer.imageshack.us/a/img537/8286/EBBZOM.png) 59 | 60 | You can find a sample of generated application [here](https://github.com/madtrax/sample-angular-spring). 61 | 62 | ### Folder structure 63 | 64 | The application folder structure before running grunt and bower should be: 65 | 66 | ```bash 67 | ├── Gruntfile.js 68 | ├── README.md 69 | ├── bower.json 70 | ├── package.json 71 | ├── pom.xml 72 | └── src 73 | └── main 74 | ├── java 75 | │   └── com 76 | │   └── mycompany 77 | │   └── myapp 78 | │   ├── controller 79 | │   │   └── ApplicationController.java 80 | │   └── service 81 | │   └── ApplicationService.java 82 | ├── resources 83 | │   ├── log4j2.xml 84 | │   └── spring 85 | │   ├── application-config.xml 86 | │   └── mvc-config.xml 87 | └── webapp 88 | ├── app 89 | │   ├── app.js 90 | │   ├── components 91 | │   │   ├── core 92 | │   │   │   └── directives 93 | │   │   │   └── directives.js 94 | │   │   └── main 95 | │   │   ├── controllers 96 | │   │   │   └── main.js 97 | │   │   └── services 98 | │   │   └── main.js 99 | │   ├── config.js 100 | │   └── routes.js 101 | ├── config 102 | │   └── config.properties 103 | ├── index.html 104 | ├── style 105 | │   └── style.css 106 | ├── templates 107 | │   ├── header.html 108 | │   └── main 109 | │   └── main.html 110 | └── web.xml 111 | 112 | 22 directories, 22 files 113 | ``` 114 | 115 | ## Contributions are welcome 116 | 117 | There is many improvements that can be done for this project, feel free to contribute. 118 | 119 | ## License 120 | 121 | Apache 2.0 122 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var yeoman = require('yeoman-generator'); 3 | 4 | module.exports = yeoman.generators.Base.extend({ 5 | 6 | initializing: function () { 7 | this.pkg = require('../package.json'); 8 | }, 9 | 10 | prompting: function () { 11 | var done = this.async(); 12 | 13 | this.log('Thank you for using angular-spring generator!'); 14 | 15 | var prompts = [ 16 | { type: 'input', name: 'projectName', message: 'What\'s the name of the project?', default: 'MyProject' }, 17 | { type: 'input', name: 'projectAuthor', message: 'Project author?', default: 'John Doe' }, 18 | { type: 'input', name: 'projectWebsite', message: 'Project website?', default: 'localhost' }, 19 | { type: 'input', name: 'projectEmail', message: 'Author\'s email?', default: 'john.doe@localhost' }, 20 | { type: 'input', name: 'packageName', message: 'What is your default Java package name?', 21 | validate: function (input) { 22 | if (/^([a-z_]{1}[a-z0-9_]*(\.[a-z_]{1}[a-z0-9_]*)*)$/.test(input)) return true; 23 | return 'The package name you have provided is not a valid Java package name.'; 24 | }, 25 | default: 'com.mycompany.myapp' 26 | }, 27 | { type: 'confirm', name: 'useAngularStrap', message: 'Would you like to use AngularStrap (Bootsrap for AngularJS)?', default: false}, 28 | { type: 'confirm', name: 'useFontAwesome', message: 'Would you like to use FontAwesome (Icons font)?', default: false} 29 | ]; 30 | 31 | this.prompt(prompts, function (props) { 32 | this.properties = props; 33 | this.properties.generatorName = this.pkg.name; 34 | 35 | done(); 36 | }.bind(this)); 37 | }, 38 | 39 | writing: { 40 | 41 | app: function () { 42 | 43 | var underscoreParams = { evaluate: /\<\%([\s\S]+?)\%\>/g, interpolate: /\<\%\=([\s\S]+?)\%\>/g, escape: /\<-([\s\S]+?)\>/g }; 44 | var baseProjectPath = 'base-project/'; 45 | 46 | var genericTemplateFiles = ['_package.json', '_bower.json', '_pom.xml', '_README.md', '_.gitignore', '_.travis.yml'] 47 | var genericCopyFiles = ['_Gruntfile.js']; 48 | var packagePath = this.properties.packageName.replace(/\./g, '/'); 49 | var javaSrcPath = baseProjectPath + 'src/main/java/' 50 | var javaSrcTestPath = baseProjectPath + 'src/test/java/' 51 | var javaPath = 'src/main/java/' + packagePath + '/'; 52 | var javaTestPath = 'src/test/java/' + packagePath + '/'; 53 | 54 | for (var f in genericTemplateFiles) 55 | this.template(baseProjectPath + genericTemplateFiles[f], genericTemplateFiles[f].substr(1,500), this, underscoreParams); 56 | 57 | for (var t in genericCopyFiles) 58 | this.copy(baseProjectPath + genericCopyFiles[t], genericCopyFiles[t].substr(1,500), this, underscoreParams); 59 | 60 | this.directory(baseProjectPath + 'src/main/webapp/', 'src/main/webapp/'); 61 | this.directory(baseProjectPath + 'src/main/resources/', 'src/main/resources/'); 62 | this.directory(baseProjectPath + 'src/test/resources/', 'src/test/resources/'); 63 | 64 | this.directory(baseProjectPath + 'src/main/java/package/', 'src/main/java/' + packagePath + '/'); 65 | this.directory(baseProjectPath + 'src/test/java/package/', 'src/test/java/' + packagePath + '/'); 66 | 67 | this.template(baseProjectPath + 'src/main/webapp/app/app.js', 'src/main/webapp/app/app.js', this, underscoreParams); 68 | this.template(baseProjectPath + '_web.xml', 'src/main/webapp/web.xml', this, underscoreParams); 69 | 70 | this.template(baseProjectPath + 'src/main/webapp/config/config.properties', 'src/main/webapp/config/config.properties', this, underscoreParams); 71 | this.template(baseProjectPath + 'src/main/resources/spring/application-config.xml', 'src/main/resources/spring/application-config.xml', this, underscoreParams); 72 | this.template(baseProjectPath + 'src/main/resources/spring/mvc-config.xml', 'src/main/resources/spring/mvc-config.xml', this, underscoreParams); 73 | this.template(baseProjectPath + 'src/main/resources/log4j2.xml', 'src/main/resources/log4j2.xml', this, underscoreParams); 74 | 75 | this.template(javaSrcPath + 'package/controller/ApplicationController.java', javaPath + 'controller/ApplicationController.java', this, underscoreParams); 76 | this.template(javaSrcPath + 'package/service/ApplicationService.java', javaPath + 'service/ApplicationService.java', this, underscoreParams); 77 | 78 | this.template(javaSrcTestPath + 'package/controller/ApplicationControllerTest.java', javaTestPath + 'controller/ApplicationControllerTest.java', this, underscoreParams); 79 | this.template(javaSrcTestPath + 'package/service/ApplicationServiceTest.java', javaTestPath + 'service/ApplicationServiceTest.java', this, underscoreParams); 80 | 81 | this.template(baseProjectPath + 'src/test/resources/config/config.test.properties', 'src/test/resources/config/config.test.properties', this, underscoreParams); 82 | 83 | }, 84 | 85 | projectfiles: function () { } 86 | }, 87 | 88 | install: function () { 89 | this.installDependencies({ 90 | skipInstall: this.options['skip-install'] 91 | }); 92 | } 93 | }); 94 | -------------------------------------------------------------------------------- /app/templates/base-project/_.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | bower_components/ 4 | -------------------------------------------------------------------------------- /app/templates/base-project/_.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - openjdk7 4 | - oraclejdk7 5 | before_install: 6 | - currentfolder=${PWD##*/} 7 | - if [ "$currentfolder" != '<%= properties.projectName %>' ]; then cd .. && eval "mv $currentfolder <%= properties.projectName %>" && cd <%= properties.projectName %>; fi 8 | - npm install -g bower grunt-cli grunt 9 | - bower install && npm install && grunt 10 | -------------------------------------------------------------------------------- /app/templates/base-project/_Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | grunt.initConfig({ 4 | 5 | pkg: grunt.file.readJSON('package.json'), 6 | 7 | folders: { 8 | webapp: { 9 | root: 'src/main/webapp/', 10 | build: 'src/main/webapp/WEB-INF/' 11 | } 12 | }, 13 | 14 | banner: '/*!\n * <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + 15 | '<%= grunt.template.today("yyyy-mm-dd") %>\n' + 16 | '<%= pkg.homepage ? " * " + pkg.homepage + "\\n" : "" %>' + 17 | ' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + 18 | ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %>\n*/\n', 19 | 20 | bower_concat: { 21 | all: { 22 | dest: '<%= folders.webapp.build %>js/lib.js', 23 | cssDest: '<%= folders.webapp.build %>style/lib.css', 24 | bowerOptions: { 25 | relative: false 26 | } 27 | } 28 | }, 29 | 30 | concat: { 31 | js: { 32 | src: [ '<%= folders.webapp.root %>/app/app.js', '<%= folders.webapp.root %>/app/**/*.js' ], 33 | dest: '<%= folders.webapp.build %>js/app.js' 34 | }, 35 | css:{ 36 | src: [ '<%= folders.webapp.root %>/style/**/*.css' ], 37 | dest: '<%= folders.webapp.build %>style/app.css' 38 | } 39 | }, 40 | 41 | copy: { 42 | tomcat: { 43 | src: ['<%= folders.webapp.root %>/web.xml'], 44 | dest: '<%= folders.webapp.build %>/web.xml' 45 | }, 46 | resources: { 47 | expand: true, 48 | cwd: '<%= folders.webapp.root %>/../resources/', 49 | src: ['**/**/*'], 50 | dest: '<%= folders.webapp.build %>/resources/' 51 | }, 52 | config: { 53 | expand: true, 54 | cwd: '<%= folders.webapp.root %>/config/', 55 | src: ['**/**/*'], 56 | dest: '<%= folders.webapp.build %>config/' 57 | }, 58 | img: { 59 | expand: true, 60 | cwd: '<%= folders.webapp.root %>/img/', 61 | src: ['**/**/*'], 62 | dest: '<%= folders.webapp.build %>img/' 63 | }, 64 | templates: { 65 | expand: true, 66 | cwd: '<%= folders.webapp.root %>', 67 | src: ['index.html', 'templates/**/*.html'], 68 | dest: '<%= folders.webapp.build %>' 69 | }, 70 | fonts: { 71 | expand: true, 72 | flatten: true, 73 | src: [ 'bower_components/components-font-awesome/fonts/**/*'], 74 | dest: '<%= folders.webapp.build %>/fonts/' 75 | } 76 | }, 77 | 78 | uglify: { 79 | options: { 80 | banner: '<%= banner %>' 81 | }, 82 | js: { 83 | src: '<%= concat.js.dest %>', 84 | dest: '<%= folders.webapp.build %>js/app.min.js' 85 | } 86 | }, 87 | 88 | jshint: { 89 | options: { 90 | curly: false, 91 | eqeqeq: true, 92 | immed: true, 93 | latedef: false, 94 | newcap: true, 95 | noarg: true, 96 | sub: true, 97 | undef: false, 98 | unused: true, 99 | boss: true, 100 | eqnull: true, 101 | browser: true, 102 | globals: { 103 | jQuery: true 104 | } 105 | }, 106 | all: ['Gruntfile.js', '<%= folders.webapp.root %>/app/**/*.js'] 107 | }, 108 | 109 | qunit: { 110 | files: ['test/**/*.html'] 111 | }, 112 | 113 | watch: { 114 | js: { 115 | files: '<%= jshint.all %>', 116 | tasks: ['concat:js'] 117 | }, 118 | templates: { 119 | files: ['<%= folders.webapp.root %>/index.html', '<%= folders.webapp.root %>templates/**/*.html'], 120 | tasks: [ 'copy:templates' ] 121 | }, 122 | css: { 123 | files: '<%= folders.webapp.root %>/style/*.css', 124 | tasks: [ 'concat:css' ] 125 | } 126 | 127 | } 128 | }); 129 | 130 | grunt.loadNpmTasks('grunt-contrib-concat'); 131 | grunt.loadNpmTasks('grunt-contrib-uglify'); 132 | grunt.loadNpmTasks('grunt-contrib-qunit'); 133 | grunt.loadNpmTasks('grunt-contrib-jshint'); 134 | grunt.loadNpmTasks('grunt-contrib-copy'); 135 | grunt.loadNpmTasks('grunt-contrib-watch'); 136 | 137 | grunt.loadNpmTasks('grunt-bower-concat'); 138 | 139 | grunt.registerTask('default', ['bower_concat', 'copy', 'concat', 'uglify']); 140 | grunt.registerTask('dev', ['jshint', 'concat']); 141 | 142 | }; 143 | -------------------------------------------------------------------------------- /app/templates/base-project/_README.md: -------------------------------------------------------------------------------- 1 | Project generated by angular-spring generator [![Build Status](https://travis-ci.org/madtrax/sample-angular-spring.svg?branch=master)](https://travis-ci.org/madtrax/sample-angular-spring) 2 | =================== 3 | 4 | This project has been generated by [angular-spring generator](https://github.com/madtrax/generator-angular-spring). 5 | You can compile and run the app using the commands below (You will need npm, maven and grunt installed): 6 | 7 | ```bash 8 | npm install && bower install 9 | grunt 10 | mvn tomcat7:run 11 | ``` 12 | 13 | And open [http://localhost:8080/angular-spring/](http://localhost:8080/angular-spring/) 14 | 15 | ![Image](http://imagizer.imageshack.us/a/img537/8286/EBBZOM.png) 16 | 17 | You can also simply generate a war file to deploy on your own tomcat instance 18 | 19 | ```bash 20 | npm install && bower install 21 | grunt && mvn package 22 | ``` 23 | -------------------------------------------------------------------------------- /app/templates/base-project/_bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= properties.projectName %>", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "angular": "^1.3.0", 6 | "json3": "^3.3.0", 7 | "es5-shim": "^4.0.0", 8 | "angular-animate": "^1.3.0", 9 | "angular-cookies": "^1.3.0", 10 | "angular-resource": "^1.3.0", 11 | "angular-route": "^1.3.0", 12 | "angular-sanitize": "^1.3.0" 13 | <% if (properties.useAngularStrap) { %>, "angular-strap": "~2.1.5"<% } %> 14 | <% if (properties.useFontAwesome) { %>, "components-font-awesome": "~4.2.0"<% } %> 15 | }, 16 | "devDependencies": { 17 | "angular-mocks": "~1.3.0", 18 | "angular-scenario": "~1.3.0" 19 | }, 20 | "appPath": "app" 21 | } 22 | -------------------------------------------------------------------------------- /app/templates/base-project/_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= properties.projectName %>", 3 | "homepage": "<%= properties.projectWebsite %>", 4 | "author": { 5 | "name": "<%= properties.projectAuthor %>", 6 | "email": "<%= properties.projectEmail %>" 7 | }, 8 | "version": "0.0.0", 9 | "engines": { 10 | "node": ">= 0.10.0" 11 | }, 12 | "devDependencies": { 13 | "grunt": "~0.4.5", 14 | "grunt-contrib-jshint": "~0.10.0", 15 | "grunt-contrib-watch": "~0.6.1", 16 | "grunt-contrib-qunit": "~0.5.2", 17 | "grunt-contrib-concat": "~0.4.0", 18 | "grunt-contrib-uglify": "~0.5.0", 19 | "grunt-contrib-copy": "~0.7.0", 20 | "grunt-bower-concat": "~0.4.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/templates/base-project/_pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 4.0.0 5 | <%= properties.packageName %> 6 | <%= properties.projectName %> 7 | A1 8 | war 9 | 10 | 11 | <%= properties.projectName %> 12 | 13 | 14 | org.apache.tomcat.maven 15 | tomcat7-maven-plugin 16 | 2.2 17 | 18 | /<%= properties.projectName %> 19 | 20 | 21 | 22 | org.apache.maven.plugins 23 | maven-compiler-plugin 24 | 3.1 25 | 26 | 1.7 27 | 1.7 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 1.7 37 | UTF-8 38 | UTF-8 39 | 40 | 41 | 2.2 42 | 1.2 43 | 2.5 44 | 7.0.57 45 | 46 | 47 | 4.1.4.RELEASE 48 | 49 | 50 | 4.2.1.Final 51 | 52 | 53 | 1.7.5 54 | 55 | 56 | 4.11 57 | 58 | 59 | 60 | 61 | 62 | org.springframework 63 | spring-core 64 | ${org.springframework.version} 65 | 66 | 67 | 68 | org.springframework 69 | spring-webmvc 70 | ${org.springframework.version} 71 | 72 | 73 | org.springframework 74 | spring-orm 75 | ${org.springframework.version} 76 | 77 | 78 | org.springframework 79 | spring-websocket 80 | ${org.springframework.version} 81 | 82 | 83 | org.springframework 84 | spring-messaging 85 | ${org.springframework.version} 86 | 87 | 88 | 89 | 90 | javax.servlet 91 | jstl 92 | ${jstl.version} 93 | provided 94 | 95 | 96 | javax.servlet 97 | servlet-api 98 | ${servlet.version} 99 | provided 100 | 101 | 102 | javax.servlet.jsp 103 | jsp-api 104 | ${jsp.version} 105 | provided 106 | 107 | 108 | 109 | 110 | org.apache.tomcat 111 | tomcat-catalina 112 | ${tomcat.version} 113 | provided 114 | 115 | 116 | 117 | org.apache.tomcat.embed 118 | tomcat-embed-websocket 119 | ${tomcat.version} 120 | provided 121 | 122 | 123 | 124 | 125 | org.springframework 126 | spring-tx 127 | ${org.springframework.version} 128 | 129 | 130 | 131 | 132 | org.slf4j 133 | slf4j-api 134 | 1.7.7 135 | compile 136 | 137 | 138 | 139 | 149 | 150 | 151 | 152 | org.springframework 153 | spring-test 154 | ${org.springframework.version} 155 | test 156 | 157 | 158 | junit 159 | junit 160 | 4.11 161 | test 162 | 163 | 164 | 165 | 170 | 171 | 172 | 173 | com.google.code.gson 174 | gson 175 | 2.2.4 176 | 177 | 178 | 179 | 190 | 191 | 192 | javax.mail 193 | mail 194 | 1.4 195 | 196 | 197 | 198 | 203 | 204 | 205 | org.springframework.boot 206 | spring-boot-starter-remote-shell 207 | 1.0.0.BUILD-SNAPSHOT 208 | 209 | 210 | 211 | 212 | org.apache.logging.log4j 213 | log4j-api 214 | 2.1 215 | 216 | 217 | org.apache.logging.log4j 218 | log4j-core 219 | 2.1 220 | 221 | 222 | org.apache.logging.log4j 223 | log4j-slf4j-impl 224 | 2.1 225 | 226 | 227 | org.slf4j 228 | jcl-over-slf4j 229 | 1.7.7 230 | 231 | 232 | org.slf4j 233 | jul-to-slf4j 234 | 1.7.7 235 | 236 | 237 | org.slf4j 238 | log4j-over-slf4j 239 | 1.7.7 240 | 241 | 242 | org.fusesource.mqtt-client 243 | mqtt-client 244 | 1.3 245 | 246 | 247 | org.springframework.boot 248 | spring-boot-starter-batch 249 | 1.0.0.BUILD-SNAPSHOT 250 | 251 | 252 | 253 | 254 | commons-fileupload 255 | commons-fileupload 256 | 1.3.1 257 | 258 | 259 | 260 | 265 | 266 | 267 | 268 | 269 | 270 | spring-snapshots 271 | Spring Snapshots 272 | http://repo.spring.io/snapshot 273 | 274 | true 275 | 276 | 277 | 278 | 279 | -------------------------------------------------------------------------------- /app/templates/base-project/_web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | <%= properties.projectName %> 9 | 10 | 14 | 15 | contextConfigLocation 16 | classpath:spring/application-config.xml 17 | 18 | 19 | 20 | org.springframework.web.context.ContextLoaderListener 21 | 22 | 23 | 26 | 27 | dispatcherServlet 28 | org.springframework.web.servlet.DispatcherServlet 29 | 30 | contextConfigLocation 31 | classpath:spring/mvc-config.xml 32 | 33 | 1 34 | 35 | 36 | 37 | dispatcherServlet 38 | / 39 | 40 | 41 | 42 | /index.html 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/templates/base-project/src/main/java/package/controller/ApplicationController.java: -------------------------------------------------------------------------------- 1 | package <%= properties.packageName %>.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.ResponseBody; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | 8 | import java.util.Map; 9 | import java.util.HashMap; 10 | import java.util.logging.Logger; 11 | 12 | import <%= properties.packageName %>.service.ApplicationService; 13 | 14 | @Controller 15 | public class ApplicationController { 16 | 17 | @Autowired 18 | private ApplicationService applicationService; 19 | 20 | private Logger logger = Logger.getLogger(getClass().getName()); 21 | 22 | public ApplicationController() { } 23 | 24 | @RequestMapping("/config") 25 | public @ResponseBody Map config() { 26 | Map params = new HashMap(); 27 | 28 | params.put("projectName", applicationService.getProjectName()); 29 | params.put("projectAuthor", applicationService.getProjectAuthor()); 30 | params.put("projectWebsite", applicationService.getProjectWebsite()); 31 | 32 | logger.info("Querying /config"); 33 | 34 | return params; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /app/templates/base-project/src/main/java/package/service/ApplicationService.java: -------------------------------------------------------------------------------- 1 | package <%= properties.packageName %>.service; 2 | 3 | import org.springframework.stereotype.Service; 4 | import org.springframework.beans.factory.annotation.Value; 5 | 6 | @Service 7 | public class ApplicationService { 8 | 9 | @Value("${project.name}") 10 | private String projectName; 11 | 12 | @Value("${project.author}") 13 | private String projectAuthor; 14 | 15 | @Value("${project.website}") 16 | private String projectWebsite; 17 | 18 | public ApplicationService() { } 19 | 20 | public String getProjectName() { 21 | return projectName; 22 | } 23 | 24 | public String getProjectAuthor() { 25 | return projectAuthor; 26 | } 27 | 28 | public String getProjectWebsite() { 29 | return projectWebsite; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /app/templates/base-project/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/templates/base-project/src/main/resources/spring/application-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/templates/base-project/src/main/resources/spring/mvc-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/templates/base-project/src/main/webapp/app/app.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | /* Init application */ 5 | angular 6 | .module('app', ['ngAnimate', 'ngRoute', 'ngSanitize'<% if (properties.useAngularStrap) { %>, 'mgcrea.ngStrap'<% } %>]); 7 | 8 | 9 | 10 | /* Common application conroller */ 11 | angular 12 | .module('app') 13 | .controller('ApplicationCtrl', ApplicationCtrl); 14 | 15 | ApplicationCtrl.$inject = ['$window', 'ConfService']; 16 | function ApplicationCtrl($window, ConfService) { 17 | 18 | var vm = this; 19 | 20 | vm.projectAuthor = null; 21 | vm.projectName = null; 22 | 23 | vm.loadConfig = function() { 24 | ConfService 25 | .initConfig() 26 | .error(function() { 27 | vm.projectAuthor = vm.projectName = 'Error!'; 28 | }) 29 | .then(function(res) { 30 | vm.projectAuthor = res.data.projectAuthor || 'Unknown'; 31 | vm.projectName = res.data.projectName || 'Unknown'; 32 | vm.projectWebsite = res.data.projectWebsite || 'Unknown'; 33 | }); 34 | }; 35 | 36 | vm.loadConfig(); 37 | 38 | return vm; 39 | } 40 | })(); 41 | 42 | -------------------------------------------------------------------------------- /app/templates/base-project/src/main/webapp/app/components/core/directives/directives.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | angular 5 | .module('app') 6 | .directive('sampleDirective', sampleDirective); 7 | 8 | function sampleDirective() { 9 | return function(scope, element, attrs) { 10 | scope.$watch(attrs.inputDisabled, function(val) { 11 | if (val === undefined) 12 | element.prop('disabled', false); 13 | else 14 | element.prop('disabled', true); 15 | }); 16 | }; 17 | } 18 | 19 | })(); -------------------------------------------------------------------------------- /app/templates/base-project/src/main/webapp/app/components/main/controllers/main.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | angular 5 | .module('app') 6 | .controller('MainCtrl', MainCtrl); 7 | 8 | MainCtrl.$inject = ['$window', 'MainService']; 9 | function MainCtrl($window, MainService) { 10 | 11 | var vm = this; 12 | 13 | vm.viewLocation = 'webapp/templates/main/main.html'; 14 | 15 | return vm; 16 | } 17 | 18 | })(); -------------------------------------------------------------------------------- /app/templates/base-project/src/main/webapp/app/components/main/services/main.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | angular 5 | .module('app') 6 | .service('MainService', MainService); 7 | 8 | MainService.$inject = ['$http']; 9 | function MainService($http) { 10 | 11 | var service = {}; 12 | 13 | return service; 14 | } 15 | 16 | })(); -------------------------------------------------------------------------------- /app/templates/base-project/src/main/webapp/app/config.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | angular 5 | .module('app') 6 | .service('ConfService', ConfService); 7 | 8 | ConfService.$inject = ['$http']; 9 | function ConfService($http) { 10 | 11 | var service = {}; 12 | 13 | service.initConfig = function() { 14 | return $http.get('config'); 15 | }; 16 | 17 | return service; 18 | } 19 | 20 | })(); -------------------------------------------------------------------------------- /app/templates/base-project/src/main/webapp/app/routes.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | angular 5 | .module('app') 6 | .config(Routes); 7 | 8 | Routes.$inject = ['$routeProvider']; 9 | function Routes($routeProvider) { 10 | 11 | $routeProvider. 12 | when('/', { 13 | templateUrl: 'templates/main/main.html', 14 | controller: 'MainCtrl', 15 | controllerAs: 'main' 16 | }). 17 | otherwise({ 18 | redirectTo: '/' 19 | }); 20 | } 21 | 22 | })(); -------------------------------------------------------------------------------- /app/templates/base-project/src/main/webapp/config/config.properties: -------------------------------------------------------------------------------- 1 | project.name = <%= properties.projectName %> 2 | project.author = <%= properties.projectAuthor %> 3 | project.website = <%= properties.projectWebsite %> 4 | project.generator = <%= properties.generatorName %> -------------------------------------------------------------------------------- /app/templates/base-project/src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | <%= properties.projectName %> 20 | 21 | 22 | 23 |
24 |
25 | 26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /app/templates/base-project/src/main/webapp/style/style.css: -------------------------------------------------------------------------------- 1 | body { margin:0;padding:0; } 2 | 3 | .callout { background-color: #F4F8FA; margin: 20px 0; padding: 20px; border-left: 3px solid #BCE8F1; } 4 | .callout h4 { color: #34789A;margin-top: 0;margin-bottom: 5px; } 5 | 6 | nav { height: 38px; color: #FFF; font-size: 14px; font-weight: 600; line-height: 39px; text-align: right; border-bottom: 1px solid #235D76; background: #287393;overflow: hidden; } 7 | nav a { display: inline-block; line-height: 36px; padding: 0 10px; margin: 0; color: rgba(255, 255, 255, 0.8); text-decoration: none; background: #287393; transition: all 0.1s; font-weight: 300; } 8 | nav a:hover, nav a:focus { color: #FFF; text-decoration: none; background: #256A88; } 9 | -------------------------------------------------------------------------------- /app/templates/base-project/src/main/webapp/templates/header.html: -------------------------------------------------------------------------------- 1 | 9 |
10 |
11 |
12 | -------------------------------------------------------------------------------- /app/templates/base-project/src/main/webapp/templates/main/main.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 9 | 10 |
11 |

Congratulations {{app.projectAuthor}} !

12 |

{{app.projectName}} has been generated just for you. Time to get coding!

13 |

This view is located under {{main.viewLocation}}

14 |
15 | 16 |

Optional stuff you have selected

17 |
    18 | <% if (properties.useAngularStrap) { %> 19 |
  • 20 |

    21 | AngularStrap, you can have a look at the documentation here.
    22 | You can do stuff like tooltip (rollover me) 23 | or alert message (click on me) 24 |

    25 |
  • 26 | <% } %> 27 | <% if (properties.useFontAwesome) { %> 28 |
  • 29 |

    30 | FontAwesome, check the doc here here. Now you got some fancy icons:
    31 | 32 | ... 33 |

    34 |
  • 35 | <% } %> 36 | 37 |
38 | 39 |
40 | 41 |
42 | -------------------------------------------------------------------------------- /app/templates/base-project/src/test/java/package/controller/ApplicationControllerTest.java: -------------------------------------------------------------------------------- 1 | package <%= properties.packageName %>.controller; 2 | 3 | import java.util.Map; 4 | 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.test.context.ContextConfiguration; 9 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 10 | import org.springframework.util.Assert; 11 | 12 | @RunWith(SpringJUnit4ClassRunner.class) 13 | @ContextConfiguration(locations = { "classpath:spring/application-config.xml", "classpath:spring/mvc-config.test.xml" }) 14 | public class ApplicationControllerTest { 15 | 16 | @Autowired 17 | private ApplicationController applicationController; 18 | 19 | @Test 20 | public void testConfigEndpoint() { 21 | Map res = applicationController.config(); 22 | 23 | Assert.notNull(res); 24 | Assert.notEmpty(res); 25 | Assert.isTrue(res.size() == 3); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /app/templates/base-project/src/test/java/package/service/ApplicationServiceTest.java: -------------------------------------------------------------------------------- 1 | package <%= properties.packageName %>.service; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.test.context.ContextConfiguration; 7 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 8 | import org.springframework.util.Assert; 9 | 10 | @RunWith(SpringJUnit4ClassRunner.class) 11 | @ContextConfiguration(locations = { "classpath:spring/application-config.xml", "classpath:spring/mvc-config.test.xml" }) 12 | public class ApplicationServiceTest { 13 | 14 | @Autowired 15 | private ApplicationService applicationService; 16 | 17 | @Test 18 | public void testConfigParams() { 19 | Assert.notNull(applicationService.getProjectName()); 20 | Assert.notNull(applicationService.getProjectAuthor()); 21 | Assert.notNull(applicationService.getProjectWebsite()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /app/templates/base-project/src/test/resources/config/config.test.properties: -------------------------------------------------------------------------------- 1 | project.name = <%= properties.projectName %> 2 | project.author = <%= properties.projectAuthor %> 3 | project.website = <%= properties.projectWebsite %> 4 | project.generator = <%= properties.generatorName %> 5 | -------------------------------------------------------------------------------- /app/templates/base-project/src/test/resources/spring/mvc-config.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator-angular-spring", 3 | "version": "0.0.2", 4 | "description": "(Java Spring MVC + AngularJS)/Tomcat Yeoman generator", 5 | "license": "Apache 2.0", 6 | "main": "app/index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/madtrax/generator-angular-spring" 10 | }, 11 | "author": "Mathieu DARDENNE (https://github.com/madtrax/generator-angular-spring)", 12 | "engines": { 13 | "node": ">=0.10.0" 14 | }, 15 | "scripts": { 16 | "test": "mocha" 17 | }, 18 | "files": [ 19 | "app" 20 | ], 21 | "keywords": [ 22 | "java", 23 | "spring", 24 | "mvc", 25 | "web", 26 | "javascript", 27 | "angular", 28 | "angularjs", 29 | "yeoman-generator" 30 | ], 31 | "dependencies": { 32 | "yeoman-generator": "^0.18.0" 33 | }, 34 | "devDependencies": { 35 | "mocha": "*" 36 | }, 37 | "peerDependencies": { 38 | "yo": ">=1.0.0" 39 | }, 40 | "bugs": { 41 | "url": "https://github.com/madtrax/generator-angular-spring/issues" 42 | }, 43 | "homepage": "https://github.com/madtrax/generator-angular-spring", 44 | "directories": { 45 | "test": "test" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /test/test-app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var assert = require('yeoman-generator').assert; 5 | var helpers = require('yeoman-generator').test; 6 | var os = require('os'); 7 | 8 | describe('angular-spring generator', function () { 9 | 10 | var resourceDir = 'src/main/resources/'; 11 | var testResourceDir = 'src/test/resources/'; 12 | var webappDir = 'src/main/webapp/'; 13 | var javaSrcDir = 'src/main/java/'; 14 | var javaPackageDir = javaSrcDir + 'com/mycompany/myapp/'; 15 | 16 | var defaultFiles = [ 17 | '.gitignore', 18 | '.travis.yml', 19 | 'bower.json', 20 | 'package.json', 21 | 'pom.xml', 22 | 'Gruntfile.js', 23 | 'README.md' 24 | ]; 25 | 26 | var expectedAdditionalFiles = [ 27 | resourceDir + 'spring/application-config.xml', 28 | resourceDir + 'spring/mvc-config.xml', 29 | 30 | webappDir + 'index.html', 31 | webappDir + 'web.xml', 32 | webappDir + 'config/config.properties', 33 | 34 | webappDir + 'templates/header.html', 35 | webappDir + 'templates/main/main.html', 36 | 37 | webappDir + 'app/app.js', 38 | webappDir + 'app/config.js', 39 | webappDir + 'app/routes.js', 40 | 41 | webappDir + 'app/components/core/directives/directives.js', 42 | webappDir + 'app/components/main/controllers/main.js', 43 | webappDir + 'app/components/main/services/main.js' 44 | ]; 45 | 46 | var defaultPrompt = { 47 | projectName: 'angular-spring', 48 | projectAuthor: 'John Doe', 49 | projectWebsite: 'http://github.com/madtrax', 50 | projectEmail: 'john@mycompany.com', 51 | packageName: 'com.mycompany.myapp', 52 | useAngularStrap: false, 53 | userFontAwesome: false 54 | }; 55 | 56 | var expected = defaultFiles.concat(expectedAdditionalFiles); 57 | 58 | it('creates expected files (without any optional stuff)', function (done) { 59 | 60 | 61 | helpers 62 | .run(path.join( __dirname, '../app')) 63 | .inDir(path.join(__dirname, 'temp')) 64 | .withPrompt(defaultPrompt) 65 | .on('ready', function() { }) 66 | .on('end', function() { 67 | assert.file(expected); 68 | assert.noFileContent(webappDir + 'app/app.js', /mgcrea\.ngStrap/g); 69 | assert.noFileContent(webappDir + 'templates/main/main.html', /AngularStrap/g); 70 | assert.noFileContent(webappDir + 'templates/main/main.html', /FontAwesome/g); 71 | assert.noFileContent('bower.json', /angular\-strap/g); 72 | assert.noFileContent('bower.json', /components\-font\-awesome/g); 73 | 74 | done(); 75 | }) 76 | }); 77 | 78 | 79 | it('creates expected files (+AngularStrap)', function (done) { 80 | 81 | defaultPrompt.useAngularStrap = true; 82 | 83 | helpers 84 | .run(path.join( __dirname, '../app')) 85 | .inDir(path.join(__dirname, 'temp')) 86 | .withPrompt(defaultPrompt) 87 | .on('ready', function() { }) 88 | .on('end', function() { 89 | assert.file(expected); 90 | assert.fileContent(webappDir + 'app/app.js', /mgcrea\.ngStrap/g); 91 | assert.fileContent(webappDir + 'templates/main/main.html', /AngularStrap/g); 92 | assert.noFileContent(webappDir + 'templates/main/main.html', /FontAwesome/g); 93 | assert.fileContent('bower.json', /angular\-strap/g); 94 | assert.noFileContent('bower.json', /components\-font\-awesome/g); 95 | 96 | done(); 97 | }) 98 | }); 99 | 100 | it('creates expected files (+AngularStrap +FontAwesome)', function (done) { 101 | 102 | defaultPrompt.useAngularStrap = true; 103 | defaultPrompt.useFontAwesome = true; 104 | 105 | helpers 106 | .run(path.join( __dirname, '../app')) 107 | .inDir(path.join(__dirname, 'temp')) 108 | .withPrompt(defaultPrompt) 109 | .on('ready', function() { }) 110 | .on('end', function() { 111 | assert.file(expected); 112 | assert.fileContent(webappDir + 'app/app.js', /mgcrea\.ngStrap/g); 113 | assert.fileContent(webappDir + 'templates/main/main.html', /AngularStrap/g); 114 | assert.fileContent(webappDir + 'templates/main/main.html', /FontAwesome/g); 115 | assert.fileContent(webappDir + 'templates/main/main.html', /FontAwesome/g); 116 | assert.fileContent('bower.json', /angular\-strap/g); 117 | assert.fileContent('bower.json', /components\-font\-awesome/g); 118 | done(); 119 | }) 120 | }); 121 | 122 | 123 | 124 | 125 | }); --------------------------------------------------------------------------------