- Ember.View.extend({
- attributeBindings: ['type'],
- type: 'button'
- });
- ```
-
- If the value of the property is a Boolean, the name of that property is
- added as an attribute.
-
- ```javascript
- // Renders something like
- Ember.View.extend({
- attributeBindings: ['enabled'],
- enabled: true
- });
- ```
-
- @property attributeBindings
- */
- attributeBindings: EMPTY_ARRAY,
-
- // .......................................................
- // CORE DISPLAY METHODS
- //
-
- /**
- Setup a view, but do not finish waking it up.
-
- * configure `childViews`
- * register the view with the global views hash, which is used for event
- dispatch
-
- @method init
- @private
- */
- init: function() {
- this.elementId = this.elementId || guidFor(this);
-
- this._super();
-
- // setup child views. be sure to clone the child views array first
- this._childViews = this._childViews.slice();
-
- this.classNameBindings = emberA(this.classNameBindings.slice());
-
- this.classNames = emberA(this.classNames.slice());
- },
-
- appendChild: function(view, options) {
- return this.currentState.appendChild(this, view, options);
- },
-
- /**
- Removes the child view from the parent view.
-
- @method removeChild
- @param {Ember.View} view
- @return {Ember.View} receiver
- */
- removeChild: function(view) {
- // If we're destroying, the entire subtree will be
- // freed, and the DOM will be handled separately,
- // so no need to mess with childViews.
- if (this.isDestroying) { return; }
-
- // update parent node
- set(view, '_parentView', null);
-
- // remove view from childViews array.
- var childViews = this._childViews;
-
- removeObject(childViews, view);
-
- this.propertyDidChange('childViews'); // HUH?! what happened to will change?
-
- return this;
- },
-
- /**
- Removes all children from the `parentView`.
-
- @method removeAllChildren
- @return {Ember.View} receiver
- */
- removeAllChildren: function() {
- return this.mutateChildViews(function(parentView, view) {
- parentView.removeChild(view);
- });
- },
-
- destroyAllChildren: function() {
- return this.mutateChildViews(function(parentView, view) {
- view.destroy();
- });
- },
-
- /**
- Removes the view from its `parentView`, if one is found. Otherwise
- does nothing.
-
- @method removeFromParent
- @return {Ember.View} receiver
- */
- removeFromParent: function() {
- var parent = this._parentView;
-
- // Remove DOM element from parent
- this.remove();
-
- if (parent) { parent.removeChild(this); }
- return this;
- },
-
- /**
- You must call `destroy` on a view to destroy the view (and all of its
- child views). This will remove the view from any parent node, then make
- sure that the DOM element managed by the view can be released by the
- memory manager.
-
- @method destroy
- */
- destroy: function() {
- var childViews = this._childViews,
- // get parentView before calling super because it'll be destroyed
- nonVirtualParentView = get(this, 'parentView'),
- viewName = this.viewName,
- childLen, i;
-
- if (!this._super()) { return; }
-
- childLen = childViews.length;
- for (i=childLen-1; i>=0; i--) {
- childViews[i].removedFromDOM = true;
- }
-
- // remove from non-virtual parent view if viewName was specified
- if (viewName && nonVirtualParentView) {
- nonVirtualParentView.set(viewName, null);
- }
-
- childLen = childViews.length;
- for (i=childLen-1; i>=0; i--) {
- childViews[i].destroy();
- }
-
- return this;
- },
-
- /**
- Instantiates a view to be added to the childViews array during view
- initialization. You generally will not call this method directly unless
- you are overriding `createChildViews()`. Note that this method will
- automatically configure the correct settings on the new view instance to
- act as a child of the parent.
-
- @method createChildView
- @param {Class|String} viewClass
- @param {Hash} [attrs] Attributes to add
- @return {Ember.View} new instance
- */
- createChildView: function(view, attrs) {
- if (!view) {
- throw new TypeError("createChildViews first argument must exist");
- }
-
- if (view.isView && view._parentView === this && view.container === this.container) {
- return view;
- }
-
- attrs = attrs || {};
- attrs._parentView = this;
-
- if (CoreView.detect(view)) {
- attrs.templateData = attrs.templateData || get(this, 'templateData');
-
- attrs.container = this.container;
- view = view.create(attrs);
-
- // don't set the property on a virtual view, as they are invisible to
- // consumers of the view API
- if (view.viewName) {
- set(get(this, 'concreteView'), view.viewName, view);
- }
- } else if ('string' === typeof view) {
- var fullName = 'view:' + view;
- var ViewKlass = this.container.lookupFactory(fullName);
-
-
- attrs.templateData = get(this, 'templateData');
- view = ViewKlass.create(attrs);
- } else {
- attrs.container = this.container;
-
- if (!get(view, 'templateData')) {
- attrs.templateData = get(this, 'templateData');
- }
-
- setProperties(view, attrs);
-
- }
-
- return view;
- },
-
- becameVisible: Ember.K,
- becameHidden: Ember.K,
-
- /**
- When the view's `isVisible` property changes, toggle the visibility
- element of the actual DOM element.
-
- @method _isVisibleDidChange
- @private
- */
- _isVisibleDidChange: observer('isVisible', function() {
- if (this._isVisible === get(this, 'isVisible')) { return ; }
- run.scheduleOnce('render', this, this._toggleVisibility);
- }),
-
- _toggleVisibility: function() {
- var $el = this.$();
- if (!$el) { return; }
-
- var isVisible = get(this, 'isVisible');
-
- if (this._isVisible === isVisible) { return ; }
-
- $el.toggle(isVisible);
-
- this._isVisible = isVisible;
-
- if (this._isAncestorHidden()) { return; }
-
- if (isVisible) {
- this._notifyBecameVisible();
- } else {
- this._notifyBecameHidden();
- }
- },
-
- _notifyBecameVisible: function() {
- this.trigger('becameVisible');
-
- this.forEachChildView(function(view) {
- var isVisible = get(view, 'isVisible');
-
- if (isVisible || isVisible === null) {
- view._notifyBecameVisible();
- }
- });
- },
-
- _notifyBecameHidden: function() {
- this.trigger('becameHidden');
- this.forEachChildView(function(view) {
- var isVisible = get(view, 'isVisible');
-
- if (isVisible || isVisible === null) {
- view._notifyBecameHidden();
- }
- });
- },
-
- _isAncestorHidden: function() {
- var parent = get(this, 'parentView');
-
- while (parent) {
- if (get(parent, 'isVisible') === false) { return true; }
-
- parent = get(parent, 'parentView');
- }
-
- return false;
- },
-
- clearBuffer: function() {
- this.invokeRecursively(nullViewsBuffer);
- },
- transitionTo: function(state, children) {
- this._transitionTo(state, children);
- },
- _transitionTo: function(state, children) {
- var priorState = this.currentState;
- var currentState = this.currentState = this._states[state];
-
- this._state = state;
-
- if (priorState && priorState.exit) { priorState.exit(this); }
- if (currentState.enter) { currentState.enter(this); }
- if (state === 'inDOM') { meta(this).cache.element = undefined; }
-
- if (children !== false) {
- this.forEachChildView(function(view) {
- view._transitionTo(state);
- });
- }
- },
-
- // .......................................................
- // EVENT HANDLING
- //
-
- /**
- Handle events from `Ember.EventDispatcher`
-
- @method handleEvent
- @param eventName {String}
- @param evt {Event}
- @private
- */
- handleEvent: function(eventName, evt) {
- return this.currentState.handleEvent(this, eventName, evt);
- },
-
- registerObserver: function(root, path, target, observer) {
- if (!observer && 'function' === typeof target) {
- observer = target;
- target = null;
- }
-
- if (!root || typeof root !== 'object') {
- return;
- }
-
- var view = this,
- stateCheckedObserver = function() {
- view.currentState.invokeObserver(this, observer);
- },
- scheduledObserver = function() {
- run.scheduleOnce('render', this, stateCheckedObserver);
- };
-
- addObserver(root, path, target, scheduledObserver);
-
- this.one('willClearRender', function() {
- removeObserver(root, path, target, scheduledObserver);
- });
- }
-
- });
-
- /*
- Describe how the specified actions should behave in the various
- states that a view can exist in. Possible states:
-
- * preRender: when a view is first instantiated, and after its
- element was destroyed, it is in the preRender state
- * inBuffer: once a view has been rendered, but before it has
- been inserted into the DOM, it is in the inBuffer state
- * hasElement: the DOM representation of the view is created,
- and is ready to be inserted
- * inDOM: once a view has been inserted into the DOM it is in
- the inDOM state. A view spends the vast majority of its
- existence in this state.
- * destroyed: once a view has been destroyed (using the destroy
- method), it is in this state. No further actions can be invoked
- on a destroyed view.
- */
-
- // in the destroyed state, everything is illegal
-
- // before rendering has begun, all legal manipulations are noops.
-
- // inside the buffer, legal manipulations are done on the buffer
-
- // once the view has been inserted into the DOM, legal manipulations
- // are done on the DOM element.
-
- function notifyMutationListeners() {
- run.once(View, 'notifyMutationListeners');
- }
-
- var DOMManager = {
- prepend: function(view, html) {
- view.$().prepend(html);
- notifyMutationListeners();
- },
-
- after: function(view, html) {
- view.$().after(html);
- notifyMutationListeners();
- },
-
- html: function(view, html) {
- view.$().html(html);
- notifyMutationListeners();
- },
-
- replace: function(view) {
- var element = get(view, 'element');
-
- set(view, 'element', null);
-
- view._insertElementLater(function() {
- jQuery(element).replaceWith(get(view, 'element'));
- notifyMutationListeners();
- });
- },
-
- remove: function(view) {
- view.$().remove();
- notifyMutationListeners();
- },
-
- empty: function(view) {
- view.$().empty();
- notifyMutationListeners();
- }
- };
-
- View.reopen({
- domManager: DOMManager
- });
-
- View.reopenClass({
-
- /**
- Parse a path and return an object which holds the parsed properties.
-
- For example a path like "content.isEnabled:enabled:disabled" will return the
- following object:
-
- ```javascript
- {
- path: "content.isEnabled",
- className: "enabled",
- falsyClassName: "disabled",
- classNames: ":enabled:disabled"
- }
- ```
-
- @method _parsePropertyPath
- @static
- @private
- */
- _parsePropertyPath: function(path) {
- var split = path.split(':'),
- propertyPath = split[0],
- classNames = "",
- className,
- falsyClassName;
-
- // check if the property is defined as prop:class or prop:trueClass:falseClass
- if (split.length > 1) {
- className = split[1];
- if (split.length === 3) { falsyClassName = split[2]; }
-
- classNames = ':' + className;
- if (falsyClassName) { classNames += ":" + falsyClassName; }
- }
-
- return {
- path: propertyPath,
- classNames: classNames,
- className: (className === '') ? undefined : className,
- falsyClassName: falsyClassName
- };
- },
-
- /**
- Get the class name for a given value, based on the path, optional
- `className` and optional `falsyClassName`.
-
- - if a `className` or `falsyClassName` has been specified:
- - if the value is truthy and `className` has been specified,
- `className` is returned
- - if the value is falsy and `falsyClassName` has been specified,
- `falsyClassName` is returned
- - otherwise `null` is returned
- - if the value is `true`, the dasherized last part of the supplied path
- is returned
- - if the value is not `false`, `undefined` or `null`, the `value`
- is returned
- - if none of the above rules apply, `null` is returned
-
- @method _classStringForValue
- @param path
- @param val
- @param className
- @param falsyClassName
- @static
- @private
- */
- _classStringForValue: function(path, val, className, falsyClassName) {
- if(isArray(val)) {
- val = get(val, 'length') !== 0;
- }
-
- // When using the colon syntax, evaluate the truthiness or falsiness
- // of the value to determine which className to return
- if (className || falsyClassName) {
- if (className && !!val) {
- return className;
-
- } else if (falsyClassName && !val) {
- return falsyClassName;
-
- } else {
- return null;
- }
-
- // If value is a Boolean and true, return the dasherized property
- // name.
- } else if (val === true) {
- // Normalize property path to be suitable for use
- // as a class name. For exaple, content.foo.barBaz
- // becomes bar-baz.
- var parts = path.split('.');
- return dasherize(parts[parts.length-1]);
-
- // If the value is not false, undefined, or null, return the current
- // value of the property.
- } else if (val !== false && val != null) {
- return val;
-
- // Nothing to display. Return null so that the old class is removed
- // but no new class is added.
- } else {
- return null;
- }
- }
- });
-
- var mutation = EmberObject.extend(Evented).create();
-
- View.addMutationListener = function(callback) {
- mutation.on('change', callback);
- };
-
- View.removeMutationListener = function(callback) {
- mutation.off('change', callback);
- };
-
- View.notifyMutationListeners = function() {
- mutation.trigger('change');
- };
-
- /**
- Global views hash
-
- @property views
- @static
- @type Hash
- */
- View.views = {};
-
- // If someone overrides the child views computed property when
- // defining their class, we want to be able to process the user's
- // supplied childViews and then restore the original computed property
- // at view initialization time. This happens in Ember.ContainerView's init
- // method.
- View.childViewsProperty = childViewsProperty;
-
- View.applyAttributeBindings = function(elem, name, value) {
- var type = typeOf(value);
-
- // if this changes, also change the logic in ember-handlebars/lib/helpers/binding.js
- if (name !== 'value' && (type === 'string' || (type === 'number' && !isNaN(value)))) {
- if (value !== elem.attr(name)) {
- elem.attr(name, value);
- }
- } else if (name === 'value' || type === 'boolean') {
- if (isNone(value) || value === false) {
- // `null`, `undefined` or `false` should remove attribute
- elem.removeAttr(name);
- // In IE8 `prop` couldn't remove attribute when name is `required`.
- if (name === 'required') {
- elem.removeProp(name);
- } else {
- elem.prop(name, '');
- }
- } else if (value !== elem.prop(name)) {
- // value should always be properties
- elem.prop(name, value);
- }
- } else if (!value) {
- elem.removeAttr(name);
- }
- };
-
- __exports__["default"] = View;
- });
-define("ember-views/views/view_collection",
- ["ember-metal/enumerable_utils","exports"],
- function(__dependency1__, __exports__) {
- "use strict";
- var forEach = __dependency1__.forEach;
-
- function ViewCollection(initialViews) {
- var views = this.views = initialViews || [];
- this.length = views.length;
- }
-
- ViewCollection.prototype = {
- length: 0,
-
- trigger: function(eventName) {
- var views = this.views, view;
- for (var i = 0, l = views.length; i < l; i++) {
- view = views[i];
- if (view.trigger) { view.trigger(eventName); }
- }
- },
-
- triggerRecursively: function(eventName) {
- var views = this.views;
- for (var i = 0, l = views.length; i < l; i++) {
- views[i].triggerRecursively(eventName);
- }
- },
-
- invokeRecursively: function(fn) {
- var views = this.views, view;
-
- for (var i = 0, l = views.length; i < l; i++) {
- view = views[i];
- fn(view);
- }
- },
-
- transitionTo: function(state, children) {
- var views = this.views;
- for (var i = 0, l = views.length; i < l; i++) {
- views[i]._transitionTo(state, children);
- }
- },
-
- push: function() {
- this.length += arguments.length;
- var views = this.views;
- return views.push.apply(views, arguments);
- },
-
- objectAt: function(idx) {
- return this.views[idx];
- },
-
- forEach: function(callback) {
- var views = this.views;
- return forEach(views, callback);
- },
-
- clear: function() {
- this.length = 0;
- this.views.length = 0;
- }
- };
-
- __exports__["default"] = ViewCollection;
- });
-define("ember",
- ["ember-metal","ember-runtime","ember-handlebars","ember-views","ember-routing","ember-routing-handlebars","ember-application","ember-extension-support"],
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__) {
- "use strict";
- // require the main entry points for each of these packages
- // this is so that the global exports occur properly
-
- // do this to ensure that Ember.Test is defined properly on the global
- // if it is present.
- if (Ember.__loader.registry['ember-testing']) {
- requireModule('ember-testing');
- }
-
- /**
- Ember
-
- @module ember
- */
-
- function throwWithMessage(msg) {
- return function() {
- throw new Ember.Error(msg);
- };
- }
-
- function generateRemovedClass(className) {
- var msg = " has been moved into a plugin: https://github.com/emberjs/ember-states";
-
- return {
- extend: throwWithMessage(className + msg),
- create: throwWithMessage(className + msg)
- };
- }
-
- Ember.StateManager = generateRemovedClass("Ember.StateManager");
-
- /**
- This was exported to ember-states plugin for v 1.0.0 release. See: https://github.com/emberjs/ember-states
-
- @class StateManager
- @namespace Ember
- */
-
- Ember.State = generateRemovedClass("Ember.State");
-
- /**
- This was exported to ember-states plugin for v 1.0.0 release. See: https://github.com/emberjs/ember-states
-
- @class State
- @namespace Ember
- */
- });
-define("metamorph",
- [],
- function() {
- "use strict";
- // ==========================================================================
- // Project: metamorph
- // Copyright: ©2014 Tilde, Inc. All rights reserved.
- // ==========================================================================
-
- var K = function() {},
- guid = 0,
- disableRange = (function(){
- if ('undefined' !== typeof MetamorphENV) {
- return MetamorphENV.DISABLE_RANGE_API;
- } else if ('undefined' !== ENV) {
- return ENV.DISABLE_RANGE_API;
- } else {
- return false;
- }
- })(),
-
- // Feature-detect the W3C range API, the extended check is for IE9 which only partially supports ranges
- supportsRange = (!disableRange) && typeof document !== 'undefined' && ('createRange' in document) && (typeof Range !== 'undefined') && Range.prototype.createContextualFragment,
-
- // Internet Explorer prior to 9 does not allow setting innerHTML if the first element
- // is a "zero-scope" element. This problem can be worked around by making
- // the first node an invisible text node. We, like Modernizr, use
- needsShy = typeof document !== 'undefined' && (function() {
- var testEl = document.createElement('div');
- testEl.innerHTML = "
";
- testEl.firstChild.innerHTML = "";
- return testEl.firstChild.innerHTML === '';
- })(),
-
-
- // IE 8 (and likely earlier) likes to move whitespace preceeding
- // a script tag to appear after it. This means that we can
- // accidentally remove whitespace when updating a morph.
- movesWhitespace = document && (function() {
- var testEl = document.createElement('div');
- testEl.innerHTML = "Test: Value";
- return testEl.childNodes[0].nodeValue === 'Test:' &&
- testEl.childNodes[2].nodeValue === ' Value';
- })();
-
- // Constructor that supports either Metamorph('foo') or new
- // Metamorph('foo');
- //
- // Takes a string of HTML as the argument.
-
- var Metamorph = function(html) {
- var self;
-
- if (this instanceof Metamorph) {
- self = this;
- } else {
- self = new K();
- }
-
- self.innerHTML = html;
- var myGuid = 'metamorph-'+(guid++);
- self.start = myGuid + '-start';
- self.end = myGuid + '-end';
-
- return self;
- };
-
- K.prototype = Metamorph.prototype;
-
- var rangeFor, htmlFunc, removeFunc, outerHTMLFunc, appendToFunc, afterFunc, prependFunc, startTagFunc, endTagFunc;
-
- outerHTMLFunc = function() {
- return this.startTag() + this.innerHTML + this.endTag();
- };
-
- startTagFunc = function() {
- /*
- * We replace chevron by its hex code in order to prevent escaping problems.
- * Check this thread for more explaination:
- * http://stackoverflow.com/questions/8231048/why-use-x3c-instead-of-when-generating-html-from-javascript
- */
- return "
hi ";
- * div.firstChild.firstChild.tagName //=> ""
- *
- * If our script markers are inside such a node, we need to find that
- * node and use *it* as the marker.
- */
- var realNode = function(start) {
- while (start.parentNode.tagName === "") {
- start = start.parentNode;
- }
-
- return start;
- };
-
- /*
- * When automatically adding a tbody, Internet Explorer inserts the
- * tbody immediately before the first
. Other browsers create it
- * before the first node, no matter what.
- *
- * This means the the following code:
- *
- * div = document.createElement("div");
- * div.innerHTML = "
- *
- * Generates the following DOM in IE:
- *
- * + div
- * + table
- * - script id='first'
- * + tbody
- * + tr
- * + td
- * - "hi"
- * - script id='last'
- *
- * Which means that the two script tags, even though they were
- * inserted at the same point in the hierarchy in the original
- * HTML, now have different parents.
- *
- * This code reparents the first script tag by making it the tbody's
- * first child.
- *
- */
- var fixParentage = function(start, end) {
- if (start.parentNode !== end.parentNode) {
- end.parentNode.insertBefore(start, end.parentNode.firstChild);
- }
- };
-
- htmlFunc = function(html, outerToo) {
- // get the real starting node. see realNode for details.
- var start = realNode(document.getElementById(this.start));
- var end = document.getElementById(this.end);
- var parentNode = end.parentNode;
- var node, nextSibling, last;
-
- // make sure that the start and end nodes share the same
- // parent. If not, fix it.
- fixParentage(start, end);
-
- // remove all of the nodes after the starting placeholder and
- // before the ending placeholder.
- node = start.nextSibling;
- while (node) {
- nextSibling = node.nextSibling;
- last = node === end;
-
- // if this is the last node, and we want to remove it as well,
- // set the `end` node to the next sibling. This is because
- // for the rest of the function, we insert the new nodes
- // before the end (note that insertBefore(node, null) is
- // the same as appendChild(node)).
- //
- // if we do not want to remove it, just break.
- if (last) {
- if (outerToo) { end = node.nextSibling; } else { break; }
- }
-
- node.parentNode.removeChild(node);
-
- // if this is the last node and we didn't break before
- // (because we wanted to remove the outer nodes), break
- // now.
- if (last) { break; }
-
- node = nextSibling;
- }
-
- // get the first node for the HTML string, even in cases like
- // tables and lists where a simple innerHTML on a div would
- // swallow some of the content.
- node = firstNodeFor(start.parentNode, html);
-
- if (outerToo) {
- start.parentNode.removeChild(start);
- }
-
- // copy the nodes for the HTML between the starting and ending
- // placeholder.
- while (node) {
- nextSibling = node.nextSibling;
- parentNode.insertBefore(node, end);
- node = nextSibling;
- }
- };
-
- // remove the nodes in the DOM representing this metamorph.
- //
- // this includes the starting and ending placeholders.
- removeFunc = function() {
- var start = realNode(document.getElementById(this.start));
- var end = document.getElementById(this.end);
-
- this.html('');
- start.parentNode.removeChild(start);
- end.parentNode.removeChild(end);
- };
-
- appendToFunc = function(parentNode) {
- var node = firstNodeFor(parentNode, this.outerHTML());
- var nextSibling;
-
- while (node) {
- nextSibling = node.nextSibling;
- parentNode.appendChild(node);
- node = nextSibling;
- }
- };
-
- afterFunc = function(html) {
- // get the real starting node. see realNode for details.
- var end = document.getElementById(this.end);
- var insertBefore = end.nextSibling;
- var parentNode = end.parentNode;
- var nextSibling;
- var node;
-
- // get the first node for the HTML string, even in cases like
- // tables and lists where a simple innerHTML on a div would
- // swallow some of the content.
- node = firstNodeFor(parentNode, html);
-
- // copy the nodes for the HTML between the starting and ending
- // placeholder.
- while (node) {
- nextSibling = node.nextSibling;
- parentNode.insertBefore(node, insertBefore);
- node = nextSibling;
- }
- };
-
- prependFunc = function(html) {
- var start = document.getElementById(this.start);
- var parentNode = start.parentNode;
- var nextSibling;
- var node;
-
- node = firstNodeFor(parentNode, html);
- var insertBefore = start.nextSibling;
-
- while (node) {
- nextSibling = node.nextSibling;
- parentNode.insertBefore(node, insertBefore);
- node = nextSibling;
- }
- };
- }
-
- Metamorph.prototype.html = function(html) {
- this.checkRemoved();
- if (html === undefined) { return this.innerHTML; }
-
- htmlFunc.call(this, html);
-
- this.innerHTML = html;
- };
-
- Metamorph.prototype.replaceWith = function(html) {
- this.checkRemoved();
- htmlFunc.call(this, html, true);
- };
-
- Metamorph.prototype.remove = removeFunc;
- Metamorph.prototype.outerHTML = outerHTMLFunc;
- Metamorph.prototype.appendTo = appendToFunc;
- Metamorph.prototype.after = afterFunc;
- Metamorph.prototype.prepend = prependFunc;
- Metamorph.prototype.startTag = startTagFunc;
- Metamorph.prototype.endTag = endTagFunc;
-
- Metamorph.prototype.isRemoved = function() {
- var before = document.getElementById(this.start);
- var after = document.getElementById(this.end);
-
- return !before || !after;
- };
-
- Metamorph.prototype.checkRemoved = function() {
- if (this.isRemoved()) {
- throw new Error("Cannot perform operations on a Metamorph that is not in the DOM.");
- }
- };
-
- return Metamorph;
- });
-
-define("route-recognizer",
- ["route-recognizer/dsl","exports"],
- function(__dependency1__, __exports__) {
- "use strict";
- var map = __dependency1__["default"];
-
- var specials = [
- '/', '.', '*', '+', '?', '|',
- '(', ')', '[', ']', '{', '}', '\\'
- ];
-
- var escapeRegex = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
-
- function isArray(test) {
- return Object.prototype.toString.call(test) === "[object Array]";
- }
-
- // A Segment represents a segment in the original route description.
- // Each Segment type provides an `eachChar` and `regex` method.
- //
- // The `eachChar` method invokes the callback with one or more character
- // specifications. A character specification consumes one or more input
- // characters.
- //
- // The `regex` method returns a regex fragment for the segment. If the
- // segment is a dynamic of star segment, the regex fragment also includes
- // a capture.
- //
- // A character specification contains:
- //
- // * `validChars`: a String with a list of all valid characters, or
- // * `invalidChars`: a String with a list of all invalid characters
- // * `repeat`: true if the character specification can repeat
-
- function StaticSegment(string) { this.string = string; }
- StaticSegment.prototype = {
- eachChar: function(callback) {
- var string = this.string, ch;
-
- for (var i=0, l=string.length; i " + n.nextStates.map(function(s) { return s.debug() }).join(" or ") + " )";
- }).join(", ")
- }
- END IF **/
-
- // This is a somewhat naive strategy, but should work in a lot of cases
- // A better strategy would properly resolve /posts/:id/new and /posts/edit/:id.
- //
- // This strategy generally prefers more static and less dynamic matching.
- // Specifically, it
- //
- // * prefers fewer stars to more, then
- // * prefers using stars for less of the match to more, then
- // * prefers fewer dynamic segments to more, then
- // * prefers more static segments to more
- function sortSolutions(states) {
- return states.sort(function(a, b) {
- if (a.types.stars !== b.types.stars) { return a.types.stars - b.types.stars; }
-
- if (a.types.stars) {
- if (a.types.statics !== b.types.statics) { return b.types.statics - a.types.statics; }
- if (a.types.dynamics !== b.types.dynamics) { return b.types.dynamics - a.types.dynamics; }
- }
-
- if (a.types.dynamics !== b.types.dynamics) { return a.types.dynamics - b.types.dynamics; }
- if (a.types.statics !== b.types.statics) { return b.types.statics - a.types.statics; }
-
- return 0;
- });
- }
-
- function recognizeChar(states, ch) {
- var nextStates = [];
-
- for (var i=0, l=states.length; i 2 && key.slice(keyLength -2) === '[]') {
- isArray = true;
- key = key.slice(0, keyLength - 2);
- if(!queryParams[key]) {
- queryParams[key] = [];
- }
- }
- value = pair[1] ? decodeURIComponent(pair[1]) : '';
- }
- if (isArray) {
- queryParams[key].push(value);
- } else {
- queryParams[key] = value;
- }
- }
- return queryParams;
- },
-
- recognize: function(path) {
- var states = [ this.rootState ],
- pathLen, i, l, queryStart, queryParams = {},
- isSlashDropped = false;
-
- queryStart = path.indexOf('?');
- if (queryStart !== -1) {
- var queryString = path.substr(queryStart + 1, path.length);
- path = path.substr(0, queryStart);
- queryParams = this.parseQueryString(queryString);
- }
-
- path = decodeURI(path);
-
- // DEBUG GROUP path
-
- if (path.charAt(0) !== "/") { path = "/" + path; }
-
- pathLen = path.length;
- if (pathLen > 1 && path.charAt(pathLen - 1) === "/") {
- path = path.substr(0, pathLen - 1);
- isSlashDropped = true;
- }
-
- for (i=0, l=path.length; i= 0 && proceed; --i) {
- var route = routes[i];
- recognizer.add(routes, { as: route.handler });
- proceed = route.path === '/' || route.path === '' || route.handler.slice(-6) === '.index';
- }
- });
- },
-
- hasRoute: function(route) {
- return this.recognizer.hasRoute(route);
- },
-
- queryParamsTransition: function(changelist, wasTransitioning, oldState, newState) {
- var router = this;
-
- fireQueryParamDidChange(this, newState, changelist);
-
- if (!wasTransitioning && this.activeTransition) {
- // One of the handlers in queryParamsDidChange
- // caused a transition. Just return that transition.
- return this.activeTransition;
- } else {
- // Running queryParamsDidChange didn't change anything.
- // Just update query params and be on our way.
-
- // We have to return a noop transition that will
- // perform a URL update at the end. This gives
- // the user the ability to set the url update
- // method (default is replaceState).
- var newTransition = new Transition(this);
- newTransition.queryParamsOnly = true;
-
- oldState.queryParams = finalizeQueryParamChange(this, newState.handlerInfos, newState.queryParams, newTransition);
-
- newTransition.promise = newTransition.promise.then(function(result) {
- updateURL(newTransition, oldState, true);
- if (router.didTransition) {
- router.didTransition(router.currentHandlerInfos);
- }
- return result;
- }, null, promiseLabel("Transition complete"));
- return newTransition;
- }
- },
-
- // NOTE: this doesn't really belong here, but here
- // it shall remain until our ES6 transpiler can
- // handle cyclical deps.
- transitionByIntent: function(intent, isIntermediate) {
-
- var wasTransitioning = !!this.activeTransition;
- var oldState = wasTransitioning ? this.activeTransition.state : this.state;
- var newTransition;
- var router = this;
-
- try {
- var newState = intent.applyToState(oldState, this.recognizer, this.getHandler, isIntermediate);
- var queryParamChangelist = getChangelist(oldState.queryParams, newState.queryParams);
-
- if (handlerInfosEqual(newState.handlerInfos, oldState.handlerInfos)) {
-
- // This is a no-op transition. See if query params changed.
- if (queryParamChangelist) {
- newTransition = this.queryParamsTransition(queryParamChangelist, wasTransitioning, oldState, newState);
- if (newTransition) {
- return newTransition;
- }
- }
-
- // No-op. No need to create a new transition.
- return new Transition(this);
- }
-
- if (isIntermediate) {
- setupContexts(this, newState);
- return;
- }
-
- // Create a new transition to the destination route.
- newTransition = new Transition(this, intent, newState);
-
- // Abort and usurp any previously active transition.
- if (this.activeTransition) {
- this.activeTransition.abort();
- }
- this.activeTransition = newTransition;
-
- // Transition promises by default resolve with resolved state.
- // For our purposes, swap out the promise to resolve
- // after the transition has been finalized.
- newTransition.promise = newTransition.promise.then(function(result) {
- return finalizeTransition(newTransition, result.state);
- }, null, promiseLabel("Settle transition promise when transition is finalized"));
-
- if (!wasTransitioning) {
- notifyExistingHandlers(this, newState, newTransition);
- }
-
- fireQueryParamDidChange(this, newState, queryParamChangelist);
-
- return newTransition;
- } catch(e) {
- return new Transition(this, intent, null, e);
- }
- },
-
- /**
- Clears the current and target route handlers and triggers exit
- on each of them starting at the leaf and traversing up through
- its ancestors.
- */
- reset: function() {
- if (this.state) {
- forEach(this.state.handlerInfos.slice().reverse(), function(handlerInfo) {
- var handler = handlerInfo.handler;
- callHook(handler, 'exit');
- });
- }
-
- this.state = new TransitionState();
- this.currentHandlerInfos = null;
- },
-
- activeTransition: null,
-
- /**
- var handler = handlerInfo.handler;
- The entry point for handling a change to the URL (usually
- via the back and forward button).
-
- Returns an Array of handlers and the parameters associated
- with those parameters.
-
- @param {String} url a URL to process
-
- @return {Array} an Array of `[handler, parameter]` tuples
- */
- handleURL: function(url) {
- // Perform a URL-based transition, but don't change
- // the URL afterward, since it already happened.
- var args = slice.call(arguments);
- if (url.charAt(0) !== '/') { args[0] = '/' + url; }
-
- return doTransition(this, args).method(null);
- },
-
- /**
- Hook point for updating the URL.
-
- @param {String} url a URL to update to
- */
- updateURL: function() {
- throw new Error("updateURL is not implemented");
- },
-
- /**
- Hook point for replacing the current URL, i.e. with replaceState
-
- By default this behaves the same as `updateURL`
-
- @param {String} url a URL to update to
- */
- replaceURL: function(url) {
- this.updateURL(url);
- },
-
- /**
- Transition into the specified named route.
-
- If necessary, trigger the exit callback on any handlers
- that are no longer represented by the target route.
-
- @param {String} name the name of the route
- */
- transitionTo: function(name) {
- return doTransition(this, arguments);
- },
-
- intermediateTransitionTo: function(name) {
- return doTransition(this, arguments, true);
- },
-
- refresh: function(pivotHandler) {
- var state = this.activeTransition ? this.activeTransition.state : this.state;
- var handlerInfos = state.handlerInfos;
- var params = {};
- for (var i = 0, len = handlerInfos.length; i < len; ++i) {
- var handlerInfo = handlerInfos[i];
- params[handlerInfo.name] = handlerInfo.params || {};
- }
-
- log(this, "Starting a refresh transition");
- var intent = new NamedTransitionIntent({
- name: handlerInfos[handlerInfos.length - 1].name,
- pivotHandler: pivotHandler || handlerInfos[0].handler,
- contexts: [], // TODO collect contexts...?
- queryParams: this._changedQueryParams || state.queryParams || {}
- });
-
- return this.transitionByIntent(intent, false);
- },
-
- /**
- Identical to `transitionTo` except that the current URL will be replaced
- if possible.
-
- This method is intended primarily for use with `replaceState`.
-
- @param {String} name the name of the route
- */
- replaceWith: function(name) {
- return doTransition(this, arguments).method('replace');
- },
-
- /**
- Take a named route and context objects and generate a
- URL.
-
- @param {String} name the name of the route to generate
- a URL for
- @param {...Object} objects a list of objects to serialize
-
- @return {String} a URL
- */
- generate: function(handlerName) {
-
- var partitionedArgs = extractQueryParams(slice.call(arguments, 1)),
- suppliedParams = partitionedArgs[0],
- queryParams = partitionedArgs[1];
-
- // Construct a TransitionIntent with the provided params
- // and apply it to the present state of the router.
- var intent = new NamedTransitionIntent({ name: handlerName, contexts: suppliedParams });
- var state = intent.applyToState(this.state, this.recognizer, this.getHandler);
- var params = {};
-
- for (var i = 0, len = state.handlerInfos.length; i < len; ++i) {
- var handlerInfo = state.handlerInfos[i];
- var handlerParams = handlerInfo.serialize();
- merge(params, handlerParams);
- }
- params.queryParams = queryParams;
-
- return this.recognizer.generate(handlerName, params);
- },
-
- applyIntent: function(handlerName, contexts) {
- var intent = new NamedTransitionIntent({
- name: handlerName,
- contexts: contexts
- });
-
- var state = this.activeTransition && this.activeTransition.state || this.state;
- return intent.applyToState(state, this.recognizer, this.getHandler);
- },
-
- isActiveIntent: function(handlerName, contexts, queryParams) {
- var targetHandlerInfos = this.state.handlerInfos,
- found = false, names, object, handlerInfo, handlerObj, i, len;
-
- if (!targetHandlerInfos.length) { return false; }
-
- var targetHandler = targetHandlerInfos[targetHandlerInfos.length - 1].name;
- var recogHandlers = this.recognizer.handlersFor(targetHandler);
-
- var index = 0;
- for (len = recogHandlers.length; index < len; ++index) {
- handlerInfo = targetHandlerInfos[index];
- if (handlerInfo.name === handlerName) { break; }
- }
-
- if (index === recogHandlers.length) {
- // The provided route name isn't even in the route hierarchy.
- return false;
- }
-
- var state = new TransitionState();
- state.handlerInfos = targetHandlerInfos.slice(0, index + 1);
- recogHandlers = recogHandlers.slice(0, index + 1);
-
- var intent = new NamedTransitionIntent({
- name: targetHandler,
- contexts: contexts
- });
-
- var newState = intent.applyToHandlers(state, recogHandlers, this.getHandler, targetHandler, true, true);
-
- var handlersEqual = handlerInfosEqual(newState.handlerInfos, state.handlerInfos);
- if (!queryParams || !handlersEqual) {
- return handlersEqual;
- }
-
- // Get a hash of QPs that will still be active on new route
- var activeQPsOnNewHandler = {};
- merge(activeQPsOnNewHandler, queryParams);
-
- var activeQueryParams = this.state.queryParams;
- for (var key in activeQueryParams) {
- if (activeQueryParams.hasOwnProperty(key) &&
- activeQPsOnNewHandler.hasOwnProperty(key)) {
- activeQPsOnNewHandler[key] = activeQueryParams[key];
- }
- }
-
- return handlersEqual && !getChangelist(activeQPsOnNewHandler, queryParams);
- },
-
- isActive: function(handlerName) {
- var partitionedArgs = extractQueryParams(slice.call(arguments, 1));
- return this.isActiveIntent(handlerName, partitionedArgs[0], partitionedArgs[1]);
- },
-
- trigger: function(name) {
- var args = slice.call(arguments);
- trigger(this, this.currentHandlerInfos, false, args);
- },
-
- /**
- Hook point for logging transition status updates.
-
- @param {String} message The message to log.
- */
- log: null,
-
- _willChangeContextEvent: 'willChangeContext',
- _triggerWillChangeContext: function(handlerInfos, newTransition) {
- trigger(this, handlerInfos, true, [this._willChangeContextEvent, newTransition]);
- },
-
- _triggerWillLeave: function(handlerInfos, newTransition, leavingChecker) {
- trigger(this, handlerInfos, true, ['willLeave', newTransition, leavingChecker]);
- }
- };
-
- /**
- @private
-
- Fires queryParamsDidChange event
- */
- function fireQueryParamDidChange(router, newState, queryParamChangelist) {
- // If queryParams changed trigger event
- if (queryParamChangelist) {
-
- // This is a little hacky but we need some way of storing
- // changed query params given that no activeTransition
- // is guaranteed to have occurred.
- router._changedQueryParams = queryParamChangelist.all;
- trigger(router, newState.handlerInfos, true, ['queryParamsDidChange', queryParamChangelist.changed, queryParamChangelist.all, queryParamChangelist.removed]);
- router._changedQueryParams = null;
- }
- }
-
- /**
- @private
-
- Takes an Array of `HandlerInfo`s, figures out which ones are
- exiting, entering, or changing contexts, and calls the
- proper handler hooks.
-
- For example, consider the following tree of handlers. Each handler is
- followed by the URL segment it handles.
-
- ```
- |~index ("/")
- | |~posts ("/posts")
- | | |-showPost ("/:id")
- | | |-newPost ("/new")
- | | |-editPost ("/edit")
- | |~about ("/about/:id")
- ```
-
- Consider the following transitions:
-
- 1. A URL transition to `/posts/1`.
- 1. Triggers the `*model` callbacks on the
- `index`, `posts`, and `showPost` handlers
- 2. Triggers the `enter` callback on the same
- 3. Triggers the `setup` callback on the same
- 2. A direct transition to `newPost`
- 1. Triggers the `exit` callback on `showPost`
- 2. Triggers the `enter` callback on `newPost`
- 3. Triggers the `setup` callback on `newPost`
- 3. A direct transition to `about` with a specified
- context object
- 1. Triggers the `exit` callback on `newPost`
- and `posts`
- 2. Triggers the `serialize` callback on `about`
- 3. Triggers the `enter` callback on `about`
- 4. Triggers the `setup` callback on `about`
-
- @param {Router} transition
- @param {TransitionState} newState
- */
- function setupContexts(router, newState, transition) {
- var partition = partitionHandlers(router.state, newState);
-
- forEach(partition.exited, function(handlerInfo) {
- var handler = handlerInfo.handler;
- delete handler.context;
-
- callHook(handler, 'reset', true, transition);
- callHook(handler, 'exit', transition);
- });
-
- var oldState = router.oldState = router.state;
- router.state = newState;
- var currentHandlerInfos = router.currentHandlerInfos = partition.unchanged.slice();
-
- try {
- forEach(partition.reset, function(handlerInfo) {
- var handler = handlerInfo.handler;
- callHook(handler, 'reset', false, transition);
- });
-
- forEach(partition.updatedContext, function(handlerInfo) {
- return handlerEnteredOrUpdated(currentHandlerInfos, handlerInfo, false, transition);
- });
-
- forEach(partition.entered, function(handlerInfo) {
- return handlerEnteredOrUpdated(currentHandlerInfos, handlerInfo, true, transition);
- });
- } catch(e) {
- router.state = oldState;
- router.currentHandlerInfos = oldState.handlerInfos;
- throw e;
- }
-
- router.state.queryParams = finalizeQueryParamChange(router, currentHandlerInfos, newState.queryParams, transition);
- }
-
-
- /**
- @private
-
- Helper method used by setupContexts. Handles errors or redirects
- that may happen in enter/setup.
- */
- function handlerEnteredOrUpdated(currentHandlerInfos, handlerInfo, enter, transition) {
-
- var handler = handlerInfo.handler,
- context = handlerInfo.context;
-
- callHook(handler, 'enter', transition);
- if (transition && transition.isAborted) {
- throw new TransitionAborted();
- }
-
- handler.context = context;
- callHook(handler, 'contextDidChange');
-
- callHook(handler, 'setup', context, transition);
- if (transition && transition.isAborted) {
- throw new TransitionAborted();
- }
-
- currentHandlerInfos.push(handlerInfo);
-
- return true;
- }
-
-
- /**
- @private
-
- This function is called when transitioning from one URL to
- another to determine which handlers are no longer active,
- which handlers are newly active, and which handlers remain
- active but have their context changed.
-
- Take a list of old handlers and new handlers and partition
- them into four buckets:
-
- * unchanged: the handler was active in both the old and
- new URL, and its context remains the same
- * updated context: the handler was active in both the
- old and new URL, but its context changed. The handler's
- `setup` method, if any, will be called with the new
- context.
- * exited: the handler was active in the old URL, but is
- no longer active.
- * entered: the handler was not active in the old URL, but
- is now active.
-
- The PartitionedHandlers structure has four fields:
-
- * `updatedContext`: a list of `HandlerInfo` objects that
- represent handlers that remain active but have a changed
- context
- * `entered`: a list of `HandlerInfo` objects that represent
- handlers that are newly active
- * `exited`: a list of `HandlerInfo` objects that are no
- longer active.
- * `unchanged`: a list of `HanderInfo` objects that remain active.
-
- @param {Array[HandlerInfo]} oldHandlers a list of the handler
- information for the previous URL (or `[]` if this is the
- first handled transition)
- @param {Array[HandlerInfo]} newHandlers a list of the handler
- information for the new URL
-
- @return {Partition}
- */
- function partitionHandlers(oldState, newState) {
- var oldHandlers = oldState.handlerInfos;
- var newHandlers = newState.handlerInfos;
-
- var handlers = {
- updatedContext: [],
- exited: [],
- entered: [],
- unchanged: []
- };
-
- var handlerChanged, contextChanged = false, i, l;
-
- for (i=0, l=newHandlers.length; i= 0; --i) {
- var handlerInfo = handlerInfos[i];
- merge(params, handlerInfo.params);
- if (handlerInfo.handler.inaccessibleByURL) {
- urlMethod = null;
- }
- }
-
- if (urlMethod) {
- params.queryParams = transition._visibleQueryParams || state.queryParams;
- var url = router.recognizer.generate(handlerName, params);
-
- if (urlMethod === 'replace') {
- router.replaceURL(url);
- } else {
- router.updateURL(url);
- }
- }
- }
-
- /**
- @private
-
- Updates the URL (if necessary) and calls `setupContexts`
- to update the router's array of `currentHandlerInfos`.
- */
- function finalizeTransition(transition, newState) {
-
- try {
- log(transition.router, transition.sequence, "Resolved all models on destination route; finalizing transition.");
-
- var router = transition.router,
- handlerInfos = newState.handlerInfos,
- seq = transition.sequence;
-
- // Run all the necessary enter/setup/exit hooks
- setupContexts(router, newState, transition);
-
- // Check if a redirect occurred in enter/setup
- if (transition.isAborted) {
- // TODO: cleaner way? distinguish b/w targetHandlerInfos?
- router.state.handlerInfos = router.currentHandlerInfos;
- return Promise.reject(logAbort(transition));
- }
-
- updateURL(transition, newState, transition.intent.url);
-
- transition.isActive = false;
- router.activeTransition = null;
-
- trigger(router, router.currentHandlerInfos, true, ['didTransition']);
-
- if (router.didTransition) {
- router.didTransition(router.currentHandlerInfos);
- }
-
- log(router, transition.sequence, "TRANSITION COMPLETE.");
-
- // Resolve with the final handler.
- return handlerInfos[handlerInfos.length - 1].handler;
- } catch(e) {
- if (!((e instanceof TransitionAborted))) {
- //var erroneousHandler = handlerInfos.pop();
- var infos = transition.state.handlerInfos;
- transition.trigger(true, 'error', e, transition, infos[infos.length-1].handler);
- transition.abort();
- }
-
- throw e;
- }
- }
-
- /**
- @private
-
- Begins and returns a Transition based on the provided
- arguments. Accepts arguments in the form of both URL
- transitions and named transitions.
-
- @param {Router} router
- @param {Array[Object]} args arguments passed to transitionTo,
- replaceWith, or handleURL
- */
- function doTransition(router, args, isIntermediate) {
- // Normalize blank transitions to root URL transitions.
- var name = args[0] || '/';
-
- var lastArg = args[args.length-1];
- var queryParams = {};
- if (lastArg && lastArg.hasOwnProperty('queryParams')) {
- queryParams = pop.call(args).queryParams;
- }
-
- var intent;
- if (args.length === 0) {
-
- log(router, "Updating query params");
-
- // A query param update is really just a transition
- // into the route you're already on.
- var handlerInfos = router.state.handlerInfos;
- intent = new NamedTransitionIntent({
- name: handlerInfos[handlerInfos.length - 1].name,
- contexts: [],
- queryParams: queryParams
- });
-
- } else if (name.charAt(0) === '/') {
-
- log(router, "Attempting URL transition to " + name);
- intent = new URLTransitionIntent({ url: name });
-
- } else {
-
- log(router, "Attempting transition to " + name);
- intent = new NamedTransitionIntent({
- name: args[0],
- contexts: slice.call(args, 1),
- queryParams: queryParams
- });
- }
-
- return router.transitionByIntent(intent, isIntermediate);
- }
-
- function handlerInfosEqual(handlerInfos, otherHandlerInfos) {
- if (handlerInfos.length !== otherHandlerInfos.length) {
- return false;
- }
-
- for (var i = 0, len = handlerInfos.length; i < len; ++i) {
- if (handlerInfos[i] !== otherHandlerInfos[i]) {
- return false;
- }
- }
- return true;
- }
-
- function finalizeQueryParamChange(router, resolvedHandlers, newQueryParams, transition) {
- // We fire a finalizeQueryParamChange event which
- // gives the new route hierarchy a chance to tell
- // us which query params it's consuming and what
- // their final values are. If a query param is
- // no longer consumed in the final route hierarchy,
- // its serialized segment will be removed
- // from the URL.
-
- for (var k in newQueryParams) {
- if (newQueryParams.hasOwnProperty(k) &&
- newQueryParams[k] === null) {
- delete newQueryParams[k];
- }
- }
-
- var finalQueryParamsArray = [];
- trigger(router, resolvedHandlers, true, ['finalizeQueryParamChange', newQueryParams, finalQueryParamsArray, transition]);
-
- if (transition) {
- transition._visibleQueryParams = {};
- }
-
- var finalQueryParams = {};
- for (var i = 0, len = finalQueryParamsArray.length; i < len; ++i) {
- var qp = finalQueryParamsArray[i];
- finalQueryParams[qp.key] = qp.value;
- if (transition && qp.visible !== false) {
- transition._visibleQueryParams[qp.key] = qp.value;
- }
- }
- return finalQueryParams;
- }
-
- function notifyExistingHandlers(router, newState, newTransition) {
- var oldHandlers = router.state.handlerInfos,
- changing = [],
- leavingIndex = null,
- leaving, leavingChecker, i, oldHandlerLen, oldHandler, newHandler;
-
- oldHandlerLen = oldHandlers.length;
- for (i = 0; i < oldHandlerLen; i++) {
- oldHandler = oldHandlers[i];
- newHandler = newState.handlerInfos[i];
-
- if (!newHandler || oldHandler.name !== newHandler.name) {
- leavingIndex = i;
- break;
- }
-
- if (!newHandler.isResolved) {
- changing.push(oldHandler);
- }
- }
-
- if (leavingIndex !== null) {
- leaving = oldHandlers.slice(leavingIndex, oldHandlerLen);
- leavingChecker = function(name) {
- for (var h = 0, len = leaving.length; h < len; h++) {
- if (leaving[h].name === name) {
- return true;
- }
- }
- return false;
- };
-
- router._triggerWillLeave(leaving, newTransition, leavingChecker);
- }
-
- if (changing.length > 0) {
- router._triggerWillChangeContext(changing, newTransition);
- }
-
- trigger(router, oldHandlers, true, ['willTransition', newTransition]);
- }
-
- __exports__["default"] = Router;
- });
-define("router/transition-intent",
- ["./utils","exports"],
- function(__dependency1__, __exports__) {
- "use strict";
- var merge = __dependency1__.merge;
-
- function TransitionIntent(props) {
- this.initialize(props);
-
- // TODO: wat
- this.data = this.data || {};
- }
-
- TransitionIntent.prototype = {
- initialize: null,
- applyToState: null
- };
-
- __exports__["default"] = TransitionIntent;
- });
-define("router/transition-intent/named-transition-intent",
- ["../transition-intent","../transition-state","../handler-info/factory","../utils","exports"],
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
- "use strict";
- var TransitionIntent = __dependency1__["default"];
- var TransitionState = __dependency2__["default"];
- var handlerInfoFactory = __dependency3__["default"];
- var isParam = __dependency4__.isParam;
- var extractQueryParams = __dependency4__.extractQueryParams;
- var merge = __dependency4__.merge;
- var subclass = __dependency4__.subclass;
-
- __exports__["default"] = subclass(TransitionIntent, {
- name: null,
- pivotHandler: null,
- contexts: null,
- queryParams: null,
-
- initialize: function(props) {
- this.name = props.name;
- this.pivotHandler = props.pivotHandler;
- this.contexts = props.contexts || [];
- this.queryParams = props.queryParams;
- },
-
- applyToState: function(oldState, recognizer, getHandler, isIntermediate) {
-
- var partitionedArgs = extractQueryParams([this.name].concat(this.contexts)),
- pureArgs = partitionedArgs[0],
- queryParams = partitionedArgs[1],
- handlers = recognizer.handlersFor(pureArgs[0]);
-
- var targetRouteName = handlers[handlers.length-1].handler;
-
- return this.applyToHandlers(oldState, handlers, getHandler, targetRouteName, isIntermediate);
- },
-
- applyToHandlers: function(oldState, handlers, getHandler, targetRouteName, isIntermediate, checkingIfActive) {
-
- var i, len;
- var newState = new TransitionState();
- var objects = this.contexts.slice(0);
-
- var invalidateIndex = handlers.length;
-
- // Pivot handlers are provided for refresh transitions
- if (this.pivotHandler) {
- for (i = 0, len = handlers.length; i < len; ++i) {
- if (getHandler(handlers[i].handler) === this.pivotHandler) {
- invalidateIndex = i;
- break;
- }
- }
- }
-
- var pivotHandlerFound = !this.pivotHandler;
-
- for (i = handlers.length - 1; i >= 0; --i) {
- var result = handlers[i];
- var name = result.handler;
- var handler = getHandler(name);
-
- var oldHandlerInfo = oldState.handlerInfos[i];
- var newHandlerInfo = null;
-
- if (result.names.length > 0) {
- if (i >= invalidateIndex) {
- newHandlerInfo = this.createParamHandlerInfo(name, handler, result.names, objects, oldHandlerInfo);
- } else {
- newHandlerInfo = this.getHandlerInfoForDynamicSegment(name, handler, result.names, objects, oldHandlerInfo, targetRouteName, i);
- }
- } else {
- // This route has no dynamic segment.
- // Therefore treat as a param-based handlerInfo
- // with empty params. This will cause the `model`
- // hook to be called with empty params, which is desirable.
- newHandlerInfo = this.createParamHandlerInfo(name, handler, result.names, objects, oldHandlerInfo);
- }
-
- if (checkingIfActive) {
- // If we're performing an isActive check, we want to
- // serialize URL params with the provided context, but
- // ignore mismatches between old and new context.
- newHandlerInfo = newHandlerInfo.becomeResolved(null, newHandlerInfo.context);
- var oldContext = oldHandlerInfo && oldHandlerInfo.context;
- if (result.names.length > 0 && newHandlerInfo.context === oldContext) {
- // If contexts match in isActive test, assume params also match.
- // This allows for flexibility in not requiring that every last
- // handler provide a `serialize` method
- newHandlerInfo.params = oldHandlerInfo && oldHandlerInfo.params;
- }
- newHandlerInfo.context = oldContext;
- }
-
- var handlerToUse = oldHandlerInfo;
- if (i >= invalidateIndex || newHandlerInfo.shouldSupercede(oldHandlerInfo)) {
- invalidateIndex = Math.min(i, invalidateIndex);
- handlerToUse = newHandlerInfo;
- }
-
- if (isIntermediate && !checkingIfActive) {
- handlerToUse = handlerToUse.becomeResolved(null, handlerToUse.context);
- }
-
- newState.handlerInfos.unshift(handlerToUse);
- }
-
- if (objects.length > 0) {
- throw new Error("More context objects were passed than there are dynamic segments for the route: " + targetRouteName);
- }
-
- if (!isIntermediate) {
- this.invalidateChildren(newState.handlerInfos, invalidateIndex);
- }
-
- merge(newState.queryParams, this.queryParams || {});
-
- return newState;
- },
-
- invalidateChildren: function(handlerInfos, invalidateIndex) {
- for (var i = invalidateIndex, l = handlerInfos.length; i < l; ++i) {
- var handlerInfo = handlerInfos[i];
- handlerInfos[i] = handlerInfos[i].getUnresolved();
- }
- },
-
- getHandlerInfoForDynamicSegment: function(name, handler, names, objects, oldHandlerInfo, targetRouteName, i) {
-
- var numNames = names.length;
- var objectToUse;
- if (objects.length > 0) {
-
- // Use the objects provided for this transition.
- objectToUse = objects[objects.length - 1];
- if (isParam(objectToUse)) {
- return this.createParamHandlerInfo(name, handler, names, objects, oldHandlerInfo);
- } else {
- objects.pop();
- }
- } else if (oldHandlerInfo && oldHandlerInfo.name === name) {
- // Reuse the matching oldHandlerInfo
- return oldHandlerInfo;
- } else {
- if (this.preTransitionState) {
- var preTransitionHandlerInfo = this.preTransitionState.handlerInfos[i];
- objectToUse = preTransitionHandlerInfo && preTransitionHandlerInfo.context;
- } else {
- // Ideally we should throw this error to provide maximal
- // information to the user that not enough context objects
- // were provided, but this proves too cumbersome in Ember
- // in cases where inner template helpers are evaluated
- // before parent helpers un-render, in which cases this
- // error somewhat prematurely fires.
- //throw new Error("Not enough context objects were provided to complete a transition to " + targetRouteName + ". Specifically, the " + name + " route needs an object that can be serialized into its dynamic URL segments [" + names.join(', ') + "]");
- return oldHandlerInfo;
- }
- }
-
- return handlerInfoFactory('object', {
- name: name,
- handler: handler,
- context: objectToUse,
- names: names
- });
- },
-
- createParamHandlerInfo: function(name, handler, names, objects, oldHandlerInfo) {
- var params = {};
-
- // Soak up all the provided string/numbers
- var numNames = names.length;
- while (numNames--) {
-
- // Only use old params if the names match with the new handler
- var oldParams = (oldHandlerInfo && name === oldHandlerInfo.name && oldHandlerInfo.params) || {};
-
- var peek = objects[objects.length - 1];
- var paramName = names[numNames];
- if (isParam(peek)) {
- params[paramName] = "" + objects.pop();
- } else {
- // If we're here, this means only some of the params
- // were string/number params, so try and use a param
- // value from a previous handler.
- if (oldParams.hasOwnProperty(paramName)) {
- params[paramName] = oldParams[paramName];
- } else {
- throw new Error("You didn't provide enough string/numeric parameters to satisfy all of the dynamic segments for route " + name);
- }
- }
- }
-
- return handlerInfoFactory('param', {
- name: name,
- handler: handler,
- params: params
- });
- }
- });
- });
-define("router/transition-intent/url-transition-intent",
- ["../transition-intent","../transition-state","../handler-info/factory","../utils","exports"],
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
- "use strict";
- var TransitionIntent = __dependency1__["default"];
- var TransitionState = __dependency2__["default"];
- var handlerInfoFactory = __dependency3__["default"];
- var oCreate = __dependency4__.oCreate;
- var merge = __dependency4__.merge;
- var subclass = __dependency4__.subclass;
-
- __exports__["default"] = subclass(TransitionIntent, {
- url: null,
-
- initialize: function(props) {
- this.url = props.url;
- },
-
- applyToState: function(oldState, recognizer, getHandler) {
- var newState = new TransitionState();
-
- var results = recognizer.recognize(this.url),
- queryParams = {},
- i, len;
-
- if (!results) {
- throw new UnrecognizedURLError(this.url);
- }
-
- var statesDiffer = false;
-
- for (i = 0, len = results.length; i < len; ++i) {
- var result = results[i];
- var name = result.handler;
- var handler = getHandler(name);
-
- if (handler.inaccessibleByURL) {
- throw new UnrecognizedURLError(this.url);
- }
-
- var newHandlerInfo = handlerInfoFactory('param', {
- name: name,
- handler: handler,
- params: result.params
- });
-
- var oldHandlerInfo = oldState.handlerInfos[i];
- if (statesDiffer || newHandlerInfo.shouldSupercede(oldHandlerInfo)) {
- statesDiffer = true;
- newState.handlerInfos[i] = newHandlerInfo;
- } else {
- newState.handlerInfos[i] = oldHandlerInfo;
- }
- }
-
- merge(newState.queryParams, results.queryParams);
-
- return newState;
- }
- });
-
- /**
- Promise reject reasons passed to promise rejection
- handlers for failed transitions.
- */
- function UnrecognizedURLError(message) {
- this.message = (message || "UnrecognizedURLError");
- this.name = "UnrecognizedURLError";
- }
- });
-define("router/transition-state",
- ["./handler-info","./utils","rsvp/promise","exports"],
- function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
- "use strict";
- var ResolvedHandlerInfo = __dependency1__.ResolvedHandlerInfo;
- var forEach = __dependency2__.forEach;
- var promiseLabel = __dependency2__.promiseLabel;
- var callHook = __dependency2__.callHook;
- var Promise = __dependency3__["default"];
-
- function TransitionState(other) {
- this.handlerInfos = [];
- this.queryParams = {};
- this.params = {};
- }
-
- TransitionState.prototype = {
- handlerInfos: null,
- queryParams: null,
- params: null,
-
- promiseLabel: function(label) {
- var targetName = '';
- forEach(this.handlerInfos, function(handlerInfo) {
- if (targetName !== '') {
- targetName += '.';
- }
- targetName += handlerInfo.name;
- });
- return promiseLabel("'" + targetName + "': " + label);
- },
-
- resolve: function(shouldContinue, payload) {
- var self = this;
- // First, calculate params for this state. This is useful
- // information to provide to the various route hooks.
- var params = this.params;
- forEach(this.handlerInfos, function(handlerInfo) {
- params[handlerInfo.name] = handlerInfo.params || {};
- });
-
- payload = payload || {};
- payload.resolveIndex = 0;
-
- var currentState = this;
- var wasAborted = false;
-
- // The prelude RSVP.resolve() asyncs us into the promise land.
- return Promise.resolve(null, this.promiseLabel("Start transition"))
- .then(resolveOneHandlerInfo, null, this.promiseLabel('Resolve handler'))['catch'](handleError, this.promiseLabel('Handle error'));
-
- function innerShouldContinue() {
- return Promise.resolve(shouldContinue(), currentState.promiseLabel("Check if should continue"))['catch'](function(reason) {
- // We distinguish between errors that occurred
- // during resolution (e.g. beforeModel/model/afterModel),
- // and aborts due to a rejecting promise from shouldContinue().
- wasAborted = true;
- return Promise.reject(reason);
- }, currentState.promiseLabel("Handle abort"));
- }
-
- function handleError(error) {
- // This is the only possible
- // reject value of TransitionState#resolve
- var handlerInfos = currentState.handlerInfos;
- var errorHandlerIndex = payload.resolveIndex >= handlerInfos.length ?
- handlerInfos.length - 1 : payload.resolveIndex;
- return Promise.reject({
- error: error,
- handlerWithError: currentState.handlerInfos[errorHandlerIndex].handler,
- wasAborted: wasAborted,
- state: currentState
- });
- }
-
- function proceed(resolvedHandlerInfo) {
- var wasAlreadyResolved = currentState.handlerInfos[payload.resolveIndex].isResolved;
-
- // Swap the previously unresolved handlerInfo with
- // the resolved handlerInfo
- currentState.handlerInfos[payload.resolveIndex++] = resolvedHandlerInfo;
-
- if (!wasAlreadyResolved) {
- // Call the redirect hook. The reason we call it here
- // vs. afterModel is so that redirects into child
- // routes don't re-run the model hooks for this
- // already-resolved route.
- var handler = resolvedHandlerInfo.handler;
- callHook(handler, 'redirect', resolvedHandlerInfo.context, payload);
- }
-
- // Proceed after ensuring that the redirect hook
- // didn't abort this transition by transitioning elsewhere.
- return innerShouldContinue().then(resolveOneHandlerInfo, null, currentState.promiseLabel('Resolve handler'));
- }
-
- function resolveOneHandlerInfo() {
- if (payload.resolveIndex === currentState.handlerInfos.length) {
- // This is is the only possible
- // fulfill value of TransitionState#resolve
- return {
- error: null,
- state: currentState
- };
- }
-
- var handlerInfo = currentState.handlerInfos[payload.resolveIndex];
-
- return handlerInfo.resolve(innerShouldContinue, payload)
- .then(proceed, null, currentState.promiseLabel('Proceed'));
- }
- }
- };
-
- __exports__["default"] = TransitionState;
- });
-define("router/transition",
- ["rsvp/promise","./handler-info","./utils","exports"],
- function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
- "use strict";
- var Promise = __dependency1__["default"];
- var ResolvedHandlerInfo = __dependency2__.ResolvedHandlerInfo;
- var trigger = __dependency3__.trigger;
- var slice = __dependency3__.slice;
- var log = __dependency3__.log;
- var promiseLabel = __dependency3__.promiseLabel;
-
- /**
- @private
-
- A Transition is a thennable (a promise-like object) that represents
- an attempt to transition to another route. It can be aborted, either
- explicitly via `abort` or by attempting another transition while a
- previous one is still underway. An aborted transition can also
- be `retry()`d later.
- */
- function Transition(router, intent, state, error) {
- var transition = this;
- this.state = state || router.state;
- this.intent = intent;
- this.router = router;
- this.data = this.intent && this.intent.data || {};
- this.resolvedModels = {};
- this.queryParams = {};
-
- if (error) {
- this.promise = Promise.reject(error);
- return;
- }
-
- if (state) {
- this.params = state.params;
- this.queryParams = state.queryParams;
- this.handlerInfos = state.handlerInfos;
-
- var len = state.handlerInfos.length;
- if (len) {
- this.targetName = state.handlerInfos[len-1].name;
- }
-
- for (var i = 0; i < len; ++i) {
- var handlerInfo = state.handlerInfos[i];
-
- // TODO: this all seems hacky
- if (!handlerInfo.isResolved) { break; }
- this.pivotHandler = handlerInfo.handler;
- }
-
- this.sequence = Transition.currentSequence++;
- this.promise = state.resolve(checkForAbort, this)['catch'](function(result) {
- if (result.wasAborted || transition.isAborted) {
- return Promise.reject(logAbort(transition));
- } else {
- transition.trigger('error', result.error, transition, result.handlerWithError);
- transition.abort();
- return Promise.reject(result.error);
- }
- }, promiseLabel('Handle Abort'));
- } else {
- this.promise = Promise.resolve(this.state);
- this.params = {};
- }
-
- function checkForAbort() {
- if (transition.isAborted) {
- return Promise.reject(undefined, promiseLabel("Transition aborted - reject"));
- }
- }
- }
-
- Transition.currentSequence = 0;
-
- Transition.prototype = {
- targetName: null,
- urlMethod: 'update',
- intent: null,
- params: null,
- pivotHandler: null,
- resolveIndex: 0,
- handlerInfos: null,
- resolvedModels: null,
- isActive: true,
- state: null,
- queryParamsOnly: false,
-
- isTransition: true,
-
- isExiting: function(handler) {
- var handlerInfos = this.handlerInfos;
- for (var i = 0, len = handlerInfos.length; i < len; ++i) {
- var handlerInfo = handlerInfos[i];
- if (handlerInfo.name === handler || handlerInfo.handler === handler) {
- return false;
- }
- }
- return true;
- },
-
- /**
- @public
-
- The Transition's internal promise. Calling `.then` on this property
- is that same as calling `.then` on the Transition object itself, but
- this property is exposed for when you want to pass around a
- Transition's promise, but not the Transition object itself, since
- Transition object can be externally `abort`ed, while the promise
- cannot.
- */
- promise: null,
-
- /**
- @public
-
- Custom state can be stored on a Transition's `data` object.
- This can be useful for decorating a Transition within an earlier
- hook and shared with a later hook. Properties set on `data` will
- be copied to new transitions generated by calling `retry` on this
- transition.
- */
- data: null,
-
- /**
- @public
-
- A standard promise hook that resolves if the transition
- succeeds and rejects if it fails/redirects/aborts.
-
- Forwards to the internal `promise` property which you can
- use in situations where you want to pass around a thennable,
- but not the Transition itself.
-
- @param {Function} onFulfilled
- @param {Function} onRejected
- @param {String} label optional string for labeling the promise.
- Useful for tooling.
- @return {Promise}
- */
- then: function(onFulfilled, onRejected, label) {
- return this.promise.then(onFulfilled, onRejected, label);
- },
-
- /**
- @public
-
- Forwards to the internal `promise` property which you can
- use in situations where you want to pass around a thennable,
- but not the Transition itself.
-
- @method catch
- @param {Function} onRejection
- @param {String} label optional string for labeling the promise.
- Useful for tooling.
- @return {Promise}
- */
- "catch": function(onRejection, label) {
- return this.promise["catch"](onRejection, label);
- },
-
- /**
- @public
-
- Forwards to the internal `promise` property which you can
- use in situations where you want to pass around a thennable,
- but not the Transition itself.
-
- @method finally
- @param {Function} callback
- @param {String} label optional string for labeling the promise.
- Useful for tooling.
- @return {Promise}
- */
- "finally": function(callback, label) {
- return this.promise["finally"](callback, label);
- },
-
- /**
- @public
-
- Aborts the Transition. Note you can also implicitly abort a transition
- by initiating another transition while a previous one is underway.
- */
- abort: function() {
- if (this.isAborted) { return this; }
- log(this.router, this.sequence, this.targetName + ": transition was aborted");
- this.intent.preTransitionState = this.router.state;
- this.isAborted = true;
- this.isActive = false;
- this.router.activeTransition = null;
- return this;
- },
-
- /**
- @public
-
- Retries a previously-aborted transition (making sure to abort the
- transition if it's still active). Returns a new transition that
- represents the new attempt to transition.
- */
- retry: function() {
- // TODO: add tests for merged state retry()s
- this.abort();
- return this.router.transitionByIntent(this.intent, false);
- },
-
- /**
- @public
-
- Sets the URL-changing method to be employed at the end of a
- successful transition. By default, a new Transition will just
- use `updateURL`, but passing 'replace' to this method will
- cause the URL to update using 'replaceWith' instead. Omitting
- a parameter will disable the URL change, allowing for transitions
- that don't update the URL at completion (this is also used for
- handleURL, since the URL has already changed before the
- transition took place).
-
- @param {String} method the type of URL-changing method to use
- at the end of a transition. Accepted values are 'replace',
- falsy values, or any other non-falsy value (which is
- interpreted as an updateURL transition).
-
- @return {Transition} this transition
- */
- method: function(method) {
- this.urlMethod = method;
- return this;
- },
-
- /**
- @public
-
- Fires an event on the current list of resolved/resolving
- handlers within this transition. Useful for firing events
- on route hierarchies that haven't fully been entered yet.
-
- Note: This method is also aliased as `send`
-
- @param {Boolean} [ignoreFailure=false] a boolean specifying whether unhandled events throw an error
- @param {String} name the name of the event to fire
- */
- trigger: function (ignoreFailure) {
- var args = slice.call(arguments);
- if (typeof ignoreFailure === 'boolean') {
- args.shift();
- } else {
- // Throw errors on unhandled trigger events by default
- ignoreFailure = false;
- }
- trigger(this.router, this.state.handlerInfos.slice(0, this.resolveIndex + 1), ignoreFailure, args);
- },
-
- /**
- @public
-
- Transitions are aborted and their promises rejected
- when redirects occur; this method returns a promise
- that will follow any redirects that occur and fulfill
- with the value fulfilled by any redirecting transitions
- that occur.
-
- @return {Promise} a promise that fulfills with the same
- value that the final redirecting transition fulfills with
- */
- followRedirects: function() {
- var router = this.router;
- return this.promise['catch'](function(reason) {
- if (router.activeTransition) {
- return router.activeTransition.followRedirects();
- }
- return Promise.reject(reason);
- });
- },
-
- toString: function() {
- return "Transition (sequence " + this.sequence + ")";
- },
-
- /**
- @private
- */
- log: function(message) {
- log(this.router, this.sequence, message);
- }
- };
-
- // Alias 'trigger' as 'send'
- Transition.prototype.send = Transition.prototype.trigger;
-
- /**
- @private
-
- Logs and returns a TransitionAborted error.
- */
- function logAbort(transition) {
- log(transition.router, transition.sequence, "detected abort.");
- return new TransitionAborted();
- }
-
- function TransitionAborted(message) {
- this.message = (message || "TransitionAborted");
- this.name = "TransitionAborted";
- }
-
- __exports__.Transition = Transition;
- __exports__.logAbort = logAbort;
- __exports__.TransitionAborted = TransitionAborted;
- });
-define("router/utils",
- ["exports"],
- function(__exports__) {
- "use strict";
- var slice = Array.prototype.slice;
-
- var _isArray;
- if (!Array.isArray) {
- _isArray = function (x) {
- return Object.prototype.toString.call(x) === "[object Array]";
- };
- } else {
- _isArray = Array.isArray;
- }
-
- var isArray = _isArray;
- __exports__.isArray = isArray;
- function merge(hash, other) {
- for (var prop in other) {
- if (other.hasOwnProperty(prop)) { hash[prop] = other[prop]; }
- }
- }
-
- var oCreate = Object.create || function(proto) {
- function F() {}
- F.prototype = proto;
- return new F();
- };
- __exports__.oCreate = oCreate;
- /**
- @private
-
- Extracts query params from the end of an array
- **/
- function extractQueryParams(array) {
- var len = (array && array.length), head, queryParams;
-
- if(len && len > 0 && array[len - 1] && array[len - 1].hasOwnProperty('queryParams')) {
- queryParams = array[len - 1].queryParams;
- head = slice.call(array, 0, len - 1);
- return [head, queryParams];
- } else {
- return [array, null];
- }
- }
-
- __exports__.extractQueryParams = extractQueryParams;/**
- @private
-
- Coerces query param properties and array elements into strings.
- **/
- function coerceQueryParamsToString(queryParams) {
- for (var key in queryParams) {
- if (typeof queryParams[key] === 'number') {
- queryParams[key] = '' + queryParams[key];
- } else if (isArray(queryParams[key])) {
- for (var i = 0, l = queryParams[key].length; i < l; i++) {
- queryParams[key][i] = '' + queryParams[key][i];
- }
- }
- }
- }
- /**
- @private
- */
- function log(router, sequence, msg) {
- if (!router.log) { return; }
-
- if (arguments.length === 3) {
- router.log("Transition #" + sequence + ": " + msg);
- } else {
- msg = sequence;
- router.log(msg);
- }
- }
-
- __exports__.log = log;function bind(context, fn) {
- var boundArgs = arguments;
- return function(value) {
- var args = slice.call(boundArgs, 2);
- args.push(value);
- return fn.apply(context, args);
- };
- }
-
- __exports__.bind = bind;function isParam(object) {
- return (typeof object === "string" || object instanceof String || typeof object === "number" || object instanceof Number);
- }
-
-
- function forEach(array, callback) {
- for (var i=0, l=array.length; i=0; i--) {
- var handlerInfo = handlerInfos[i],
- handler = handlerInfo.handler;
-
- if (handler.events && handler.events[name]) {
- if (handler.events[name].apply(handler, args) === true) {
- eventWasHandled = true;
- } else {
- return;
- }
- }
- }
-
- if (!eventWasHandled && !ignoreFailure) {
- throw new Error("Nothing handled the event '" + name + "'.");
- }
- }
-
- __exports__.trigger = trigger;function getChangelist(oldObject, newObject) {
- var key;
- var results = {
- all: {},
- changed: {},
- removed: {}
- };
-
- merge(results.all, newObject);
-
- var didChange = false;
- coerceQueryParamsToString(oldObject);
- coerceQueryParamsToString(newObject);
-
- // Calculate removals
- for (key in oldObject) {
- if (oldObject.hasOwnProperty(key)) {
- if (!newObject.hasOwnProperty(key)) {
- didChange = true;
- results.removed[key] = oldObject[key];
- }
- }
- }
-
- // Calculate changes
- for (key in newObject) {
- if (newObject.hasOwnProperty(key)) {
- if (isArray(oldObject[key]) && isArray(newObject[key])) {
- if (oldObject[key].length !== newObject[key].length) {
- results.changed[key] = newObject[key];
- didChange = true;
- } else {
- for (var i = 0, l = oldObject[key].length; i < l; i++) {
- if (oldObject[key][i] !== newObject[key][i]) {
- results.changed[key] = newObject[key];
- didChange = true;
- }
- }
- }
- }
- else {
- if (oldObject[key] !== newObject[key]) {
- results.changed[key] = newObject[key];
- didChange = true;
- }
- }
- }
- }
-
- return didChange && results;
- }
-
- __exports__.getChangelist = getChangelist;function promiseLabel(label) {
- return 'Router: ' + label;
- }
-
- __exports__.promiseLabel = promiseLabel;function subclass(parentConstructor, proto) {
- function C(props) {
- parentConstructor.call(this, props || {});
- }
- C.prototype = oCreate(parentConstructor.prototype);
- merge(C.prototype, proto);
- return C;
- }
-
- __exports__.subclass = subclass;function resolveHook(obj, hookName) {
- if (!obj) { return; }
- var underscored = "_" + hookName;
- return obj[underscored] && underscored ||
- obj[hookName] && hookName;
- }
-
- function callHook(obj, hookName) {
- var args = slice.call(arguments, 2);
- return applyHook(obj, hookName, args);
- }
-
- function applyHook(obj, _hookName, args) {
- var hookName = resolveHook(obj, _hookName);
- if (hookName) {
- return obj[hookName].apply(obj, args);
- }
- }
-
- __exports__.merge = merge;
- __exports__.slice = slice;
- __exports__.isParam = isParam;
- __exports__.coerceQueryParamsToString = coerceQueryParamsToString;
- __exports__.callHook = callHook;
- __exports__.resolveHook = resolveHook;
- __exports__.applyHook = applyHook;
- });
-define("router",
- ["./router/router","exports"],
- function(__dependency1__, __exports__) {
- "use strict";
- var Router = __dependency1__["default"];
-
- __exports__["default"] = Router;
- });
-
-define("rsvp",
- ["./rsvp/promise","./rsvp/events","./rsvp/node","./rsvp/all","./rsvp/all-settled","./rsvp/race","./rsvp/hash","./rsvp/hash-settled","./rsvp/rethrow","./rsvp/defer","./rsvp/config","./rsvp/map","./rsvp/resolve","./rsvp/reject","./rsvp/filter","./rsvp/asap","exports"],
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __exports__) {
- "use strict";
- var Promise = __dependency1__["default"];
- var EventTarget = __dependency2__["default"];
- var denodeify = __dependency3__["default"];
- var all = __dependency4__["default"];
- var allSettled = __dependency5__["default"];
- var race = __dependency6__["default"];
- var hash = __dependency7__["default"];
- var hashSettled = __dependency8__["default"];
- var rethrow = __dependency9__["default"];
- var defer = __dependency10__["default"];
- var config = __dependency11__.config;
- var configure = __dependency11__.configure;
- var map = __dependency12__["default"];
- var resolve = __dependency13__["default"];
- var reject = __dependency14__["default"];
- var filter = __dependency15__["default"];
- var asap = __dependency16__["default"];
-
- config.async = asap; // default async is asap;
- var cast = resolve;
- function async(callback, arg) {
- config.async(callback, arg);
- }
-
- function on() {
- config.on.apply(config, arguments);
- }
-
- function off() {
- config.off.apply(config, arguments);
- }
-
- // Set up instrumentation through `window.__PROMISE_INTRUMENTATION__`
- if (typeof window !== 'undefined' && typeof window['__PROMISE_INSTRUMENTATION__'] === 'object') {
- var callbacks = window['__PROMISE_INSTRUMENTATION__'];
- configure('instrument', true);
- for (var eventName in callbacks) {
- if (callbacks.hasOwnProperty(eventName)) {
- on(eventName, callbacks[eventName]);
- }
- }
- }
-
- __exports__.cast = cast;
- __exports__.Promise = Promise;
- __exports__.EventTarget = EventTarget;
- __exports__.all = all;
- __exports__.allSettled = allSettled;
- __exports__.race = race;
- __exports__.hash = hash;
- __exports__.hashSettled = hashSettled;
- __exports__.rethrow = rethrow;
- __exports__.defer = defer;
- __exports__.denodeify = denodeify;
- __exports__.configure = configure;
- __exports__.on = on;
- __exports__.off = off;
- __exports__.resolve = resolve;
- __exports__.reject = reject;
- __exports__.async = async;
- __exports__.map = map;
- __exports__.filter = filter;
- });
-define("rsvp.umd",
- ["./rsvp"],
- function(__dependency1__) {
- "use strict";
- var Promise = __dependency1__.Promise;
- var allSettled = __dependency1__.allSettled;
- var hash = __dependency1__.hash;
- var hashSettled = __dependency1__.hashSettled;
- var denodeify = __dependency1__.denodeify;
- var on = __dependency1__.on;
- var off = __dependency1__.off;
- var map = __dependency1__.map;
- var filter = __dependency1__.filter;
- var resolve = __dependency1__.resolve;
- var reject = __dependency1__.reject;
- var rethrow = __dependency1__.rethrow;
- var all = __dependency1__.all;
- var defer = __dependency1__.defer;
- var EventTarget = __dependency1__.EventTarget;
- var configure = __dependency1__.configure;
- var race = __dependency1__.race;
- var async = __dependency1__.async;
-
- var RSVP = {
- 'race': race,
- 'Promise': Promise,
- 'allSettled': allSettled,
- 'hash': hash,
- 'hashSettled': hashSettled,
- 'denodeify': denodeify,
- 'on': on,
- 'off': off,
- 'map': map,
- 'filter': filter,
- 'resolve': resolve,
- 'reject': reject,
- 'all': all,
- 'rethrow': rethrow,
- 'defer': defer,
- 'EventTarget': EventTarget,
- 'configure': configure,
- 'async': async
- };
-
- /* global define:true module:true window: true */
- if (typeof define === 'function' && define.amd) {
- define(function() { return RSVP; });
- } else if (typeof module !== 'undefined' && module.exports) {
- module.exports = RSVP;
- } else if (typeof this !== 'undefined') {
- this['RSVP'] = RSVP;
- }
- });
-define("rsvp/-internal",
- ["./utils","./instrument","./config","exports"],
- function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
- "use strict";
- var objectOrFunction = __dependency1__.objectOrFunction;
- var isFunction = __dependency1__.isFunction;
-
- var instrument = __dependency2__["default"];
-
- var config = __dependency3__.config;
-
- function noop() {}
-
- var PENDING = void 0;
- var FULFILLED = 1;
- var REJECTED = 2;
-
- var GET_THEN_ERROR = new ErrorObject();
-
- function getThen(promise) {
- try {
- return promise.then;
- } catch(error) {
- GET_THEN_ERROR.error = error;
- return GET_THEN_ERROR;
- }
- }
-
- function tryThen(then, value, fulfillmentHandler, rejectionHandler) {
- try {
- then.call(value, fulfillmentHandler, rejectionHandler);
- } catch(e) {
- return e;
- }
- }
-
- function handleForeignThenable(promise, thenable, then) {
- config.async(function(promise) {
- var sealed = false;
- var error = tryThen(then, thenable, function(value) {
- if (sealed) { return; }
- sealed = true;
- if (thenable !== value) {
- resolve(promise, value);
- } else {
- fulfill(promise, value);
- }
- }, function(reason) {
- if (sealed) { return; }
- sealed = true;
-
- reject(promise, reason);
- }, 'Settle: ' + (promise._label || ' unknown promise'));
-
- if (!sealed && error) {
- sealed = true;
- reject(promise, error);
- }
- }, promise);
- }
-
- function handleOwnThenable(promise, thenable) {
- if (thenable._state === FULFILLED) {
- fulfill(promise, thenable._result);
- } else if (promise._state === REJECTED) {
- reject(promise, thenable._result);
- } else {
- subscribe(thenable, undefined, function(value) {
- if (thenable !== value) {
- resolve(promise, value);
- } else {
- fulfill(promise, value);
- }
- }, function(reason) {
- reject(promise, reason);
- });
- }
- }
-
- function handleMaybeThenable(promise, maybeThenable) {
- if (maybeThenable.constructor === promise.constructor) {
- handleOwnThenable(promise, maybeThenable);
- } else {
- var then = getThen(maybeThenable);
-
- if (then === GET_THEN_ERROR) {
- reject(promise, GET_THEN_ERROR.error);
- } else if (then === undefined) {
- fulfill(promise, maybeThenable);
- } else if (isFunction(then)) {
- handleForeignThenable(promise, maybeThenable, then);
- } else {
- fulfill(promise, maybeThenable);
- }
- }
- }
-
- function resolve(promise, value) {
- if (promise === value) {
- fulfill(promise, value);
- } else if (objectOrFunction(value)) {
- handleMaybeThenable(promise, value);
- } else {
- fulfill(promise, value);
- }
- }
-
- function publishRejection(promise) {
- if (promise._onerror) {
- promise._onerror(promise._result);
- }
-
- publish(promise);
- }
-
- function fulfill(promise, value) {
- if (promise._state !== PENDING) { return; }
-
- promise._result = value;
- promise._state = FULFILLED;
-
- if (promise._subscribers.length === 0) {
- if (config.instrument) {
- instrument('fulfilled', promise);
- }
- } else {
- config.async(publish, promise);
- }
- }
-
- function reject(promise, reason) {
- if (promise._state !== PENDING) { return; }
- promise._state = REJECTED;
- promise._result = reason;
-
- config.async(publishRejection, promise);
- }
-
- function subscribe(parent, child, onFulfillment, onRejection) {
- var subscribers = parent._subscribers;
- var length = subscribers.length;
-
- parent._onerror = null;
-
- subscribers[length] = child;
- subscribers[length + FULFILLED] = onFulfillment;
- subscribers[length + REJECTED] = onRejection;
-
- if (length === 0 && parent._state) {
- config.async(publish, parent);
- }
- }
-
- function publish(promise) {
- var subscribers = promise._subscribers;
- var settled = promise._state;
-
- if (config.instrument) {
- instrument(settled === FULFILLED ? 'fulfilled' : 'rejected', promise);
- }
-
- if (subscribers.length === 0) { return; }
-
- var child, callback, detail = promise._result;
-
- for (var i = 0; i < subscribers.length; i += 3) {
- child = subscribers[i];
- callback = subscribers[i + settled];
-
- if (child) {
- invokeCallback(settled, child, callback, detail);
- } else {
- callback(detail);
- }
- }
-
- promise._subscribers.length = 0;
- }
-
- function ErrorObject() {
- this.error = null;
- }
-
- var TRY_CATCH_ERROR = new ErrorObject();
-
- function tryCatch(callback, detail) {
- try {
- return callback(detail);
- } catch(e) {
- TRY_CATCH_ERROR.error = e;
- return TRY_CATCH_ERROR;
- }
- }
-
- function invokeCallback(settled, promise, callback, detail) {
- var hasCallback = isFunction(callback),
- value, error, succeeded, failed;
-
- if (hasCallback) {
- value = tryCatch(callback, detail);
-
- if (value === TRY_CATCH_ERROR) {
- failed = true;
- error = value.error;
- value = null;
- } else {
- succeeded = true;
- }
-
- if (promise === value) {
- reject(promise, new TypeError('A promises callback cannot return that same promise.'));
- return;
- }
-
- } else {
- value = detail;
- succeeded = true;
- }
-
- if (promise._state !== PENDING) {
- // noop
- } else if (hasCallback && succeeded) {
- resolve(promise, value);
- } else if (failed) {
- reject(promise, error);
- } else if (settled === FULFILLED) {
- fulfill(promise, value);
- } else if (settled === REJECTED) {
- reject(promise, value);
- }
- }
-
- function initializePromise(promise, resolver) {
- try {
- resolver(function resolvePromise(value){
- resolve(promise, value);
- }, function rejectPromise(reason) {
- reject(promise, reason);
- });
- } catch(e) {
- reject(promise, e);
- }
- }
-
- __exports__.noop = noop;
- __exports__.resolve = resolve;
- __exports__.reject = reject;
- __exports__.fulfill = fulfill;
- __exports__.subscribe = subscribe;
- __exports__.publish = publish;
- __exports__.publishRejection = publishRejection;
- __exports__.initializePromise = initializePromise;
- __exports__.invokeCallback = invokeCallback;
- __exports__.FULFILLED = FULFILLED;
- __exports__.REJECTED = REJECTED;
- __exports__.PENDING = PENDING;
- });
-define("rsvp/all-settled",
- ["./enumerator","./promise","./utils","exports"],
- function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
- "use strict";
- var Enumerator = __dependency1__["default"];
- var makeSettledResult = __dependency1__.makeSettledResult;
- var Promise = __dependency2__["default"];
- var o_create = __dependency3__.o_create;
-
- function AllSettled(Constructor, entries, label) {
- this._superConstructor(Constructor, entries, false /* don't abort on reject */, label);
- }
-
- AllSettled.prototype = o_create(Enumerator.prototype);
- AllSettled.prototype._superConstructor = Enumerator;
- AllSettled.prototype._makeResult = makeSettledResult;
- AllSettled.prototype._validationError = function() {
- return new Error('allSettled must be called with an array');
- };
-
- /**
- `RSVP.allSettled` is similar to `RSVP.all`, but instead of implementing
- a fail-fast method, it waits until all the promises have returned and
- shows you all the results. This is useful if you want to handle multiple
- promises' failure states together as a set.
-
- Returns a promise that is fulfilled when all the given promises have been
- settled. The return promise is fulfilled with an array of the states of
- the promises passed into the `promises` array argument.
-
- Each state object will either indicate fulfillment or rejection, and
- provide the corresponding value or reason. The states will take one of
- the following formats:
-
- ```javascript
- { state: 'fulfilled', value: value }
- or
- { state: 'rejected', reason: reason }
- ```
-
- Example:
-
- ```javascript
- var promise1 = RSVP.Promise.resolve(1);
- var promise2 = RSVP.Promise.reject(new Error('2'));
- var promise3 = RSVP.Promise.reject(new Error('3'));
- var promises = [ promise1, promise2, promise3 ];
-
- RSVP.allSettled(promises).then(function(array){
- // array == [
- // { state: 'fulfilled', value: 1 },
- // { state: 'rejected', reason: Error },
- // { state: 'rejected', reason: Error }
- // ]
- // Note that for the second item, reason.message will be '2', and for the
- // third item, reason.message will be '3'.
- }, function(error) {
- // Not run. (This block would only be called if allSettled had failed,
- // for instance if passed an incorrect argument type.)
- });
- ```
-
- @method allSettled
- @static
- @for RSVP
- @param {Array} promises
- @param {String} label - optional string that describes the promise.
- Useful for tooling.
- @return {Promise} promise that is fulfilled with an array of the settled
- states of the constituent promises.
- */
-
- __exports__["default"] = function allSettled(entries, label) {
- return new AllSettled(Promise, entries, label).promise;
- }
- });
-define("rsvp/all",
- ["./promise","exports"],
- function(__dependency1__, __exports__) {
- "use strict";
- var Promise = __dependency1__["default"];
-
- /**
- This is a convenient alias for `RSVP.Promise.all`.
-
- @method all
- @static
- @for RSVP
- @param {Array} array Array of promises.
- @param {String} label An optional label. This is useful
- for tooling.
- */
- __exports__["default"] = function all(array, label) {
- return Promise.all(array, label);
- }
- });
-define("rsvp/asap",
- ["exports"],
- function(__exports__) {
- "use strict";
- var len = 0;
-
- __exports__["default"] = function asap(callback, arg) {
- queue[len] = callback;
- queue[len + 1] = arg;
- len += 2;
- if (len === 2) {
- // If len is 1, that means that we need to schedule an async flush.
- // If additional callbacks are queued before the queue is flushed, they
- // will be processed by this flush that we are scheduling.
- scheduleFlush();
- }
- }
-
- var browserGlobal = (typeof window !== 'undefined') ? window : {};
- var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
-
- // test for web worker but not in IE10
- var isWorker = typeof Uint8ClampedArray !== 'undefined' &&
- typeof importScripts !== 'undefined' &&
- typeof MessageChannel !== 'undefined';
-
- // node
- function useNextTick() {
- return function() {
- process.nextTick(flush);
- };
- }
-
- function useMutationObserver() {
- var iterations = 0;
- var observer = new BrowserMutationObserver(flush);
- var node = document.createTextNode('');
- observer.observe(node, { characterData: true });
-
- return function() {
- node.data = (iterations = ++iterations % 2);
- };
- }
-
- // web worker
- function useMessageChannel() {
- var channel = new MessageChannel();
- channel.port1.onmessage = flush;
- return function () {
- channel.port2.postMessage(0);
- };
- }
-
- function useSetTimeout() {
- return function() {
- setTimeout(flush, 1);
- };
- }
-
- var queue = new Array(1000);
- function flush() {
- for (var i = 0; i < len; i+=2) {
- var callback = queue[i];
- var arg = queue[i+1];
-
- callback(arg);
-
- queue[i] = undefined;
- queue[i+1] = undefined;
- }
-
- len = 0;
- }
-
- var scheduleFlush;
-
- // Decide what async method to use to triggering processing of queued callbacks:
- if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
- scheduleFlush = useNextTick();
- } else if (BrowserMutationObserver) {
- scheduleFlush = useMutationObserver();
- } else if (isWorker) {
- scheduleFlush = useMessageChannel();
- } else {
- scheduleFlush = useSetTimeout();
- }
- });
-define("rsvp/config",
- ["./events","exports"],
- function(__dependency1__, __exports__) {
- "use strict";
- var EventTarget = __dependency1__["default"];
-
- var config = {
- instrument: false
- };
-
- EventTarget.mixin(config);
-
- function configure(name, value) {
- if (name === 'onerror') {
- // handle for legacy users that expect the actual
- // error to be passed to their function added via
- // `RSVP.configure('onerror', someFunctionHere);`
- config.on('error', value);
- return;
- }
-
- if (arguments.length === 2) {
- config[name] = value;
- } else {
- return config[name];
- }
- }
-
- __exports__.config = config;
- __exports__.configure = configure;
- });
-define("rsvp/defer",
- ["./promise","exports"],
- function(__dependency1__, __exports__) {
- "use strict";
- var Promise = __dependency1__["default"];
-
- /**
- `RSVP.defer` returns an object similar to jQuery's `$.Deferred`.
- `RSVP.defer` should be used when porting over code reliant on `$.Deferred`'s
- interface. New code should use the `RSVP.Promise` constructor instead.
-
- The object returned from `RSVP.defer` is a plain object with three properties:
-
- * promise - an `RSVP.Promise`.
- * reject - a function that causes the `promise` property on this object to
- become rejected
- * resolve - a function that causes the `promise` property on this object to
- become fulfilled.
-
- Example:
-
- ```javascript
- var deferred = RSVP.defer();
-
- deferred.resolve("Success!");
-
- defered.promise.then(function(value){
- // value here is "Success!"
- });
- ```
-
- @method defer
- @static
- @for RSVP
- @param {String} label optional string for labeling the promise.
- Useful for tooling.
- @return {Object}
- */
-
- __exports__["default"] = function defer(label) {
- var deferred = { };
-
- deferred.promise = new Promise(function(resolve, reject) {
- deferred.resolve = resolve;
- deferred.reject = reject;
- }, label);
-
- return deferred;
- }
- });
-define("rsvp/enumerator",
- ["./utils","./-internal","exports"],
- function(__dependency1__, __dependency2__, __exports__) {
- "use strict";
- var isArray = __dependency1__.isArray;
- var isMaybeThenable = __dependency1__.isMaybeThenable;
-
- var noop = __dependency2__.noop;
- var reject = __dependency2__.reject;
- var fulfill = __dependency2__.fulfill;
- var subscribe = __dependency2__.subscribe;
- var FULFILLED = __dependency2__.FULFILLED;
- var REJECTED = __dependency2__.REJECTED;
- var PENDING = __dependency2__.PENDING;
-
- function makeSettledResult(state, position, value) {
- if (state === FULFILLED) {
- return {
- state: 'fulfilled',
- value: value
- };
- } else {
- return {
- state: 'rejected',
- reason: value
- };
- }
- }
-
- __exports__.makeSettledResult = makeSettledResult;function Enumerator(Constructor, input, abortOnReject, label) {
- this._instanceConstructor = Constructor;
- this.promise = new Constructor(noop, label);
- this._abortOnReject = abortOnReject;
-
- if (this._validateInput(input)) {
- this._input = input;
- this.length = input.length;
- this._remaining = input.length;
-
- this._init();
-
- if (this.length === 0) {
- fulfill(this.promise, this._result);
- } else {
- this.length = this.length || 0;
- this._enumerate();
- if (this._remaining === 0) {
- fulfill(this.promise, this._result);
- }
- }
- } else {
- reject(this.promise, this._validationError());
- }
- }
-
- Enumerator.prototype._validateInput = function(input) {
- return isArray(input);
- };
-
- Enumerator.prototype._validationError = function() {
- return new Error('Array Methods must be provided an Array');
- };
-
- Enumerator.prototype._init = function() {
- this._result = new Array(this.length);
- };
-
- __exports__["default"] = Enumerator;
-
- Enumerator.prototype._enumerate = function() {
- var length = this.length;
- var promise = this.promise;
- var input = this._input;
-
- for (var i = 0; promise._state === PENDING && i < length; i++) {
- this._eachEntry(input[i], i);
- }
- };
-
- Enumerator.prototype._eachEntry = function(entry, i) {
- var c = this._instanceConstructor;
- if (isMaybeThenable(entry)) {
- if (entry.constructor === c && entry._state !== PENDING) {
- entry._onerror = null;
- this._settledAt(entry._state, i, entry._result);
- } else {
- this._willSettleAt(c.resolve(entry), i);
- }
- } else {
- this._remaining--;
- this._result[i] = this._makeResult(FULFILLED, i, entry);
- }
- };
-
- Enumerator.prototype._settledAt = function(state, i, value) {
- var promise = this.promise;
-
- if (promise._state === PENDING) {
- this._remaining--;
-
- if (this._abortOnReject && state === REJECTED) {
- reject(promise, value);
- } else {
- this._result[i] = this._makeResult(state, i, value);
- }
- }
-
- if (this._remaining === 0) {
- fulfill(promise, this._result);
- }
- };
-
- Enumerator.prototype._makeResult = function(state, i, value) {
- return value;
- };
-
- Enumerator.prototype._willSettleAt = function(promise, i) {
- var enumerator = this;
-
- subscribe(promise, undefined, function(value) {
- enumerator._settledAt(FULFILLED, i, value);
- }, function(reason) {
- enumerator._settledAt(REJECTED, i, reason);
- });
- };
- });
-define("rsvp/events",
- ["exports"],
- function(__exports__) {
- "use strict";
- function indexOf(callbacks, callback) {
- for (var i=0, l=callbacks.length; i 1;
- };
-
- RSVP.filter(promises, filterFn).then(function(result){
- // result is [ 2, 3 ]
- });
- ```
-
- If any of the `promises` given to `RSVP.filter` are rejected, the first promise
- that is rejected will be given as an argument to the returned promise's
- rejection handler. For example:
-
- ```javascript
- var promise1 = RSVP.resolve(1);
- var promise2 = RSVP.reject(new Error('2'));
- var promise3 = RSVP.reject(new Error('3'));
- var promises = [ promise1, promise2, promise3 ];
-
- var filterFn = function(item){
- return item > 1;
- };
-
- RSVP.filter(promises, filterFn).then(function(array){
- // Code here never runs because there are rejected promises!
- }, function(reason) {
- // reason.message === '2'
- });
- ```
-
- `RSVP.filter` will also wait for any promises returned from `filterFn`.
- For instance, you may want to fetch a list of users then return a subset
- of those users based on some asynchronous operation:
-
- ```javascript
-
- var alice = { name: 'alice' };
- var bob = { name: 'bob' };
- var users = [ alice, bob ];
-
- var promises = users.map(function(user){
- return RSVP.resolve(user);
- });
-
- var filterFn = function(user){
- // Here, Alice has permissions to create a blog post, but Bob does not.
- return getPrivilegesForUser(user).then(function(privs){
- return privs.can_create_blog_post === true;
- });
- };
- RSVP.filter(promises, filterFn).then(function(users){
- // true, because the server told us only Alice can create a blog post.
- users.length === 1;
- // false, because Alice is the only user present in `users`
- users[0] === bob;
- });
- ```
-
- @method filter
- @static
- @for RSVP
- @param {Array} promises
- @param {Function} filterFn - function to be called on each resolved value to
- filter the final results.
- @param {String} label optional string describing the promise. Useful for
- tooling.
- @return {Promise}
- */
- __exports__["default"] = function filter(promises, filterFn, label) {
- return Promise.all(promises, label).then(function(values) {
- if (!isFunction(filterFn)) {
- throw new TypeError("You must pass a function as filter's second argument.");
- }
-
- var length = values.length;
- var filtered = new Array(length);
-
- for (var i = 0; i < length; i++) {
- filtered[i] = filterFn(values[i]);
- }
-
- return Promise.all(filtered, label).then(function(filtered) {
- var results = new Array(length);
- var newLength = 0;
-
- for (var i = 0; i < length; i++) {
- if (filtered[i]) {
- results[newLength] = values[i];
- newLength++;
- }
- }
-
- results.length = newLength;
-
- return results;
- });
- });
- }
- });
-define("rsvp/hash-settled",
- ["./promise","./enumerator","./promise-hash","./utils","exports"],
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
- "use strict";
- var Promise = __dependency1__["default"];
- var makeSettledResult = __dependency2__.makeSettledResult;
- var PromiseHash = __dependency3__["default"];
- var Enumerator = __dependency2__["default"];
- var o_create = __dependency4__.o_create;
-
- function HashSettled(Constructor, object, label) {
- this._superConstructor(Constructor, object, false, label);
- }
-
- HashSettled.prototype = o_create(PromiseHash.prototype);
- HashSettled.prototype._superConstructor = Enumerator;
- HashSettled.prototype._makeResult = makeSettledResult;
-
- HashSettled.prototype._validationError = function() {
- return new Error('hashSettled must be called with an object');
- };
-
- /**
- `RSVP.hashSettled` is similar to `RSVP.allSettled`, but takes an object
- instead of an array for its `promises` argument.
-
- Unlike `RSVP.all` or `RSVP.hash`, which implement a fail-fast method,
- but like `RSVP.allSettled`, `hashSettled` waits until all the
- constituent promises have returned and then shows you all the results
- with their states and values/reasons. This is useful if you want to
- handle multiple promises' failure states together as a set.
-
- Returns a promise that is fulfilled when all the given promises have been
- settled, or rejected if the passed parameters are invalid.
-
- The returned promise is fulfilled with a hash that has the same key names as
- the `promises` object argument. If any of the values in the object are not
- promises, they will be copied over to the fulfilled object and marked with state
- 'fulfilled'.
-
- Example:
-
- ```javascript
- var promises = {
- myPromise: RSVP.Promise.resolve(1),
- yourPromise: RSVP.Promise.resolve(2),
- theirPromise: RSVP.Promise.resolve(3),
- notAPromise: 4
- };
-
- RSVP.hashSettled(promises).then(function(hash){
- // hash here is an object that looks like:
- // {
- // myPromise: { state: 'fulfilled', value: 1 },
- // yourPromise: { state: 'fulfilled', value: 2 },
- // theirPromise: { state: 'fulfilled', value: 3 },
- // notAPromise: { state: 'fulfilled', value: 4 }
- // }
- });
- ```
-
- If any of the `promises` given to `RSVP.hash` are rejected, the state will
- be set to 'rejected' and the reason for rejection provided.
-
- Example:
-
- ```javascript
- var promises = {
- myPromise: RSVP.Promise.resolve(1),
- rejectedPromise: RSVP.Promise.reject(new Error('rejection')),
- anotherRejectedPromise: RSVP.Promise.reject(new Error('more rejection')),
- };
-
- RSVP.hashSettled(promises).then(function(hash){
- // hash here is an object that looks like:
- // {
- // myPromise: { state: 'fulfilled', value: 1 },
- // rejectedPromise: { state: 'rejected', reason: Error },
- // anotherRejectedPromise: { state: 'rejected', reason: Error },
- // }
- // Note that for rejectedPromise, reason.message == 'rejection',
- // and for anotherRejectedPromise, reason.message == 'more rejection'.
- });
- ```
-
- An important note: `RSVP.hashSettled` is intended for plain JavaScript objects that
- are just a set of keys and values. `RSVP.hashSettled` will NOT preserve prototype
- chains.
-
- Example:
-
- ```javascript
- function MyConstructor(){
- this.example = RSVP.Promise.resolve('Example');
- }
-
- MyConstructor.prototype = {
- protoProperty: RSVP.Promise.resolve('Proto Property')
- };
-
- var myObject = new MyConstructor();
-
- RSVP.hashSettled(myObject).then(function(hash){
- // protoProperty will not be present, instead you will just have an
- // object that looks like:
- // {
- // example: { state: 'fulfilled', value: 'Example' }
- // }
- //
- // hash.hasOwnProperty('protoProperty'); // false
- // 'undefined' === typeof hash.protoProperty
- });
- ```
-
- @method hashSettled
- @for RSVP
- @param {Object} promises
- @param {String} label optional string that describes the promise.
- Useful for tooling.
- @return {Promise} promise that is fulfilled when when all properties of `promises`
- have been settled.
- @static
- */
- __exports__["default"] = function hashSettled(object, label) {
- return new HashSettled(Promise, object, label).promise;
- }
- });
-define("rsvp/hash",
- ["./promise","./promise-hash","exports"],
- function(__dependency1__, __dependency2__, __exports__) {
- "use strict";
- var Promise = __dependency1__["default"];
- var PromiseHash = __dependency2__["default"];
-
- /**
- `RSVP.hash` is similar to `RSVP.all`, but takes an object instead of an array
- for its `promises` argument.
-
- Returns a promise that is fulfilled when all the given promises have been
- fulfilled, or rejected if any of them become rejected. The returned promise
- is fulfilled with a hash that has the same key names as the `promises` object
- argument. If any of the values in the object are not promises, they will
- simply be copied over to the fulfilled object.
-
- Example:
-
- ```javascript
- var promises = {
- myPromise: RSVP.resolve(1),
- yourPromise: RSVP.resolve(2),
- theirPromise: RSVP.resolve(3),
- notAPromise: 4
- };
-
- RSVP.hash(promises).then(function(hash){
- // hash here is an object that looks like:
- // {
- // myPromise: 1,
- // yourPromise: 2,
- // theirPromise: 3,
- // notAPromise: 4
- // }
- });
- ````
-
- If any of the `promises` given to `RSVP.hash` are rejected, the first promise
- that is rejected will be given as the reason to the rejection handler.
-
- Example:
-
- ```javascript
- var promises = {
- myPromise: RSVP.resolve(1),
- rejectedPromise: RSVP.reject(new Error('rejectedPromise')),
- anotherRejectedPromise: RSVP.reject(new Error('anotherRejectedPromise')),
- };
-
- RSVP.hash(promises).then(function(hash){
- // Code here never runs because there are rejected promises!
- }, function(reason) {
- // reason.message === 'rejectedPromise'
- });
- ```
-
- An important note: `RSVP.hash` is intended for plain JavaScript objects that
- are just a set of keys and values. `RSVP.hash` will NOT preserve prototype
- chains.
-
- Example:
-
- ```javascript
- function MyConstructor(){
- this.example = RSVP.resolve('Example');
- }
-
- MyConstructor.prototype = {
- protoProperty: RSVP.resolve('Proto Property')
- };
-
- var myObject = new MyConstructor();
-
- RSVP.hash(myObject).then(function(hash){
- // protoProperty will not be present, instead you will just have an
- // object that looks like:
- // {
- // example: 'Example'
- // }
- //
- // hash.hasOwnProperty('protoProperty'); // false
- // 'undefined' === typeof hash.protoProperty
- });
- ```
-
- @method hash
- @static
- @for RSVP
- @param {Object} promises
- @param {String} label optional string that describes the promise.
- Useful for tooling.
- @return {Promise} promise that is fulfilled when all properties of `promises`
- have been fulfilled, or rejected if any of them become rejected.
- */
- __exports__["default"] = function hash(object, label) {
- return new PromiseHash(Promise, object, label).promise;
- }
- });
-define("rsvp/instrument",
- ["./config","./utils","exports"],
- function(__dependency1__, __dependency2__, __exports__) {
- "use strict";
- var config = __dependency1__.config;
- var now = __dependency2__.now;
-
- var queue = [];
-
- __exports__["default"] = function instrument(eventName, promise, child) {
- if (1 === queue.push({
- name: eventName,
- payload: {
- guid: promise._guidKey + promise._id,
- eventName: eventName,
- detail: promise._result,
- childGuid: child && promise._guidKey + child._id,
- label: promise._label,
- timeStamp: now(),
- stack: new Error(promise._label).stack
- }})) {
-
- setTimeout(function() {
- var entry;
- for (var i = 0; i < queue.length; i++) {
- entry = queue[i];
- config.trigger(entry.name, entry.payload);
- }
- queue.length = 0;
- }, 50);
- }
- }
- });
-define("rsvp/map",
- ["./promise","./utils","exports"],
- function(__dependency1__, __dependency2__, __exports__) {
- "use strict";
- var Promise = __dependency1__["default"];
- var isFunction = __dependency2__.isFunction;
-
- /**
- `RSVP.map` is similar to JavaScript's native `map` method, except that it
- waits for all promises to become fulfilled before running the `mapFn` on
- each item in given to `promises`. `RSVP.map` returns a promise that will
- become fulfilled with the result of running `mapFn` on the values the promises
- become fulfilled with.
-
- For example:
-
- ```javascript
-
- var promise1 = RSVP.resolve(1);
- var promise2 = RSVP.resolve(2);
- var promise3 = RSVP.resolve(3);
- var promises = [ promise1, promise2, promise3 ];
-
- var mapFn = function(item){
- return item + 1;
- };
-
- RSVP.map(promises, mapFn).then(function(result){
- // result is [ 2, 3, 4 ]
- });
- ```
-
- If any of the `promises` given to `RSVP.map` are rejected, the first promise
- that is rejected will be given as an argument to the returned promise's
- rejection handler. For example:
-
- ```javascript
- var promise1 = RSVP.resolve(1);
- var promise2 = RSVP.reject(new Error('2'));
- var promise3 = RSVP.reject(new Error('3'));
- var promises = [ promise1, promise2, promise3 ];
-
- var mapFn = function(item){
- return item + 1;
- };
-
- RSVP.map(promises, mapFn).then(function(array){
- // Code here never runs because there are rejected promises!
- }, function(reason) {
- // reason.message === '2'
- });
- ```
-
- `RSVP.map` will also wait if a promise is returned from `mapFn`. For example,
- say you want to get all comments from a set of blog posts, but you need
- the blog posts first because they contain a url to those comments.
-
- ```javscript
-
- var mapFn = function(blogPost){
- // getComments does some ajax and returns an RSVP.Promise that is fulfilled
- // with some comments data
- return getComments(blogPost.comments_url);
- };
-
- // getBlogPosts does some ajax and returns an RSVP.Promise that is fulfilled
- // with some blog post data
- RSVP.map(getBlogPosts(), mapFn).then(function(comments){
- // comments is the result of asking the server for the comments
- // of all blog posts returned from getBlogPosts()
- });
- ```
-
- @method map
- @static
- @for RSVP
- @param {Array} promises
- @param {Function} mapFn function to be called on each fulfilled promise.
- @param {String} label optional string for labeling the promise.
- Useful for tooling.
- @return {Promise} promise that is fulfilled with the result of calling
- `mapFn` on each fulfilled promise or value when they become fulfilled.
- The promise will be rejected if any of the given `promises` become rejected.
- @static
- */
- __exports__["default"] = function map(promises, mapFn, label) {
- return Promise.all(promises, label).then(function(values) {
- if (!isFunction(mapFn)) {
- throw new TypeError("You must pass a function as map's second argument.");
- }
-
- var length = values.length;
- var results = new Array(length);
-
- for (var i = 0; i < length; i++) {
- results[i] = mapFn(values[i]);
- }
-
- return Promise.all(results, label);
- });
- }
- });
-define("rsvp/node",
- ["./promise","./-internal","./utils","exports"],
- function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
- "use strict";
- var Promise = __dependency1__["default"];
- var noop = __dependency2__.noop;
- var resolve = __dependency2__.resolve;
- var reject = __dependency2__.reject;
- var isArray = __dependency3__.isArray;
-
- function Result() {
- this.value = undefined;
- }
-
- var ERROR = new Result();
- var GET_THEN_ERROR = new Result();
-
- function getThen(obj) {
- try {
- return obj.then;
- } catch(error) {
- ERROR.value= error;
- return ERROR;
- }
- }
-
-
- function tryApply(f, s, a) {
- try {
- f.apply(s, a);
- } catch(error) {
- ERROR.value = error;
- return ERROR;
- }
- }
-
- function makeObject(_, argumentNames) {
- var obj = {};
- var name;
- var i;
- var length = _.length;
- var args = new Array(length);
-
- for (var x = 0; x < length; x++) {
- args[x] = _[x];
- }
-
- for (i = 0; i < argumentNames.length; i++) {
- name = argumentNames[i];
- obj[name] = args[i + 1];
- }
-
- return obj;
- }
-
- function arrayResult(_) {
- var length = _.length;
- var args = new Array(length - 1);
-
- for (var i = 1; i < length; i++) {
- args[i - 1] = _[i];
- }
-
- return args;
- }
-
- function wrapThenable(then, promise) {
- return {
- then: function(onFulFillment, onRejection) {
- return then.call(promise, onFulFillment, onRejection);
- }
- };
- }
-
- /**
- `RSVP.denodeify` takes a 'node-style' function and returns a function that
- will return an `RSVP.Promise`. You can use `denodeify` in Node.js or the
- browser when you'd prefer to use promises over using callbacks. For example,
- `denodeify` transforms the following:
-
- ```javascript
- var fs = require('fs');
-
- fs.readFile('myfile.txt', function(err, data){
- if (err) return handleError(err);
- handleData(data);
- });
- ```
-
- into:
-
- ```javascript
- var fs = require('fs');
- var readFile = RSVP.denodeify(fs.readFile);
-
- readFile('myfile.txt').then(handleData, handleError);
- ```
-
- If the node function has multiple success parameters, then `denodeify`
- just returns the first one:
-
- ```javascript
- var request = RSVP.denodeify(require('request'));
-
- request('http://example.com').then(function(res) {
- // ...
- });
- ```
-
- However, if you need all success parameters, setting `denodeify`'s
- second parameter to `true` causes it to return all success parameters
- as an array:
-
- ```javascript
- var request = RSVP.denodeify(require('request'), true);
-
- request('http://example.com').then(function(result) {
- // result[0] -> res
- // result[1] -> body
- });
- ```
-
- Or if you pass it an array with names it returns the parameters as a hash:
-
- ```javascript
- var request = RSVP.denodeify(require('request'), ['res', 'body']);
-
- request('http://example.com').then(function(result) {
- // result.res
- // result.body
- });
- ```
-
- Sometimes you need to retain the `this`:
-
- ```javascript
- var app = require('express')();
- var render = RSVP.denodeify(app.render.bind(app));
- ```
-
- The denodified function inherits from the original function. It works in all
- environments, except IE 10 and below. Consequently all properties of the original
- function are available to you. However, any properties you change on the
- denodeified function won't be changed on the original function. Example:
-
- ```javascript
- var request = RSVP.denodeify(require('request')),
- cookieJar = request.jar(); // <- Inheritance is used here
-
- request('http://example.com', {jar: cookieJar}).then(function(res) {
- // cookieJar.cookies holds now the cookies returned by example.com
- });
- ```
-
- Using `denodeify` makes it easier to compose asynchronous operations instead
- of using callbacks. For example, instead of:
-
- ```javascript
- var fs = require('fs');
-
- fs.readFile('myfile.txt', function(err, data){
- if (err) { ... } // Handle error
- fs.writeFile('myfile2.txt', data, function(err){
- if (err) { ... } // Handle error
- console.log('done')
- });
- });
- ```
-
- you can chain the operations together using `then` from the returned promise:
-
- ```javascript
- var fs = require('fs');
- var readFile = RSVP.denodeify(fs.readFile);
- var writeFile = RSVP.denodeify(fs.writeFile);
-
- readFile('myfile.txt').then(function(data){
- return writeFile('myfile2.txt', data);
- }).then(function(){
- console.log('done')
- }).catch(function(error){
- // Handle error
- });
- ```
-
- @method denodeify
- @static
- @for RSVP
- @param {Function} nodeFunc a 'node-style' function that takes a callback as
- its last argument. The callback expects an error to be passed as its first
- argument (if an error occurred, otherwise null), and the value from the
- operation as its second argument ('function(err, value){ }').
- @param {Boolean|Array} argumentNames An optional paramter that if set
- to `true` causes the promise to fulfill with the callback's success arguments
- as an array. This is useful if the node function has multiple success
- paramters. If you set this paramter to an array with names, the promise will
- fulfill with a hash with these names as keys and the success parameters as
- values.
- @return {Function} a function that wraps `nodeFunc` to return an
- `RSVP.Promise`
- @static
- */
- __exports__["default"] = function denodeify(nodeFunc, options) {
- var fn = function() {
- var self = this;
- var l = arguments.length;
- var args = new Array(l + 1);
- var arg;
- var promiseInput = false;
-
- for (var i = 0; i < l; ++i) {
- arg = arguments[i];
-
- if (!promiseInput) {
- // TODO: clean this up
- promiseInput = needsPromiseInput(arg);
- if (promiseInput === GET_THEN_ERROR) {
- var p = new Promise(noop);
- reject(p, GET_THEN_ERROR.value);
- return p;
- } else if (promiseInput && promiseInput !== true) {
- arg = wrapThenable(promiseInput, arg);
- }
- }
- args[i] = arg;
- }
-
- var promise = new Promise(noop);
-
- args[l] = function(err, val) {
- if (err)
- reject(promise, err);
- else if (options === undefined)
- resolve(promise, val);
- else if (options === true)
- resolve(promise, arrayResult(arguments));
- else if (isArray(options))
- resolve(promise, makeObject(arguments, options));
- else
- resolve(promise, val);
- };
-
- if (promiseInput) {
- return handlePromiseInput(promise, args, nodeFunc, self);
- } else {
- return handleValueInput(promise, args, nodeFunc, self);
- }
- };
-
- fn.__proto__ = nodeFunc;
-
- return fn;
- }
-
- function handleValueInput(promise, args, nodeFunc, self) {
- var result = tryApply(nodeFunc, self, args);
- if (result === ERROR) {
- reject(promise, result.value);
- }
- return promise;
- }
-
- function handlePromiseInput(promise, args, nodeFunc, self){
- return Promise.all(args).then(function(args){
- var result = tryApply(nodeFunc, self, args);
- if (result === ERROR) {
- reject(promise, result.value);
- }
- return promise;
- });
- }
-
- function needsPromiseInput(arg) {
- if (arg && typeof arg === 'object') {
- if (arg.constructor === Promise) {
- return true;
- } else {
- return getThen(arg);
- }
- } else {
- return false;
- }
- }
- });
-define("rsvp/promise-hash",
- ["./enumerator","./-internal","./utils","exports"],
- function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
- "use strict";
- var Enumerator = __dependency1__["default"];
- var PENDING = __dependency2__.PENDING;
- var o_create = __dependency3__.o_create;
-
- function PromiseHash(Constructor, object, label) {
- this._superConstructor(Constructor, object, true, label);
- }
-
- __exports__["default"] = PromiseHash;
-
- PromiseHash.prototype = o_create(Enumerator.prototype);
- PromiseHash.prototype._superConstructor = Enumerator;
- PromiseHash.prototype._init = function() {
- this._result = {};
- };
-
- PromiseHash.prototype._validateInput = function(input) {
- return input && typeof input === 'object';
- };
-
- PromiseHash.prototype._validationError = function() {
- return new Error('Promise.hash must be called with an object');
- };
-
- PromiseHash.prototype._enumerate = function() {
- var promise = this.promise;
- var input = this._input;
- var results = [];
-
- for (var key in input) {
- if (promise._state === PENDING && input.hasOwnProperty(key)) {
- results.push({
- position: key,
- entry: input[key]
- });
- }
- }
-
- var length = results.length;
- this._remaining = length;
- var result;
-
- for (var i = 0; promise._state === PENDING && i < length; i++) {
- result = results[i];
- this._eachEntry(result.entry, result.position);
- }
- };
- });
-define("rsvp/promise",
- ["./config","./instrument","./utils","./-internal","./promise/all","./promise/race","./promise/resolve","./promise/reject","exports"],
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
- "use strict";
- var config = __dependency1__.config;
- var instrument = __dependency2__["default"];
-
- var isFunction = __dependency3__.isFunction;
- var now = __dependency3__.now;
-
- var noop = __dependency4__.noop;
- var subscribe = __dependency4__.subscribe;
- var initializePromise = __dependency4__.initializePromise;
- var invokeCallback = __dependency4__.invokeCallback;
- var FULFILLED = __dependency4__.FULFILLED;
- var REJECTED = __dependency4__.REJECTED;
-
- var all = __dependency5__["default"];
- var race = __dependency6__["default"];
- var Resolve = __dependency7__["default"];
- var Reject = __dependency8__["default"];
-
- var guidKey = 'rsvp_' + now() + '-';
- var counter = 0;
-
- function needsResolver() {
- throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
- }
-
- function needsNew() {
- throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
- }
- __exports__["default"] = Promise;
- /**
- Promise objects represent the eventual result of an asynchronous operation. The
- primary way of interacting with a promise is through its `then` method, which
- registers callbacks to receive either a promise’s eventual value or the reason
- why the promise cannot be fulfilled.
-
- Terminology
- -----------
-
- - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
- - `thenable` is an object or function that defines a `then` method.
- - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
- - `exception` is a value that is thrown using the throw statement.
- - `reason` is a value that indicates why a promise was rejected.
- - `settled` the final resting state of a promise, fulfilled or rejected.
-
- A promise can be in one of three states: pending, fulfilled, or rejected.
-
- Promises that are fulfilled have a fulfillment value and are in the fulfilled
- state. Promises that are rejected have a rejection reason and are in the
- rejected state. A fulfillment value is never a thenable.
-
- Promises can also be said to *resolve* a value. If this value is also a
- promise, then the original promise's settled state will match the value's
- settled state. So a promise that *resolves* a promise that rejects will
- itself reject, and a promise that *resolves* a promise that fulfills will
- itself fulfill.
-
-
- Basic Usage:
- ------------
-
- ```js
- var promise = new Promise(function(resolve, reject) {
- // on success
- resolve(value);
-
- // on failure
- reject(reason);
- });
-
- promise.then(function(value) {
- // on fulfillment
- }, function(reason) {
- // on rejection
- });
- ```
-
- Advanced Usage:
- ---------------
-
- Promises shine when abstracting away asynchronous interactions such as
- `XMLHttpRequest`s.
-
- ```js
- function getJSON(url) {
- return new Promise(function(resolve, reject){
- var xhr = new XMLHttpRequest();
-
- xhr.open('GET', url);
- xhr.onreadystatechange = handler;
- xhr.responseType = 'json';
- xhr.setRequestHeader('Accept', 'application/json');
- xhr.send();
-
- function handler() {
- if (this.readyState === this.DONE) {
- if (this.status === 200) {
- resolve(this.response);
- } else {
- reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
- }
- }
- };
- });
- }
-
- getJSON('/posts.json').then(function(json) {
- // on fulfillment
- }, function(reason) {
- // on rejection
- });
- ```
-
- Unlike callbacks, promises are great composable primitives.
-
- ```js
- Promise.all([
- getJSON('/posts'),
- getJSON('/comments')
- ]).then(function(values){
- values[0] // => postsJSON
- values[1] // => commentsJSON
-
- return values;
- });
- ```
-
- @class RSVP.Promise
- @param {function} resolver
- @param {String} label optional string for labeling the promise.
- Useful for tooling.
- @constructor
- */
- function Promise(resolver, label) {
- this._id = counter++;
- this._label = label;
- this._state = undefined;
- this._result = undefined;
- this._subscribers = [];
-
- if (config.instrument) {
- instrument('created', this);
- }
-
- if (noop !== resolver) {
- if (!isFunction(resolver)) {
- needsResolver();
- }
-
- if (!(this instanceof Promise)) {
- needsNew();
- }
-
- initializePromise(this, resolver);
- }
- }
-
- Promise.cast = Resolve; // deprecated
- Promise.all = all;
- Promise.race = race;
- Promise.resolve = Resolve;
- Promise.reject = Reject;
-
- Promise.prototype = {
- constructor: Promise,
-
- _guidKey: guidKey,
-
- _onerror: function (reason) {
- config.trigger('error', reason);
- },
-
- /**
- The primary way of interacting with a promise is through its `then` method,
- which registers callbacks to receive either a promise's eventual value or the
- reason why the promise cannot be fulfilled.
-
- ```js
- findUser().then(function(user){
- // user is available
- }, function(reason){
- // user is unavailable, and you are given the reason why
- });
- ```
-
- Chaining
- --------
-
- The return value of `then` is itself a promise. This second, 'downstream'
- promise is resolved with the return value of the first promise's fulfillment
- or rejection handler, or rejected if the handler throws an exception.
-
- ```js
- findUser().then(function (user) {
- return user.name;
- }, function (reason) {
- return 'default name';
- }).then(function (userName) {
- // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
- // will be `'default name'`
- });
-
- findUser().then(function (user) {
- throw new Error('Found user, but still unhappy');
- }, function (reason) {
- throw new Error('`findUser` rejected and we're unhappy');
- }).then(function (value) {
- // never reached
- }, function (reason) {
- // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
- // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
- });
- ```
- If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
-
- ```js
- findUser().then(function (user) {
- throw new PedagogicalException('Upstream error');
- }).then(function (value) {
- // never reached
- }).then(function (value) {
- // never reached
- }, function (reason) {
- // The `PedgagocialException` is propagated all the way down to here
- });
- ```
-
- Assimilation
- ------------
-
- Sometimes the value you want to propagate to a downstream promise can only be
- retrieved asynchronously. This can be achieved by returning a promise in the
- fulfillment or rejection handler. The downstream promise will then be pending
- until the returned promise is settled. This is called *assimilation*.
-
- ```js
- findUser().then(function (user) {
- return findCommentsByAuthor(user);
- }).then(function (comments) {
- // The user's comments are now available
- });
- ```
-
- If the assimliated promise rejects, then the downstream promise will also reject.
-
- ```js
- findUser().then(function (user) {
- return findCommentsByAuthor(user);
- }).then(function (comments) {
- // If `findCommentsByAuthor` fulfills, we'll have the value here
- }, function (reason) {
- // If `findCommentsByAuthor` rejects, we'll have the reason here
- });
- ```
-
- Simple Example
- --------------
-
- Synchronous Example
-
- ```javascript
- var result;
-
- try {
- result = findResult();
- // success
- } catch(reason) {
- // failure
- }
- ```
-
- Errback Example
-
- ```js
- findResult(function(result, err){
- if (err) {
- // failure
- } else {
- // success
- }
- });
- ```
-
- Promise Example;
-
- ```javascript
- findResult().then(function(result){
- // success
- }, function(reason){
- // failure
- });
- ```
-
- Advanced Example
- --------------
-
- Synchronous Example
-
- ```javascript
- var author, books;
-
- try {
- author = findAuthor();
- books = findBooksByAuthor(author);
- // success
- } catch(reason) {
- // failure
- }
- ```
-
- Errback Example
-
- ```js
-
- function foundBooks(books) {
-
- }
-
- function failure(reason) {
-
- }
-
- findAuthor(function(author, err){
- if (err) {
- failure(err);
- // failure
- } else {
- try {
- findBoooksByAuthor(author, function(books, err) {
- if (err) {
- failure(err);
- } else {
- try {
- foundBooks(books);
- } catch(reason) {
- failure(reason);
- }
- }
- });
- } catch(error) {
- failure(err);
- }
- // success
- }
- });
- ```
-
- Promise Example;
-
- ```javascript
- findAuthor().
- then(findBooksByAuthor).
- then(function(books){
- // found books
- }).catch(function(reason){
- // something went wrong
- });
- ```
-
- @method then
- @param {Function} onFulfilled
- @param {Function} onRejected
- @param {String} label optional string for labeling the promise.
- Useful for tooling.
- @return {Promise}
- */
- then: function(onFulfillment, onRejection, label) {
- var parent = this;
- var state = parent._state;
-
- if (state === FULFILLED && !onFulfillment || state === REJECTED && !onRejection) {
- if (config.instrument) {
- instrument('chained', this, this);
- }
- return this;
- }
-
- parent._onerror = null;
-
- var child = new this.constructor(noop, label);
- var result = parent._result;
-
- if (config.instrument) {
- instrument('chained', parent, child);
- }
-
- if (state) {
- var callback = arguments[state - 1];
- config.async(function(){
- invokeCallback(state, child, callback, result);
- });
- } else {
- subscribe(parent, child, onFulfillment, onRejection);
- }
-
- return child;
- },
-
- /**
- `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
- as the catch block of a try/catch statement.
-
- ```js
- function findAuthor(){
- throw new Error('couldn't find that author');
- }
-
- // synchronous
- try {
- findAuthor();
- } catch(reason) {
- // something went wrong
- }
-
- // async with promises
- findAuthor().catch(function(reason){
- // something went wrong
- });
- ```
-
- @method catch
- @param {Function} onRejection
- @param {String} label optional string for labeling the promise.
- Useful for tooling.
- @return {Promise}
- */
- 'catch': function(onRejection, label) {
- return this.then(null, onRejection, label);
- },
-
- /**
- `finally` will be invoked regardless of the promise's fate just as native
- try/catch/finally behaves
-
- Synchronous example:
-
- ```js
- findAuthor() {
- if (Math.random() > 0.5) {
- throw new Error();
- }
- return new Author();
- }
-
- try {
- return findAuthor(); // succeed or fail
- } catch(error) {
- return findOtherAuther();
- } finally {
- // always runs
- // doesn't affect the return value
- }
- ```
-
- Asynchronous example:
-
- ```js
- findAuthor().catch(function(reason){
- return findOtherAuther();
- }).finally(function(){
- // author was either found, or not
- });
- ```
-
- @method finally
- @param {Function} callback
- @param {String} label optional string for labeling the promise.
- Useful for tooling.
- @return {Promise}
- */
- 'finally': function(callback, label) {
- var constructor = this.constructor;
-
- return this.then(function(value) {
- return constructor.resolve(callback()).then(function(){
- return value;
- });
- }, function(reason) {
- return constructor.resolve(callback()).then(function(){
- throw reason;
- });
- }, label);
- }
- };
- });
-define("rsvp/promise/all",
- ["../enumerator","exports"],
- function(__dependency1__, __exports__) {
- "use strict";
- var Enumerator = __dependency1__["default"];
-
- /**
- `RSVP.Promise.all` accepts an array of promises, and returns a new promise which
- is fulfilled with an array of fulfillment values for the passed promises, or
- rejected with the reason of the first passed promise to be rejected. It casts all
- elements of the passed iterable to promises as it runs this algorithm.
-
- Example:
-
- ```javascript
- var promise1 = RSVP.resolve(1);
- var promise2 = RSVP.resolve(2);
- var promise3 = RSVP.resolve(3);
- var promises = [ promise1, promise2, promise3 ];
-
- RSVP.Promise.all(promises).then(function(array){
- // The array here would be [ 1, 2, 3 ];
- });
- ```
-
- If any of the `promises` given to `RSVP.all` are rejected, the first promise
- that is rejected will be given as an argument to the returned promises's
- rejection handler. For example:
-
- Example:
-
- ```javascript
- var promise1 = RSVP.resolve(1);
- var promise2 = RSVP.reject(new Error("2"));
- var promise3 = RSVP.reject(new Error("3"));
- var promises = [ promise1, promise2, promise3 ];
-
- RSVP.Promise.all(promises).then(function(array){
- // Code here never runs because there are rejected promises!
- }, function(error) {
- // error.message === "2"
- });
- ```
-
- @method all
- @static
- @param {Array} entries array of promises
- @param {String} label optional string for labeling the promise.
- Useful for tooling.
- @return {Promise} promise that is fulfilled when all `promises` have been
- fulfilled, or rejected if any of them become rejected.
- @static
- */
- __exports__["default"] = function all(entries, label) {
- return new Enumerator(this, entries, true /* abort on reject */, label).promise;
- }
- });
-define("rsvp/promise/race",
- ["../utils","../-internal","exports"],
- function(__dependency1__, __dependency2__, __exports__) {
- "use strict";
- var isArray = __dependency1__.isArray;
-
- var noop = __dependency2__.noop;
- var resolve = __dependency2__.resolve;
- var reject = __dependency2__.reject;
- var subscribe = __dependency2__.subscribe;
- var PENDING = __dependency2__.PENDING;
-
- /**
- `RSVP.Promise.race` returns a new promise which is settled in the same way as the
- first passed promise to settle.
-
- Example:
-
- ```javascript
- var promise1 = new RSVP.Promise(function(resolve, reject){
- setTimeout(function(){
- resolve('promise 1');
- }, 200);
- });
-
- var promise2 = new RSVP.Promise(function(resolve, reject){
- setTimeout(function(){
- resolve('promise 2');
- }, 100);
- });
-
- RSVP.Promise.race([promise1, promise2]).then(function(result){
- // result === 'promise 2' because it was resolved before promise1
- // was resolved.
- });
- ```
-
- `RSVP.Promise.race` is deterministic in that only the state of the first
- settled promise matters. For example, even if other promises given to the
- `promises` array argument are resolved, but the first settled promise has
- become rejected before the other promises became fulfilled, the returned
- promise will become rejected:
-
- ```javascript
- var promise1 = new RSVP.Promise(function(resolve, reject){
- setTimeout(function(){
- resolve('promise 1');
- }, 200);
- });
-
- var promise2 = new RSVP.Promise(function(resolve, reject){
- setTimeout(function(){
- reject(new Error('promise 2'));
- }, 100);
- });
-
- RSVP.Promise.race([promise1, promise2]).then(function(result){
- // Code here never runs
- }, function(reason){
- // reason.message === 'promise 2' because promise 2 became rejected before
- // promise 1 became fulfilled
- });
- ```
-
- An example real-world use case is implementing timeouts:
-
- ```javascript
- RSVP.Promise.race([ajax('foo.json'), timeout(5000)])
- ```
-
- @method race
- @static
- @param {Array} promises array of promises to observe
- @param {String} label optional string for describing the promise returned.
- Useful for tooling.
- @return {Promise} a promise which settles in the same way as the first passed
- promise to settle.
- */
- __exports__["default"] = function race(entries, label) {
- /*jshint validthis:true */
- var Constructor = this;
-
- var promise = new Constructor(noop, label);
-
- if (!isArray(entries)) {
- reject(promise, new TypeError('You must pass an array to race.'));
- return promise;
- }
-
- var length = entries.length;
-
- function onFulfillment(value) {
- resolve(promise, value);
- }
-
- function onRejection(reason) {
- reject(promise, reason);
- }
-
- for (var i = 0; promise._state === PENDING && i < length; i++) {
- subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);
- }
-
- return promise;
- }
- });
-define("rsvp/promise/reject",
- ["../-internal","exports"],
- function(__dependency1__, __exports__) {
- "use strict";
- var noop = __dependency1__.noop;
- var _reject = __dependency1__.reject;
-
- /**
- `RSVP.Promise.reject` returns a promise rejected with the passed `reason`.
- It is shorthand for the following:
-
- ```javascript
- var promise = new RSVP.Promise(function(resolve, reject){
- reject(new Error('WHOOPS'));
- });
-
- promise.then(function(value){
- // Code here doesn't run because the promise is rejected!
- }, function(reason){
- // reason.message === 'WHOOPS'
- });
- ```
-
- Instead of writing the above, your code now simply becomes the following:
-
- ```javascript
- var promise = RSVP.Promise.reject(new Error('WHOOPS'));
-
- promise.then(function(value){
- // Code here doesn't run because the promise is rejected!
- }, function(reason){
- // reason.message === 'WHOOPS'
- });
- ```
-
- @method reject
- @static
- @param {Any} reason value that the returned promise will be rejected with.
- @param {String} label optional string for identifying the returned promise.
- Useful for tooling.
- @return {Promise} a promise rejected with the given `reason`.
- */
- __exports__["default"] = function reject(reason, label) {
- /*jshint validthis:true */
- var Constructor = this;
- var promise = new Constructor(noop, label);
- _reject(promise, reason);
- return promise;
- }
- });
-define("rsvp/promise/resolve",
- ["../-internal","exports"],
- function(__dependency1__, __exports__) {
- "use strict";
- var noop = __dependency1__.noop;
- var _resolve = __dependency1__.resolve;
-
- /**
- `RSVP.Promise.resolve` returns a promise that will become resolved with the
- passed `value`. It is shorthand for the following:
-
- ```javascript
- var promise = new RSVP.Promise(function(resolve, reject){
- resolve(1);
- });
-
- promise.then(function(value){
- // value === 1
- });
- ```
-
- Instead of writing the above, your code now simply becomes the following:
-
- ```javascript
- var promise = RSVP.Promise.resolve(1);
-
- promise.then(function(value){
- // value === 1
- });
- ```
-
- @method resolve
- @static
- @param {Any} value value that the returned promise will be resolved with
- @param {String} label optional string for identifying the returned promise.
- Useful for tooling.
- @return {Promise} a promise that will become fulfilled with the given
- `value`
- */
- __exports__["default"] = function resolve(object, label) {
- /*jshint validthis:true */
- var Constructor = this;
-
- if (object && typeof object === 'object' && object.constructor === Constructor) {
- return object;
- }
-
- var promise = new Constructor(noop, label);
- _resolve(promise, object);
- return promise;
- }
- });
-define("rsvp/race",
- ["./promise","exports"],
- function(__dependency1__, __exports__) {
- "use strict";
- var Promise = __dependency1__["default"];
-
- /**
- This is a convenient alias for `RSVP.Promise.race`.
-
- @method race
- @static
- @for RSVP
- @param {Array} array Array of promises.
- @param {String} label An optional label. This is useful
- for tooling.
- */
- __exports__["default"] = function race(array, label) {
- return Promise.race(array, label);
- }
- });
-define("rsvp/reject",
- ["./promise","exports"],
- function(__dependency1__, __exports__) {
- "use strict";
- var Promise = __dependency1__["default"];
-
- /**
- This is a convenient alias for `RSVP.Promise.reject`.
-
- @method reject
- @static
- @for RSVP
- @param {Any} reason value that the returned promise will be rejected with.
- @param {String} label optional string for identifying the returned promise.
- Useful for tooling.
- @return {Promise} a promise rejected with the given `reason`.
- */
- __exports__["default"] = function reject(reason, label) {
- return Promise.reject(reason, label);
- }
- });
-define("rsvp/resolve",
- ["./promise","exports"],
- function(__dependency1__, __exports__) {
- "use strict";
- var Promise = __dependency1__["default"];
-
- /**
- This is a convenient alias for `RSVP.Promise.resolve`.
-
- @method resolve
- @static
- @for RSVP
- @param {Any} value value that the returned promise will be resolved with
- @param {String} label optional string for identifying the returned promise.
- Useful for tooling.
- @return {Promise} a promise that will become fulfilled with the given
- `value`
- */
- __exports__["default"] = function resolve(value, label) {
- return Promise.resolve(value, label);
- }
- });
-define("rsvp/rethrow",
- ["exports"],
- function(__exports__) {
- "use strict";
- /**
- `RSVP.rethrow` will rethrow an error on the next turn of the JavaScript event
- loop in order to aid debugging.
-
- Promises A+ specifies that any exceptions that occur with a promise must be
- caught by the promises implementation and bubbled to the last handler. For
- this reason, it is recommended that you always specify a second rejection
- handler function to `then`. However, `RSVP.rethrow` will throw the exception
- outside of the promise, so it bubbles up to your console if in the browser,
- or domain/cause uncaught exception in Node. `rethrow` will also throw the
- error again so the error can be handled by the promise per the spec.
-
- ```javascript
- function throws(){
- throw new Error('Whoops!');
- }
-
- var promise = new RSVP.Promise(function(resolve, reject){
- throws();
- });
-
- promise.catch(RSVP.rethrow).then(function(){
- // Code here doesn't run because the promise became rejected due to an
- // error!
- }, function (err){
- // handle the error here
- });
- ```
-
- The 'Whoops' error will be thrown on the next turn of the event loop
- and you can watch for it in your console. You can also handle it using a
- rejection handler given to `.then` or `.catch` on the returned promise.
-
- @method rethrow
- @static
- @for RSVP
- @param {Error} reason reason the promise became rejected.
- @throws Error
- @static
- */
- __exports__["default"] = function rethrow(reason) {
- setTimeout(function() {
- throw reason;
- });
- throw reason;
- }
- });
-define("rsvp/utils",
- ["exports"],
- function(__exports__) {
- "use strict";
- function objectOrFunction(x) {
- return typeof x === 'function' || (typeof x === 'object' && x !== null);
- }
-
- __exports__.objectOrFunction = objectOrFunction;function isFunction(x) {
- return typeof x === 'function';
- }
-
- __exports__.isFunction = isFunction;function isMaybeThenable(x) {
- return typeof x === 'object' && x !== null;
- }
-
- __exports__.isMaybeThenable = isMaybeThenable;var _isArray;
- if (!Array.isArray) {
- _isArray = function (x) {
- return Object.prototype.toString.call(x) === '[object Array]';
- };
- } else {
- _isArray = Array.isArray;
- }
-
- var isArray = _isArray;
- __exports__.isArray = isArray;
- // Date.now is not available in browsers < IE9
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#Compatibility
- var now = Date.now || function() { return new Date().getTime(); };
- __exports__.now = now;
- function F() { }
-
- var o_create = (Object.create || function (o) {
- if (arguments.length > 1) {
- throw new Error('Second argument not supported');
- }
- if (typeof o !== 'object') {
- throw new TypeError('Argument must be an object');
- }
- F.prototype = o;
- return new F();
- });
- __exports__.o_create = o_create;
- });
-requireModule("ember");
-
-})();
\ No newline at end of file
diff --git a/httpclient/.classpath b/httpclient/.classpath
deleted file mode 100644
index 8ebf6d9c31..0000000000
--- a/httpclient/.classpath
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/httpclient/.project b/httpclient/.project
deleted file mode 100644
index 83c3ed0493..0000000000
--- a/httpclient/.project
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
- httpclient
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/httpclient/.springBeans b/httpclient/.springBeans
deleted file mode 100644
index a79097f40d..0000000000
--- a/httpclient/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/api-servlet.xml
-
-
-
-
diff --git a/hystrix/pom.xml b/hystrix/pom.xml
new file mode 100644
index 0000000000..0ec5fa0411
--- /dev/null
+++ b/hystrix/pom.xml
@@ -0,0 +1,80 @@
+
+
+ 4.0.0
+ com.baeldung
+ hystrix
+ 1.0
+
+ hystrix
+
+
+
+
+ 1.8
+
+
+ 1.4.10
+ 0.20.7
+
+
+ 1.3
+ 4.12
+
+
+ 3.5.1
+ 2.6
+ 2.19.1
+ 2.7
+
+
+
+
+
+
+ com.netflix.hystrix
+ hystrix-core
+ ${hystrix-core.version}
+
+
+
+ com.netflix.rxjava
+ rxjava-core
+ ${rxjava-core.version}
+
+
+
+ org.hamcrest
+ hamcrest-all
+ ${hamcrest-all.version}
+ test
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+
+
diff --git a/hystrix/src/main/java/com/baeldung/hystrix/RemoteServiceSimulator.java b/hystrix/src/main/java/com/baeldung/hystrix/RemoteServiceSimulator.java
new file mode 100644
index 0000000000..3efd579d84
--- /dev/null
+++ b/hystrix/src/main/java/com/baeldung/hystrix/RemoteServiceSimulator.java
@@ -0,0 +1,15 @@
+package com.baeldung.hystrix;
+
+
+public class RemoteServiceSimulator {
+
+ public String checkSomething(final long timeout) throws InterruptedException {
+
+ System.out.print(String.format("Waiting %sms. ", timeout));
+
+ // to simulate a real world delay in processing.
+ Thread.sleep(timeout);
+
+ return "Done waiting.";
+ }
+}
diff --git a/hystrix/src/test/java/com/baeldung/hystrix/CommandHelloWorld.java b/hystrix/src/test/java/com/baeldung/hystrix/CommandHelloWorld.java
new file mode 100644
index 0000000000..4f2b0c38c3
--- /dev/null
+++ b/hystrix/src/test/java/com/baeldung/hystrix/CommandHelloWorld.java
@@ -0,0 +1,19 @@
+package com.baeldung.hystrix;
+
+import com.netflix.hystrix.HystrixCommand;
+import com.netflix.hystrix.HystrixCommandGroupKey;
+
+class CommandHelloWorld extends HystrixCommand {
+
+ private final String name;
+
+ CommandHelloWorld(String name) {
+ super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
+ this.name = name;
+ }
+
+ @Override
+ protected String run() {
+ return "Hello " + name + "!";
+ }
+}
diff --git a/hystrix/src/test/java/com/baeldung/hystrix/HystrixTimeoutTest.java b/hystrix/src/test/java/com/baeldung/hystrix/HystrixTimeoutTest.java
new file mode 100644
index 0000000000..773c76536f
--- /dev/null
+++ b/hystrix/src/test/java/com/baeldung/hystrix/HystrixTimeoutTest.java
@@ -0,0 +1,62 @@
+package com.baeldung.hystrix;
+
+import com.netflix.hystrix.*;
+import com.netflix.hystrix.collapser.RequestCollapserFactory;
+import com.netflix.hystrix.exception.HystrixRuntimeException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+
+public class HystrixTimeoutTest {
+
+ private static HystrixCommand.Setter config;
+ private static HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter();
+
+
+ @Rule
+ public final ExpectedException exception = ExpectedException.none();
+
+ @Before
+ public void setup() {
+ config = HystrixCommand
+ .Setter
+ .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroup1"));
+ }
+
+ @Test
+ public void givenInputBob_andDefaultSettings_thenReturnHelloBob(){
+ assertThat(new CommandHelloWorld("Bob").execute(), equalTo("Hello Bob!"));
+ }
+
+ @Test
+ public void givenTimeoutEqualTo100_andDefaultSettings_thenReturnSuccess() throws InterruptedException {
+ assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(100)).execute(), equalTo("Success"));
+ }
+
+ @Test
+ public void givenTimeoutEqualTo10000_andDefaultSettings_thenExpectHystrixRuntimeException() throws InterruptedException {
+ exception.expect(HystrixRuntimeException.class);
+ new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(10_000)).execute();
+ }
+
+ @Test
+ public void givenTimeoutEqualTo5000_andExecutionTimeoutEqualTo10000_thenReturnSuccess() throws InterruptedException {
+ commandProperties.withExecutionTimeoutInMilliseconds(10_000);
+ config.andCommandPropertiesDefaults(commandProperties);
+ assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(5_000)).execute(), equalTo("Success"));
+ }
+
+ @Test
+ public void givenTimeoutEqualTo15000_andExecutionTimeoutEqualTo10000_thenExpectHystrixRuntimeException() throws InterruptedException {
+ exception.expect(HystrixRuntimeException.class);
+ commandProperties.withExecutionTimeoutInMilliseconds(10_000);
+ config.andCommandPropertiesDefaults(commandProperties);
+ new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(15_000)).execute();
+ }
+
+}
diff --git a/hystrix/src/test/java/com/baeldung/hystrix/RemoteServiceTestCommand.java b/hystrix/src/test/java/com/baeldung/hystrix/RemoteServiceTestCommand.java
new file mode 100644
index 0000000000..49ea951579
--- /dev/null
+++ b/hystrix/src/test/java/com/baeldung/hystrix/RemoteServiceTestCommand.java
@@ -0,0 +1,20 @@
+package com.baeldung.hystrix;
+
+import com.netflix.hystrix.HystrixCommand;
+import com.netflix.hystrix.HystrixCommandGroupKey;
+
+
+class RemoteServiceTestCommand extends HystrixCommand {
+
+ private final RemoteServiceTestSimulator remoteService;
+
+ RemoteServiceTestCommand(Setter config, RemoteServiceTestSimulator remoteService) {
+ super(config);
+ this.remoteService = remoteService;
+ }
+
+ @Override
+ protected String run() throws Exception {
+ return remoteService.execute();
+ }
+}
diff --git a/hystrix/src/test/java/com/baeldung/hystrix/RemoteServiceTestSimulator.java b/hystrix/src/test/java/com/baeldung/hystrix/RemoteServiceTestSimulator.java
new file mode 100644
index 0000000000..54c626a67a
--- /dev/null
+++ b/hystrix/src/test/java/com/baeldung/hystrix/RemoteServiceTestSimulator.java
@@ -0,0 +1,16 @@
+package com.baeldung.hystrix;
+
+
+class RemoteServiceTestSimulator {
+
+ private long wait;
+
+ RemoteServiceTestSimulator(long wait) throws InterruptedException {
+ this.wait = wait;
+ }
+
+ String execute() throws InterruptedException {
+ Thread.sleep(wait);
+ return "Success";
+ }
+}
diff --git a/immutables/pom.xml b/immutables/pom.xml
new file mode 100644
index 0000000000..2b4aba59b1
--- /dev/null
+++ b/immutables/pom.xml
@@ -0,0 +1,50 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ immutables
+ 1.0.0-SNAPSHOT
+
+
+
+ org.immutables
+ value
+ 2.2.10
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.assertj
+ assertj-core
+ 3.5.2
+ test
+
+
+ org.mutabilitydetector
+ MutabilityDetector
+ 0.9.5
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.3
+
+ 1.8
+ 1.8
+
+
+
+
+
\ No newline at end of file
diff --git a/immutables/src/main/java/com/baeldung/immutable/Address.java b/immutables/src/main/java/com/baeldung/immutable/Address.java
new file mode 100644
index 0000000000..93474dc043
--- /dev/null
+++ b/immutables/src/main/java/com/baeldung/immutable/Address.java
@@ -0,0 +1,9 @@
+package com.baeldung.immutable;
+
+import org.immutables.value.Value;
+
+@Value.Immutable
+public interface Address {
+ String getStreetName();
+ Integer getNumber();
+}
diff --git a/immutables/src/main/java/com/baeldung/immutable/Person.java b/immutables/src/main/java/com/baeldung/immutable/Person.java
new file mode 100644
index 0000000000..466daf42c2
--- /dev/null
+++ b/immutables/src/main/java/com/baeldung/immutable/Person.java
@@ -0,0 +1,9 @@
+package com.baeldung.immutable;
+
+import org.immutables.value.Value;
+
+@Value.Immutable
+public abstract class Person {
+ abstract String getName();
+ abstract Integer getAge();
+}
diff --git a/immutables/src/main/java/com/baeldung/immutable/auxiliary/Person.java b/immutables/src/main/java/com/baeldung/immutable/auxiliary/Person.java
new file mode 100644
index 0000000000..78fe28c50c
--- /dev/null
+++ b/immutables/src/main/java/com/baeldung/immutable/auxiliary/Person.java
@@ -0,0 +1,13 @@
+package com.baeldung.immutable.auxiliary;
+
+
+import org.immutables.value.Value;
+
+@Value.Immutable
+public abstract class Person {
+ abstract String getName();
+ abstract Integer getAge();
+
+ @Value.Auxiliary
+ abstract String getAuxiliaryField();
+}
\ No newline at end of file
diff --git a/immutables/src/main/java/com/baeldung/immutable/default_/Person.java b/immutables/src/main/java/com/baeldung/immutable/default_/Person.java
new file mode 100644
index 0000000000..bc48f11a38
--- /dev/null
+++ b/immutables/src/main/java/com/baeldung/immutable/default_/Person.java
@@ -0,0 +1,14 @@
+package com.baeldung.immutable.default_;
+
+import org.immutables.value.Value;
+
+@Value.Immutable(prehash = true)
+public abstract class Person {
+
+ abstract String getName();
+
+ @Value.Default
+ Integer getAge() {
+ return 42;
+ }
+}
diff --git a/immutables/src/main/java/com/baeldung/immutable/parameter/Person.java b/immutables/src/main/java/com/baeldung/immutable/parameter/Person.java
new file mode 100644
index 0000000000..4e8218f99c
--- /dev/null
+++ b/immutables/src/main/java/com/baeldung/immutable/parameter/Person.java
@@ -0,0 +1,14 @@
+package com.baeldung.immutable.parameter;
+
+
+import org.immutables.value.Value;
+
+@Value.Immutable
+public abstract class Person {
+
+ @Value.Parameter
+ abstract String getName();
+
+ @Value.Parameter
+ abstract Integer getAge();
+}
\ No newline at end of file
diff --git a/immutables/src/main/java/com/baeldung/immutable/prehash/Person.java b/immutables/src/main/java/com/baeldung/immutable/prehash/Person.java
new file mode 100644
index 0000000000..5e5dd4d9e9
--- /dev/null
+++ b/immutables/src/main/java/com/baeldung/immutable/prehash/Person.java
@@ -0,0 +1,9 @@
+package com.baeldung.immutable.prehash;
+
+import org.immutables.value.Value;
+
+@Value.Immutable(prehash = true)
+public abstract class Person {
+ abstract String getName();
+ abstract Integer getAge();
+}
diff --git a/immutables/src/test/java/com/baeldung/immutable/ImmutablePersonTest.java b/immutables/src/test/java/com/baeldung/immutable/ImmutablePersonTest.java
new file mode 100644
index 0000000000..bf075569db
--- /dev/null
+++ b/immutables/src/test/java/com/baeldung/immutable/ImmutablePersonTest.java
@@ -0,0 +1,27 @@
+package com.baeldung.immutable;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mutabilitydetector.unittesting.MutabilityAssert.assertImmutable;
+
+public class ImmutablePersonTest {
+
+ @Test
+ public void whenModifying_shouldCreateNewInstance() throws Exception {
+ final ImmutablePerson john = ImmutablePerson.builder()
+ .age(42)
+ .name("John")
+ .build();
+
+ final ImmutablePerson john43 = john.withAge(43);
+
+ assertThat(john)
+ .isNotSameAs(john43);
+
+ assertThat(john.getAge())
+ .isEqualTo(42);
+
+ assertImmutable(ImmutablePerson.class);
+ }
+}
\ No newline at end of file
diff --git a/immutables/src/test/java/com/baeldung/immutable/auxiliary/ImmutablePersonAuxiliaryTest.java b/immutables/src/test/java/com/baeldung/immutable/auxiliary/ImmutablePersonAuxiliaryTest.java
new file mode 100644
index 0000000000..83f9e51ed5
--- /dev/null
+++ b/immutables/src/test/java/com/baeldung/immutable/auxiliary/ImmutablePersonAuxiliaryTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.immutable.auxiliary;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ImmutablePersonAuxiliaryTest {
+
+ @Test
+ public void whenComparing_shouldIgnore() throws Exception {
+ final ImmutablePerson john1 = ImmutablePerson.builder()
+ .name("John")
+ .age(42)
+ .auxiliaryField("Value1")
+ .build();
+
+ final ImmutablePerson john2 = ImmutablePerson.builder()
+ .name("John")
+ .age(42)
+ .auxiliaryField("Value2")
+ .build();
+
+
+ assertThat(john1.equals(john2))
+ .isTrue();
+
+ assertThat(john1.toString())
+ .isEqualTo(john2.toString());
+
+ assertThat(john1.hashCode())
+ .isEqualTo(john2.hashCode());
+ }
+}
\ No newline at end of file
diff --git a/immutables/src/test/java/com/baeldung/immutable/default_/ImmutablePersonDefaultTest.java b/immutables/src/test/java/com/baeldung/immutable/default_/ImmutablePersonDefaultTest.java
new file mode 100644
index 0000000000..5cf4ac0cf7
--- /dev/null
+++ b/immutables/src/test/java/com/baeldung/immutable/default_/ImmutablePersonDefaultTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.immutable.default_;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ImmutablePersonDefaultTest {
+
+ @Test
+ public void whenInstantiating_shouldUseDefaultValue() throws Exception {
+
+ final ImmutablePerson john = ImmutablePerson.builder().name("John").build();
+
+ assertThat(john.getAge()).isEqualTo(42);
+
+ }
+}
\ No newline at end of file
diff --git a/jackson/.classpath b/jackson/.classpath
deleted file mode 100644
index 8ebf6d9c31..0000000000
--- a/jackson/.classpath
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/jackson/.project b/jackson/.project
deleted file mode 100644
index ea8ae1a67f..0000000000
--- a/jackson/.project
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
- jackson
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/jackson/.springBeans b/jackson/.springBeans
deleted file mode 100644
index a79097f40d..0000000000
--- a/jackson/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/api-servlet.xml
-
-
-
-
diff --git a/jackson/pom.xml b/jackson/pom.xml
index c7cd172757..17b0ac507e 100644
--- a/jackson/pom.xml
+++ b/jackson/pom.xml
@@ -109,6 +109,31 @@
${mockito.version}
test
+
+
+
+
+ org.slf4j
+ slf4j-api
+ ${org.slf4j.version}
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+
+
+
+ org.slf4j
+ jcl-over-slf4j
+ ${org.slf4j.version}
+
+
+
+ org.slf4j
+ log4j-over-slf4j
+ ${org.slf4j.version}
+
diff --git a/jackson/src/test/java/com/baeldung/jackson/bidirection/CustomListDeserializer.java b/jackson/src/test/java/com/baeldung/jackson/bidirection/CustomListDeserializer.java
index 5f1f1edf2b..c00316e365 100644
--- a/jackson/src/test/java/com/baeldung/jackson/bidirection/CustomListDeserializer.java
+++ b/jackson/src/test/java/com/baeldung/jackson/bidirection/CustomListDeserializer.java
@@ -7,9 +7,19 @@ import java.util.List;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
-public class CustomListDeserializer extends JsonDeserializer> {
+public class CustomListDeserializer extends StdDeserializer> {
+
+ private static final long serialVersionUID = 1095767961632979804L;
+
+ public CustomListDeserializer() {
+ this(null);
+ }
+
+ public CustomListDeserializer(final Class> vc) {
+ super(vc);
+ }
@Override
public List deserialize(final JsonParser jsonparser, final DeserializationContext context) throws IOException, JsonProcessingException {
diff --git a/jackson/src/test/java/com/baeldung/jackson/bidirection/CustomListSerializer.java b/jackson/src/test/java/com/baeldung/jackson/bidirection/CustomListSerializer.java
index 1d8ca011ea..75e0a4ecb7 100644
--- a/jackson/src/test/java/com/baeldung/jackson/bidirection/CustomListSerializer.java
+++ b/jackson/src/test/java/com/baeldung/jackson/bidirection/CustomListSerializer.java
@@ -6,11 +6,20 @@ import java.util.List;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
-public class CustomListSerializer extends JsonSerializer> {
+public class CustomListSerializer extends StdSerializer> {
+ private static final long serialVersionUID = 3698763098000900856L;
+
+ public CustomListSerializer() {
+ this(null);
+ }
+
+ public CustomListSerializer(final Class> t) {
+ super(t);
+ }
@Override
public void serialize(final List items, final JsonGenerator generator, final SerializerProvider provider) throws IOException, JsonProcessingException {
final List ids = new ArrayList();
diff --git a/jackson/src/test/java/com/baeldung/jackson/date/CustomDateDeserializer.java b/jackson/src/test/java/com/baeldung/jackson/date/CustomDateDeserializer.java
index a63190c8f5..90c7d9fbac 100644
--- a/jackson/src/test/java/com/baeldung/jackson/date/CustomDateDeserializer.java
+++ b/jackson/src/test/java/com/baeldung/jackson/date/CustomDateDeserializer.java
@@ -8,12 +8,21 @@ import java.util.Date;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
-public class CustomDateDeserializer extends JsonDeserializer {
+public class CustomDateDeserializer extends StdDeserializer {
+ private static final long serialVersionUID = -5451717385630622729L;
private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
+ public CustomDateDeserializer() {
+ this(null);
+ }
+
+ public CustomDateDeserializer(final Class> vc) {
+ super(vc);
+ }
+
@Override
public Date deserialize(final JsonParser jsonparser, final DeserializationContext context) throws IOException, JsonProcessingException {
final String date = jsonparser.getText();
diff --git a/jackson/src/test/java/com/baeldung/jackson/date/CustomDateSerializer.java b/jackson/src/test/java/com/baeldung/jackson/date/CustomDateSerializer.java
index 8d435b7b69..d840e1940f 100644
--- a/jackson/src/test/java/com/baeldung/jackson/date/CustomDateSerializer.java
+++ b/jackson/src/test/java/com/baeldung/jackson/date/CustomDateSerializer.java
@@ -6,13 +6,22 @@ import java.util.Date;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
-public class CustomDateSerializer extends JsonSerializer {
+public class CustomDateSerializer extends StdSerializer {
+ private static final long serialVersionUID = -2894356342227378312L;
private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
+ public CustomDateSerializer() {
+ this(null);
+ }
+
+ public CustomDateSerializer(final Class t) {
+ super(t);
+ }
+
@Override
public void serialize(final Date value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException {
gen.writeString(formatter.format(value));
diff --git a/jackson/src/test/java/com/baeldung/jackson/date/CustomDateTimeSerializer.java b/jackson/src/test/java/com/baeldung/jackson/date/CustomDateTimeSerializer.java
index 88c069419b..ab4f4bbec7 100644
--- a/jackson/src/test/java/com/baeldung/jackson/date/CustomDateTimeSerializer.java
+++ b/jackson/src/test/java/com/baeldung/jackson/date/CustomDateTimeSerializer.java
@@ -8,10 +8,20 @@ import org.joda.time.format.DateTimeFormatter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
-public class CustomDateTimeSerializer extends JsonSerializer {
+public class CustomDateTimeSerializer extends StdSerializer {
+
+ private static final long serialVersionUID = -3927232057990121460L;
+
+ public CustomDateTimeSerializer() {
+ this(null);
+ }
+
+ public CustomDateTimeSerializer(final Class t) {
+ super(t);
+ }
private static DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
diff --git a/jackson/src/test/java/com/baeldung/jackson/date/CustomLocalDateTimeSerializer.java b/jackson/src/test/java/com/baeldung/jackson/date/CustomLocalDateTimeSerializer.java
index 3f8f5e098e..dbcf42488e 100644
--- a/jackson/src/test/java/com/baeldung/jackson/date/CustomLocalDateTimeSerializer.java
+++ b/jackson/src/test/java/com/baeldung/jackson/date/CustomLocalDateTimeSerializer.java
@@ -6,13 +6,23 @@ import java.time.format.DateTimeFormatter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
-public class CustomLocalDateTimeSerializer extends JsonSerializer {
+public class CustomLocalDateTimeSerializer extends StdSerializer {
+
+ private static final long serialVersionUID = -7449444168934819290L;
private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
+ public CustomLocalDateTimeSerializer() {
+ this(null);
+ }
+
+ public CustomLocalDateTimeSerializer(final Class t) {
+ super(t);
+ }
+
@Override
public void serialize(final LocalDateTime value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException {
gen.writeString(formatter.format(value));
diff --git a/jackson/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializer.java b/jackson/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializer.java
index 3be6685103..e9c89b8c78 100644
--- a/jackson/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializer.java
+++ b/jackson/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializer.java
@@ -2,17 +2,26 @@ package com.baeldung.jackson.deserialization;
import java.io.IOException;
-import com.baeldung.jackson.dtos.User;
import com.baeldung.jackson.dtos.Item;
-
+import com.baeldung.jackson.dtos.User;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.node.IntNode;
-public class ItemDeserializer extends JsonDeserializer- {
+public class ItemDeserializer extends StdDeserializer
- {
+
+ private static final long serialVersionUID = 1883547683050039861L;
+
+ public ItemDeserializer() {
+ this(null);
+ }
+
+ public ItemDeserializer(final Class> vc) {
+ super(vc);
+ }
/**
* {"id":1,"itemNr":"theItem","owner":2}
diff --git a/jackson/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializerOnClass.java b/jackson/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializerOnClass.java
index 169a5c1c50..2036780e99 100644
--- a/jackson/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializerOnClass.java
+++ b/jackson/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializerOnClass.java
@@ -4,15 +4,24 @@ import java.io.IOException;
import com.baeldung.jackson.dtos.ItemWithSerializer;
import com.baeldung.jackson.dtos.User;
-
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.node.IntNode;
-public class ItemDeserializerOnClass extends JsonDeserializer
{
+public class ItemDeserializerOnClass extends StdDeserializer {
+
+ private static final long serialVersionUID = 5579141241817332594L;
+
+ public ItemDeserializerOnClass() {
+ this(null);
+ }
+
+ public ItemDeserializerOnClass(final Class> vc) {
+ super(vc);
+ }
/**
* {"id":1,"itemNr":"theItem","owner":2}
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java b/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java
new file mode 100644
index 0000000000..58293c0562
--- /dev/null
+++ b/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java
@@ -0,0 +1,54 @@
+package com.baeldung.jackson.dtos;
+
+public class MyDtoWithSpecialField {
+
+ private String[] stringValue;
+ private int intValue;
+ private boolean booleanValue;
+
+ public MyDtoWithSpecialField() {
+ super();
+ }
+
+ public MyDtoWithSpecialField(final String[] stringValue, final int intValue, final boolean booleanValue) {
+ super();
+
+ this.stringValue = stringValue;
+ this.intValue = intValue;
+ this.booleanValue = booleanValue;
+ }
+
+ // API
+
+ public String[] getStringValue() {
+ return stringValue;
+ }
+
+ public void setStringValue(final String[] stringValue) {
+ this.stringValue = stringValue;
+ }
+
+ public int getIntValue() {
+ return intValue;
+ }
+
+ public void setIntValue(final int intValue) {
+ this.intValue = intValue;
+ }
+
+ public boolean isBooleanValue() {
+ return booleanValue;
+ }
+
+ public void setBooleanValue(final boolean booleanValue) {
+ this.booleanValue = booleanValue;
+ }
+
+ //
+
+ @Override
+ public String toString() {
+ return "MyDto [stringValue=" + stringValue + ", intValue=" + intValue + ", booleanValue=" + booleanValue + "]";
+ }
+
+}
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyMixInForString.java b/jackson/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java
similarity index 76%
rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyMixInForString.java
rename to jackson/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java
index b386541df6..ca29c98b9a 100644
--- a/jackson/src/test/java/com/baeldung/jackson/dtos/MyMixInForString.java
+++ b/jackson/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java
@@ -3,6 +3,6 @@ package com.baeldung.jackson.dtos;
import com.fasterxml.jackson.annotation.JsonIgnoreType;
@JsonIgnoreType
-public class MyMixInForString {
+public class MyMixInForIgnoreType {
//
}
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/TypeSerializer.java b/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/TypeSerializer.java
index c5d5d7e0a8..fc5011137c 100644
--- a/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/TypeSerializer.java
+++ b/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/TypeSerializer.java
@@ -4,10 +4,20 @@ import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
-public class TypeSerializer extends JsonSerializer {
+public class TypeSerializer extends StdSerializer {
+
+ private static final long serialVersionUID = -7650668914169390772L;
+
+ public TypeSerializer() {
+ this(null);
+ }
+
+ public TypeSerializer(final Class t) {
+ super(t);
+ }
@Override
public void serialize(final TypeEnumWithCustomSerializer value, final JsonGenerator generator, final SerializerProvider provider) throws IOException, JsonProcessingException {
diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java b/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java
new file mode 100644
index 0000000000..a3d0b377c6
--- /dev/null
+++ b/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java
@@ -0,0 +1,44 @@
+package com.baeldung.jackson.objectmapper;
+
+import java.io.IOException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.baeldung.jackson.objectmapper.dto.Car;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.ObjectCodec;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+public class CustomCarDeserializer extends StdDeserializer {
+
+ private static final long serialVersionUID = -5918629454846356161L;
+ private final Logger Logger = LoggerFactory.getLogger(getClass());
+
+ public CustomCarDeserializer() {
+ this(null);
+ }
+
+ public CustomCarDeserializer(final Class> vc) {
+ super(vc);
+ }
+
+
+
+ @Override
+ public Car deserialize(final JsonParser parser, final DeserializationContext deserializer) throws IOException {
+ final Car car = new Car();
+ final ObjectCodec codec = parser.getCodec();
+ final JsonNode node = codec.readTree(parser);
+ try {
+ final JsonNode colorNode = node.get("color");
+ final String color = colorNode.asText();
+ car.setColor(color);
+ } catch (final Exception e) {
+ Logger.debug("101_parse_exeption: unknown json.");
+ }
+ return car;
+ }
+}
diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java b/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java
new file mode 100644
index 0000000000..37bae829b7
--- /dev/null
+++ b/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java
@@ -0,0 +1,31 @@
+package com.baeldung.jackson.objectmapper;
+
+import java.io.IOException;
+
+import com.baeldung.jackson.objectmapper.dto.Car;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+public class CustomCarSerializer extends StdSerializer
+{
+
+ private static final long serialVersionUID = 1396140685442227917L;
+
+ public CustomCarSerializer() {
+ this(null);
+ }
+
+ public CustomCarSerializer(final Class t) {
+ super(t);
+ }
+
+ @Override
+ public void serialize(final Car car, final JsonGenerator jsonGenerator, final SerializerProvider serializer) throws IOException, JsonProcessingException
+ {
+ jsonGenerator.writeStartObject();
+ jsonGenerator.writeStringField("model: ", car.getType());
+ jsonGenerator.writeEndObject();
+ }
+}
diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/TestJavaReadWriteJsonExample.java b/jackson/src/test/java/com/baeldung/jackson/objectmapper/TestJavaReadWriteJsonExample.java
new file mode 100644
index 0000000000..54ddf469c8
--- /dev/null
+++ b/jackson/src/test/java/com/baeldung/jackson/objectmapper/TestJavaReadWriteJsonExample.java
@@ -0,0 +1,68 @@
+package com.baeldung.jackson.objectmapper;
+
+import com.baeldung.jackson.objectmapper.dto.Car;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+public class TestJavaReadWriteJsonExample {
+ final String EXAMPLE_JSON = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
+ final String LOCAL_JSON = "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"BMW\" }]";
+
+ @Test
+ public void whenWriteJavaToJson_thanCorrect() throws Exception {
+ final ObjectMapper objectMapper = new ObjectMapper();
+ final Car car = new Car("yellow", "renault");
+ final String carAsString = objectMapper.writeValueAsString(car);
+ assertThat(carAsString, containsString("yellow"));
+ assertThat(carAsString, containsString("renault"));
+ }
+
+ @Test
+ public void whenReadJsonToJava_thanCorrect() throws Exception {
+ final ObjectMapper objectMapper = new ObjectMapper();
+ final Car car = objectMapper.readValue(EXAMPLE_JSON, Car.class);
+ assertNotNull(car);
+ assertThat(car.getColor(), containsString("Black"));
+ }
+
+ @Test
+ public void whenReadJsonToJsonNode_thanCorrect() throws Exception {
+ final ObjectMapper objectMapper = new ObjectMapper();
+ final JsonNode jsonNode = objectMapper.readTree(EXAMPLE_JSON);
+ assertNotNull(jsonNode);
+ assertThat(jsonNode.get("color").asText(), containsString("Black"));
+ }
+
+ @Test
+ public void whenReadJsonToList_thanCorrect() throws Exception {
+ final ObjectMapper objectMapper = new ObjectMapper();
+ final List listCar = objectMapper.readValue(LOCAL_JSON, new TypeReference>() {
+
+ });
+ for (final Car car : listCar) {
+ assertNotNull(car);
+ assertThat(car.getType(), equalTo("BMW"));
+ }
+ }
+
+ @Test
+ public void whenReadJsonToMap_thanCorrect() throws Exception {
+ final ObjectMapper objectMapper = new ObjectMapper();
+ final Map map = objectMapper.readValue(EXAMPLE_JSON, new TypeReference>() {
+ });
+ assertNotNull(map);
+ for (final String key : map.keySet()) {
+ assertNotNull(key);
+ }
+ }
+}
diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/TestSerializationDeserializationFeature.java b/jackson/src/test/java/com/baeldung/jackson/objectmapper/TestSerializationDeserializationFeature.java
new file mode 100644
index 0000000000..96918f4c28
--- /dev/null
+++ b/jackson/src/test/java/com/baeldung/jackson/objectmapper/TestSerializationDeserializationFeature.java
@@ -0,0 +1,84 @@
+package com.baeldung.jackson.objectmapper;
+
+import com.baeldung.jackson.objectmapper.dto.Car;
+import com.baeldung.jackson.objectmapper.dto.Request;
+import com.fasterxml.jackson.core.Version;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import org.junit.Test;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+public class TestSerializationDeserializationFeature {
+ final String EXAMPLE_JSON = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
+ final String JSON_CAR = "{ \"color\" : \"Black\", \"type\" : \"Fiat\", \"year\" : \"1970\" }";
+ final String JSON_ARRAY = "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"BMW\" }]";
+
+ @Test
+ public void whenFailOnUnkownPropertiesFalse_thanJsonReadCorrectly() throws Exception {
+
+ final ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ final Car car = objectMapper.readValue(JSON_CAR, Car.class);
+ final JsonNode jsonNodeRoot = objectMapper.readTree(JSON_CAR);
+ final JsonNode jsonNodeYear = jsonNodeRoot.get("year");
+ final String year = jsonNodeYear.asText();
+
+ assertNotNull(car);
+ assertThat(car.getColor(), equalTo("Black"));
+ assertThat(year, containsString("1970"));
+ }
+
+ @Test
+ public void whenCustomSerializerDeserializer_thanReadWriteCorrect() throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ final SimpleModule serializerModule = new SimpleModule("CustomSerializer", new Version(1, 0, 0, null, null, null));
+ serializerModule.addSerializer(Car.class, new CustomCarSerializer());
+ mapper.registerModule(serializerModule);
+ final Car car = new Car("yellow", "renault");
+ final String carJson = mapper.writeValueAsString(car);
+ assertThat(carJson, containsString("renault"));
+ assertThat(carJson, containsString("model"));
+
+ final SimpleModule deserializerModule = new SimpleModule("CustomCarDeserializer", new Version(1, 0, 0, null, null, null));
+ deserializerModule.addDeserializer(Car.class, new CustomCarDeserializer());
+ mapper.registerModule(deserializerModule);
+ final Car carResult = mapper.readValue(EXAMPLE_JSON, Car.class);
+ assertNotNull(carResult);
+ assertThat(carResult.getColor(), equalTo("Black"));
+ }
+
+ @Test
+ public void whenDateFormatSet_thanSerializedAsExpected() throws Exception {
+ final ObjectMapper objectMapper = new ObjectMapper();
+ final Car car = new Car("yellow", "renault");
+ final Request request = new Request();
+ request.setCar(car);
+ request.setDatePurchased(new Date());
+ final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm a z");
+ objectMapper.setDateFormat(df);
+ final String carAsString = objectMapper.writeValueAsString(request);
+ assertNotNull(carAsString);
+ assertThat(carAsString, containsString("datePurchased"));
+ }
+
+ @Test
+ public void whenUseJavaArrayForJsonArrayTrue_thanJsonReadAsArray() throws Exception {
+ final ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
+ final Car[] cars = objectMapper.readValue(JSON_ARRAY, Car[].class);
+ for (final Car car : cars) {
+ assertNotNull(car);
+ assertThat(car.getType(), equalTo("BMW"));
+ }
+ }
+}
diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java b/jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java
new file mode 100644
index 0000000000..bf4309439b
--- /dev/null
+++ b/jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java
@@ -0,0 +1,31 @@
+package com.baeldung.jackson.objectmapper.dto;
+
+public class Car {
+
+ private String color;
+ private String type;
+
+ public Car() {
+ }
+
+ public Car(final String color, final String type) {
+ this.color = color;
+ this.type = type;
+ }
+
+ public String getColor() {
+ return color;
+ }
+
+ public void setColor(final String color) {
+ this.color = color;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(final String type) {
+ this.type = type;
+ }
+}
diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java b/jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java
new file mode 100644
index 0000000000..2a4cce0fdd
--- /dev/null
+++ b/jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java
@@ -0,0 +1,24 @@
+package com.baeldung.jackson.objectmapper.dto;
+
+import java.util.Date;
+
+public class Request {
+ Car car;
+ Date datePurchased;
+
+ public Car getCar() {
+ return car;
+ }
+
+ public void setCar(final Car car) {
+ this.car = car;
+ }
+
+ public Date getDatePurchased() {
+ return datePurchased;
+ }
+
+ public void setDatePurchased(final Date datePurchased) {
+ this.datePurchased = datePurchased;
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java b/jackson/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java
index cb93f9cb03..b5624c566a 100644
--- a/jackson/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java
+++ b/jackson/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java
@@ -3,13 +3,22 @@ package com.baeldung.jackson.serialization;
import java.io.IOException;
import com.baeldung.jackson.dtos.Item;
-
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
-public class ItemSerializer extends JsonSerializer- {
+public class ItemSerializer extends StdSerializer
- {
+
+ private static final long serialVersionUID = 6739170890621978901L;
+
+ public ItemSerializer() {
+ this(null);
+ }
+
+ public ItemSerializer(final Class
- t) {
+ super(t);
+ }
@Override
public final void serialize(final Item value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException {
diff --git a/jackson/src/test/java/com/baeldung/jackson/serialization/ItemSerializerOnClass.java b/jackson/src/test/java/com/baeldung/jackson/serialization/ItemSerializerOnClass.java
index 79b450d7f1..1fdf44e17c 100644
--- a/jackson/src/test/java/com/baeldung/jackson/serialization/ItemSerializerOnClass.java
+++ b/jackson/src/test/java/com/baeldung/jackson/serialization/ItemSerializerOnClass.java
@@ -3,13 +3,22 @@ package com.baeldung.jackson.serialization;
import java.io.IOException;
import com.baeldung.jackson.dtos.ItemWithSerializer;
-
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
-public class ItemSerializerOnClass extends JsonSerializer
{
+public class ItemSerializerOnClass extends StdSerializer {
+
+ private static final long serialVersionUID = -1760959597313610409L;
+
+ public ItemSerializerOnClass() {
+ this(null);
+ }
+
+ public ItemSerializerOnClass(final Class t) {
+ super(t);
+ }
@Override
public final void serialize(final ItemWithSerializer value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException {
diff --git a/jackson/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java b/jackson/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java
index e915378498..d0b2d7f5e9 100644
--- a/jackson/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java
+++ b/jackson/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java
@@ -4,10 +4,20 @@ import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
-public class MyDtoNullKeySerializer extends JsonSerializer {
+public class MyDtoNullKeySerializer extends StdSerializer {
+
+ private static final long serialVersionUID = -4478531309177369056L;
+
+ public MyDtoNullKeySerializer() {
+ this(null);
+ }
+
+ public MyDtoNullKeySerializer(final Class t) {
+ super(t);
+ }
@Override
public void serialize(final Object value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException {
diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonAnnotationTest.java b/jackson/src/test/java/com/baeldung/jackson/test/JacksonAnnotationTest.java
index 74fbd021a0..d854d89b5f 100644
--- a/jackson/src/test/java/com/baeldung/jackson/test/JacksonAnnotationTest.java
+++ b/jackson/src/test/java/com/baeldung/jackson/test/JacksonAnnotationTest.java
@@ -12,11 +12,8 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
-import com.baeldung.jackson.bidirection.ItemWithIdentity;
-import com.baeldung.jackson.bidirection.ItemWithRef;
-import com.baeldung.jackson.bidirection.UserWithRef;
-import com.baeldung.jackson.dtos.User;
-import com.baeldung.jackson.dtos.withEnum.TypeEnumWithValue;
+import org.junit.Test;
+
import com.baeldung.jackson.annotation.BeanWithCreator;
import com.baeldung.jackson.annotation.BeanWithCustomAnnotation;
import com.baeldung.jackson.annotation.BeanWithFilter;
@@ -30,16 +27,17 @@ import com.baeldung.jackson.annotation.RawBean;
import com.baeldung.jackson.annotation.UnwrappedUser;
import com.baeldung.jackson.annotation.UserWithIgnoreType;
import com.baeldung.jackson.annotation.Zoo;
+import com.baeldung.jackson.bidirection.ItemWithIdentity;
+import com.baeldung.jackson.bidirection.ItemWithRef;
import com.baeldung.jackson.bidirection.UserWithIdentity;
+import com.baeldung.jackson.bidirection.UserWithRef;
import com.baeldung.jackson.date.EventWithFormat;
import com.baeldung.jackson.date.EventWithSerializer;
-import com.baeldung.jackson.dtos.MyMixInForString;
+import com.baeldung.jackson.dtos.MyMixInForIgnoreType;
+import com.baeldung.jackson.dtos.withEnum.TypeEnumWithValue;
import com.baeldung.jackson.exception.UserWithRoot;
import com.baeldung.jackson.jsonview.Item;
import com.baeldung.jackson.jsonview.Views;
-import org.junit.Ignore;
-import org.junit.Test;
-
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.InjectableValues;
@@ -127,7 +125,7 @@ public class JacksonAnnotationTest {
public void whenDeserializingUsingJsonCreator_thenCorrect() throws JsonProcessingException, IOException {
final String json = "{\"id\":1,\"theName\":\"My bean\"}";
- final BeanWithCreator bean = new ObjectMapper().reader(BeanWithCreator.class).readValue(json);
+ final BeanWithCreator bean = new ObjectMapper().readerFor(BeanWithCreator.class).readValue(json);
assertEquals("My bean", bean.name);
}
@@ -136,7 +134,7 @@ public class JacksonAnnotationTest {
final String json = "{\"name\":\"My bean\"}";
final InjectableValues inject = new InjectableValues.Std().addValue(int.class, 1);
- final BeanWithInject bean = new ObjectMapper().reader(inject).withType(BeanWithInject.class).readValue(json);
+ final BeanWithInject bean = new ObjectMapper().reader(inject).forType(BeanWithInject.class).readValue(json);
assertEquals("My bean", bean.name);
assertEquals(1, bean.id);
}
@@ -145,7 +143,7 @@ public class JacksonAnnotationTest {
public void whenDeserializingUsingJsonAnySetter_thenCorrect() throws JsonProcessingException, IOException {
final String json = "{\"name\":\"My bean\",\"attr2\":\"val2\",\"attr1\":\"val1\"}";
- final ExtendableBean bean = new ObjectMapper().reader(ExtendableBean.class).readValue(json);
+ final ExtendableBean bean = new ObjectMapper().readerFor(ExtendableBean.class).readValue(json);
assertEquals("My bean", bean.name);
assertEquals("val2", bean.getProperties().get("attr2"));
}
@@ -154,7 +152,7 @@ public class JacksonAnnotationTest {
public void whenDeserializingUsingJsonSetter_thenCorrect() throws JsonProcessingException, IOException {
final String json = "{\"id\":1,\"name\":\"My bean\"}";
- final BeanWithGetter bean = new ObjectMapper().reader(BeanWithGetter.class).readValue(json);
+ final BeanWithGetter bean = new ObjectMapper().readerFor(BeanWithGetter.class).readValue(json);
assertEquals("My bean", bean.getTheName());
}
@@ -164,7 +162,7 @@ public class JacksonAnnotationTest {
final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
- final EventWithSerializer event = new ObjectMapper().reader(EventWithSerializer.class).readValue(json);
+ final EventWithSerializer event = new ObjectMapper().readerFor(EventWithSerializer.class).readValue(json);
assertEquals("20-12-2014 02:30:00", df.format(event.eventDate));
}
@@ -235,7 +233,7 @@ public class JacksonAnnotationTest {
public void whenDeserializingPolymorphic_thenCorrect() throws JsonProcessingException, IOException {
final String json = "{\"animal\":{\"name\":\"lacy\",\"type\":\"cat\"}}";
- final Zoo zoo = new ObjectMapper().reader().withType(Zoo.class).readValue(json);
+ final Zoo zoo = new ObjectMapper().readerFor(Zoo.class).readValue(json);
assertEquals("lacy", zoo.animal.name);
assertEquals(Zoo.Cat.class, zoo.animal.getClass());
@@ -250,7 +248,7 @@ public class JacksonAnnotationTest {
assertThat(result, containsString("My bean"));
assertThat(result, containsString("1"));
- final BeanWithGetter resultBean = new ObjectMapper().reader(BeanWithGetter.class).readValue(result);
+ final BeanWithGetter resultBean = new ObjectMapper().readerFor(BeanWithGetter.class).readValue(result);
assertEquals("My bean", resultBean.getTheName());
}
@@ -338,19 +336,19 @@ public class JacksonAnnotationTest {
assertThat(result, not(containsString("dateCreated")));
}
- @Ignore("Jackson 2.7.1-1 seems to have changed the API regarding mixins")
+ // @Ignore("Jackson 2.7.1-1 seems to have changed the API regarding mixins")
@Test
public void whenSerializingUsingMixInAnnotation_thenCorrect() throws JsonProcessingException {
- final User user = new User(1, "John");
+ final com.baeldung.jackson.dtos.Item item = new com.baeldung.jackson.dtos.Item(1, "book", null);
- String result = new ObjectMapper().writeValueAsString(user);
- assertThat(result, containsString("John"));
+ String result = new ObjectMapper().writeValueAsString(item);
+ assertThat(result, containsString("owner"));
final ObjectMapper mapper = new ObjectMapper();
- mapper.addMixIn(String.class, MyMixInForString.class);
+ mapper.addMixIn(com.baeldung.jackson.dtos.User.class, MyMixInForIgnoreType.class);
- result = mapper.writeValueAsString(user);
- assertThat(result, not(containsString("John")));
+ result = mapper.writeValueAsString(item);
+ assertThat(result, not(containsString("owner")));
}
@Test
diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonBidirectionRelationTest.java b/jackson/src/test/java/com/baeldung/jackson/test/JacksonBidirectionRelationTest.java
index 971b40406a..db8507a4b0 100644
--- a/jackson/src/test/java/com/baeldung/jackson/test/JacksonBidirectionRelationTest.java
+++ b/jackson/src/test/java/com/baeldung/jackson/test/JacksonBidirectionRelationTest.java
@@ -7,6 +7,8 @@ import static org.junit.Assert.assertThat;
import java.io.IOException;
+import org.junit.Test;
+
import com.baeldung.jackson.bidirection.Item;
import com.baeldung.jackson.bidirection.ItemWithIdentity;
import com.baeldung.jackson.bidirection.ItemWithIgnore;
@@ -20,8 +22,6 @@ import com.baeldung.jackson.bidirection.UserWithRef;
import com.baeldung.jackson.bidirection.UserWithSerializer;
import com.baeldung.jackson.bidirection.UserWithView;
import com.baeldung.jackson.jsonview.Views;
-import org.junit.Test;
-
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -93,7 +93,7 @@ public class JacksonBidirectionRelationTest {
public void givenBidirectionRelation_whenDeserializingUsingIdentity_thenCorrect() throws JsonProcessingException, IOException {
final String json = "{\"id\":2,\"itemName\":\"book\",\"owner\":{\"id\":1,\"name\":\"John\",\"userItems\":[2]}}";
- final ItemWithIdentity item = new ObjectMapper().reader(ItemWithIdentity.class).readValue(json);
+ final ItemWithIdentity item = new ObjectMapper().readerFor(ItemWithIdentity.class).readValue(json);
assertEquals(2, item.id);
assertEquals("book", item.itemName);
@@ -104,7 +104,7 @@ public class JacksonBidirectionRelationTest {
public void givenBidirectionRelation_whenUsingCustomDeserializer_thenCorrect() throws JsonProcessingException, IOException {
final String json = "{\"id\":2,\"itemName\":\"book\",\"owner\":{\"id\":1,\"name\":\"John\",\"userItems\":[2]}}";
- final ItemWithSerializer item = new ObjectMapper().reader(ItemWithSerializer.class).readValue(json);
+ final ItemWithSerializer item = new ObjectMapper().readerFor(ItemWithSerializer.class).readValue(json);
assertEquals(2, item.id);
assertEquals("book", item.itemName);
assertEquals("John", item.owner.name);
diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonDateTest.java b/jackson/src/test/java/com/baeldung/jackson/test/JacksonDateTest.java
index 50ec50b668..d8357f8500 100644
--- a/jackson/src/test/java/com/baeldung/jackson/test/JacksonDateTest.java
+++ b/jackson/src/test/java/com/baeldung/jackson/test/JacksonDateTest.java
@@ -11,15 +11,15 @@ import java.time.LocalDateTime;
import java.util.Date;
import java.util.TimeZone;
-import com.baeldung.jackson.date.EventWithLocalDateTime;
-import com.baeldung.jackson.date.Event;
-import com.baeldung.jackson.date.EventWithFormat;
-import com.baeldung.jackson.date.EventWithJodaTime;
-import com.baeldung.jackson.date.EventWithSerializer;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.junit.Test;
+import com.baeldung.jackson.date.Event;
+import com.baeldung.jackson.date.EventWithFormat;
+import com.baeldung.jackson.date.EventWithJodaTime;
+import com.baeldung.jackson.date.EventWithLocalDateTime;
+import com.baeldung.jackson.date.EventWithSerializer;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
@@ -128,7 +128,7 @@ public class JacksonDateTest {
final ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(df);
- final Event event = mapper.reader(Event.class).readValue(json);
+ final Event event = mapper.readerFor(Event.class).readValue(json);
assertEquals("20-12-2014 02:30:00", df.format(event.eventDate));
}
@@ -139,7 +139,7 @@ public class JacksonDateTest {
final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
final ObjectMapper mapper = new ObjectMapper();
- final EventWithSerializer event = mapper.reader(EventWithSerializer.class).readValue(json);
+ final EventWithSerializer event = mapper.readerFor(EventWithSerializer.class).readValue(json);
assertEquals("20-12-2014 02:30:00", df.format(event.eventDate));
}
diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonExceptionsTest.java b/jackson/src/test/java/com/baeldung/jackson/test/JacksonExceptionsTest.java
index 90317848ce..d9b8d1cc18 100644
--- a/jackson/src/test/java/com/baeldung/jackson/test/JacksonExceptionsTest.java
+++ b/jackson/src/test/java/com/baeldung/jackson/test/JacksonExceptionsTest.java
@@ -7,9 +7,13 @@ import static org.junit.Assert.assertThat;
import java.io.IOException;
import java.util.List;
-import com.baeldung.jackson.exception.*;
import org.junit.Test;
+import com.baeldung.jackson.exception.User;
+import com.baeldung.jackson.exception.UserWithPrivateFields;
+import com.baeldung.jackson.exception.UserWithRoot;
+import com.baeldung.jackson.exception.Zoo;
+import com.baeldung.jackson.exception.ZooConfigured;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonFactory;
@@ -30,7 +34,7 @@ public class JacksonExceptionsTest {
final String json = "{\"animal\":{\"name\":\"lacy\"}}";
final ObjectMapper mapper = new ObjectMapper();
- mapper.reader().withType(Zoo.class).readValue(json);
+ mapper.reader().forType(Zoo.class).readValue(json);
}
@Test
@@ -38,7 +42,7 @@ public class JacksonExceptionsTest {
final String json = "{\"animal\":{\"name\":\"lacy\"}}";
final ObjectMapper mapper = new ObjectMapper();
- mapper.reader().withType(ZooConfigured.class).readValue(json);
+ mapper.reader().forType(ZooConfigured.class).readValue(json);
}
// JsonMappingException: No serializer found for class
@@ -67,7 +71,7 @@ public class JacksonExceptionsTest {
final String json = "{\"id\":1,\"name\":\"John\"}";
final ObjectMapper mapper = new ObjectMapper();
- mapper.reader().withType(User.class).readValue(json);
+ mapper.reader().forType(User.class).readValue(json);
}
@Test
@@ -75,7 +79,7 @@ public class JacksonExceptionsTest {
final String json = "{\"id\":1,\"name\":\"John\"}";
final ObjectMapper mapper = new ObjectMapper();
- final com.baeldung.jackson.dtos.User user = mapper.reader().withType(com.baeldung.jackson.dtos.User.class).readValue(json);
+ final com.baeldung.jackson.dtos.User user = mapper.reader().forType(com.baeldung.jackson.dtos.User.class).readValue(json);
assertEquals("John", user.name);
}
@@ -87,7 +91,7 @@ public class JacksonExceptionsTest {
final ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
- mapper.reader().withType(com.baeldung.jackson.dtos.User.class).readValue(json);
+ mapper.reader().forType(com.baeldung.jackson.dtos.User.class).readValue(json);
}
@Test
@@ -97,7 +101,7 @@ public class JacksonExceptionsTest {
final ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
- final UserWithRoot user = mapper.reader().withType(UserWithRoot.class).readValue(json);
+ final UserWithRoot user = mapper.reader().forType(UserWithRoot.class).readValue(json);
assertEquals("John", user.name);
}
@@ -107,7 +111,7 @@ public class JacksonExceptionsTest {
final String json = "[{\"id\":1,\"name\":\"John\"},{\"id\":2,\"name\":\"Adam\"}]";
final ObjectMapper mapper = new ObjectMapper();
- mapper.reader().withType(com.baeldung.jackson.dtos.User.class).readValue(json);
+ mapper.reader().forType(com.baeldung.jackson.dtos.User.class).readValue(json);
}
@Test
@@ -115,7 +119,7 @@ public class JacksonExceptionsTest {
final String json = "[{\"id\":1,\"name\":\"John\"},{\"id\":2,\"name\":\"Adam\"}]";
final ObjectMapper mapper = new ObjectMapper();
- final List users = mapper.reader().withType(new TypeReference>() {
+ final List users = mapper.reader().forType(new TypeReference>() {
}).readValue(json);
assertEquals(2, users.size());
@@ -127,7 +131,7 @@ public class JacksonExceptionsTest {
final String json = "{\"id\":1,\"name\":\"John\", \"checked\":true}";
final ObjectMapper mapper = new ObjectMapper();
- mapper.reader().withType(com.baeldung.jackson.dtos.User.class).readValue(json);
+ mapper.reader().forType(com.baeldung.jackson.dtos.User.class).readValue(json);
}
@Test
@@ -137,7 +141,7 @@ public class JacksonExceptionsTest {
final ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
- final com.baeldung.jackson.dtos.User user = mapper.reader().withType(com.baeldung.jackson.dtos.User.class).readValue(json);
+ final com.baeldung.jackson.dtos.User user = mapper.reader().forType(com.baeldung.jackson.dtos.User.class).readValue(json);
assertEquals("John", user.name);
}
@@ -147,7 +151,7 @@ public class JacksonExceptionsTest {
final String json = "{'id':1,'name':'John'}";
final ObjectMapper mapper = new ObjectMapper();
- mapper.reader().withType(com.baeldung.jackson.dtos.User.class).readValue(json);
+ mapper.reader().forType(com.baeldung.jackson.dtos.User.class).readValue(json);
}
@Test
@@ -158,7 +162,7 @@ public class JacksonExceptionsTest {
factory.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
final ObjectMapper mapper = new ObjectMapper(factory);
- final com.baeldung.jackson.dtos.User user = mapper.reader().withType(com.baeldung.jackson.dtos.User.class).readValue(json);
+ final com.baeldung.jackson.dtos.User user = mapper.reader().forType(com.baeldung.jackson.dtos.User.class).readValue(json);
assertEquals("John", user.name);
}
diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonJsonViewTest.java b/jackson/src/test/java/com/baeldung/jackson/test/JacksonJsonViewTest.java
index 61fa2919ac..477b0132e2 100644
--- a/jackson/src/test/java/com/baeldung/jackson/test/JacksonJsonViewTest.java
+++ b/jackson/src/test/java/com/baeldung/jackson/test/JacksonJsonViewTest.java
@@ -7,12 +7,12 @@ import static org.junit.Assert.assertThat;
import java.io.IOException;
-import com.baeldung.jackson.jsonview.Item;
-import com.baeldung.jackson.jsonview.User;
-import com.baeldung.jackson.jsonview.MyBeanSerializerModifier;
-import com.baeldung.jackson.jsonview.Views;
import org.junit.Test;
+import com.baeldung.jackson.jsonview.Item;
+import com.baeldung.jackson.jsonview.MyBeanSerializerModifier;
+import com.baeldung.jackson.jsonview.User;
+import com.baeldung.jackson.jsonview.Views;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -66,7 +66,7 @@ public class JacksonJsonViewTest {
final ObjectMapper mapper = new ObjectMapper();
- final User user = mapper.readerWithView(Views.Public.class).withType(User.class).readValue(json);
+ final User user = mapper.readerWithView(Views.Public.class).forType(User.class).readValue(json);
assertEquals(1, user.getId());
assertEquals("John", user.getName());
}
diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java b/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java
index 4c01ec9333..71499b8a24 100644
--- a/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java
+++ b/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java
@@ -8,17 +8,17 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
-import com.baeldung.jackson.dtos.MyDtoIncludeNonDefault;
-import com.baeldung.jackson.dtos.MyDtoWithFilter;
-import com.baeldung.jackson.dtos.ignore.MyDtoIgnoreNull;
-import com.baeldung.jackson.dtos.MyDto;
-import com.baeldung.jackson.dtos.MyMixInForString;
-import com.baeldung.jackson.dtos.ignore.MyDtoIgnoreField;
-import com.baeldung.jackson.dtos.ignore.MyDtoIgnoreFieldByName;
-import com.baeldung.jackson.serialization.MyDtoNullKeySerializer;
-import org.junit.Ignore;
import org.junit.Test;
+import com.baeldung.jackson.dtos.MyDto;
+import com.baeldung.jackson.dtos.MyDtoIncludeNonDefault;
+import com.baeldung.jackson.dtos.MyDtoWithFilter;
+import com.baeldung.jackson.dtos.MyDtoWithSpecialField;
+import com.baeldung.jackson.dtos.MyMixInForIgnoreType;
+import com.baeldung.jackson.dtos.ignore.MyDtoIgnoreField;
+import com.baeldung.jackson.dtos.ignore.MyDtoIgnoreFieldByName;
+import com.baeldung.jackson.dtos.ignore.MyDtoIgnoreNull;
+import com.baeldung.jackson.serialization.MyDtoNullKeySerializer;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException;
@@ -85,12 +85,12 @@ public class JacksonSerializationIgnoreUnitTest {
System.out.println(dtoAsString);
}
- @Ignore("Jackson 2.7.1-1 seems to have changed the API for this case")
+ // @Ignore("Jackson 2.7.1-1 seems to have changed the API for this case")
@Test
public final void givenFieldTypeIsIgnored_whenDtoIsSerialized_thenCorrect() throws JsonParseException, IOException {
final ObjectMapper mapper = new ObjectMapper();
- mapper.addMixIn(String.class, MyMixInForString.class);
- final MyDto dtoObject = new MyDto();
+ mapper.addMixIn(String[].class, MyMixInForIgnoreType.class);
+ final MyDtoWithSpecialField dtoObject = new MyDtoWithSpecialField();
dtoObject.setBooleanValue(true);
final String dtoAsString = mapper.writeValueAsString(dtoObject);
diff --git a/jackson/src/test/java/com/baeldung/jackson/try1/RestLoaderRequestDeserializer.java b/jackson/src/test/java/com/baeldung/jackson/try1/RestLoaderRequestDeserializer.java
index 849607586d..529c05ddcc 100644
--- a/jackson/src/test/java/com/baeldung/jackson/try1/RestLoaderRequestDeserializer.java
+++ b/jackson/src/test/java/com/baeldung/jackson/try1/RestLoaderRequestDeserializer.java
@@ -6,10 +6,19 @@ import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
-public class RestLoaderRequestDeserializer extends JsonDeserializer> {
+public class RestLoaderRequestDeserializer extends StdDeserializer> {
+ private static final long serialVersionUID = -4245207329377196889L;
+
+ public RestLoaderRequestDeserializer() {
+ this(null);
+ }
+
+ public RestLoaderRequestDeserializer(final Class> vc) {
+ super(vc);
+ }
@Override
public RestLoaderRequest deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
diff --git a/jjwt/.gitignore b/jjwt/.gitignore
new file mode 100644
index 0000000000..f83e8cf07c
--- /dev/null
+++ b/jjwt/.gitignore
@@ -0,0 +1,3 @@
+.idea
+target
+*.iml
diff --git a/jjwt/README.md b/jjwt/README.md
new file mode 100644
index 0000000000..47b51038a8
--- /dev/null
+++ b/jjwt/README.md
@@ -0,0 +1,45 @@
+## JWT Fun
+
+This tutorial walks you through the various features supported by the [JJWT](https://github.com/jwtk/jjwt) library - a fluent interface Java JWT building and parsing library.
+
+### Build and Run
+
+It's super easy to build and exercise this tutorial.
+
+```
+mvn clean install
+java -jar target/*.jar
+```
+
+That's it!
+
+You can hit the home endpoint with your favorite command-line http client. My favorite is: [httpie](https://github.com/jkbrzt/httpie)
+
+`http localhost:8080`
+
+```
+Available commands (assumes httpie - https://github.com/jkbrzt/httpie):
+
+ http http://localhost:8080/
+ This usage message
+
+ http http://localhost:8080/static-builder
+ build JWT from hardcoded claims
+
+ http POST http://localhost:8080/dynamic-builder-general claim-1=value-1 ... [claim-n=value-n]
+ build JWT from passed in claims (using general claims map)
+
+ http POST http://localhost:8080/dynamic-builder-specific claim-1=value-1 ... [claim-n=value-n]
+ build JWT from passed in claims (using specific claims methods)
+
+ http POST http://localhost:8080/dynamic-builder-compress claim-1=value-1 ... [claim-n=value-n]
+ build DEFLATE compressed JWT from passed in claims
+
+ http http://localhost:8080/parser?jwt=
+ Parse passed in JWT
+
+ http http://localhost:8080/parser-enforce?jwt=
+ Parse passed in JWT enforcing the 'iss' registered claim and the 'hasMotorcycle' custom claim
+```
+
+The Baeldung post that compliments this repo can be found [here](http://www.baeldung.com/)
\ No newline at end of file
diff --git a/jjwt/pom.xml b/jjwt/pom.xml
new file mode 100644
index 0000000000..24f1c5c5ab
--- /dev/null
+++ b/jjwt/pom.xml
@@ -0,0 +1,65 @@
+
+
+ 4.0.0
+
+ io.jsonwebtoken
+ jjwtfun
+ 0.0.1-SNAPSHOT
+ jar
+
+ jjwtfun
+ Exercising the JJWT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.3.5.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ io.jsonwebtoken
+ jjwt
+ 0.6.0
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/JJWTFunApplication.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/JJWTFunApplication.java
new file mode 100644
index 0000000000..5c106aac70
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/JJWTFunApplication.java
@@ -0,0 +1,12 @@
+package io.jsonwebtoken.jjwtfun;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class JJWTFunApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(JJWTFunApplication.class, args);
+ }
+}
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/CSRFConfig.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/CSRFConfig.java
new file mode 100644
index 0000000000..7d88835243
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/CSRFConfig.java
@@ -0,0 +1,21 @@
+package io.jsonwebtoken.jjwtfun.config;
+
+import io.jsonwebtoken.jjwtfun.service.SecretService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.web.csrf.CsrfTokenRepository;
+
+@Configuration
+public class CSRFConfig {
+
+ @Autowired
+ SecretService secretService;
+
+ @Bean
+ @ConditionalOnMissingBean
+ public CsrfTokenRepository jwtCsrfTokenRepository() {
+ return new JWTCsrfTokenRepository(secretService.getHS256SecretBytes());
+ }
+}
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/JWTCsrfTokenRepository.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/JWTCsrfTokenRepository.java
new file mode 100644
index 0000000000..bf88b8aff1
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/JWTCsrfTokenRepository.java
@@ -0,0 +1,68 @@
+package io.jsonwebtoken.jjwtfun.config;
+
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.web.csrf.CsrfToken;
+import org.springframework.security.web.csrf.CsrfTokenRepository;
+import org.springframework.security.web.csrf.DefaultCsrfToken;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.util.Date;
+import java.util.UUID;
+
+public class JWTCsrfTokenRepository implements CsrfTokenRepository {
+
+ private static final String DEFAULT_CSRF_TOKEN_ATTR_NAME = CSRFConfig.class.getName().concat(".CSRF_TOKEN");
+
+ private static final Logger log = LoggerFactory.getLogger(JWTCsrfTokenRepository.class);
+ private byte[] secret;
+
+ public JWTCsrfTokenRepository(byte[] secret) {
+ this.secret = secret;
+ }
+
+ @Override
+ public CsrfToken generateToken(HttpServletRequest request) {
+ String id = UUID.randomUUID().toString().replace("-", "");
+
+ Date now = new Date();
+ Date exp = new Date(System.currentTimeMillis() + (1000*30)); // 30 seconds
+
+ String token = Jwts.builder()
+ .setId(id)
+ .setIssuedAt(now)
+ .setNotBefore(now)
+ .setExpiration(exp)
+ .signWith(SignatureAlgorithm.HS256, secret)
+ .compact();
+
+ return new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", token);
+ }
+
+ @Override
+ public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response) {
+ if (token == null) {
+ HttpSession session = request.getSession(false);
+ if (session != null) {
+ session.removeAttribute(DEFAULT_CSRF_TOKEN_ATTR_NAME);
+ }
+ }
+ else {
+ HttpSession session = request.getSession();
+ session.setAttribute(DEFAULT_CSRF_TOKEN_ATTR_NAME, token);
+ }
+ }
+
+ @Override
+ public CsrfToken loadToken(HttpServletRequest request) {
+ HttpSession session = request.getSession(false);
+ if (session == null || "GET".equals(request.getMethod())) {
+ return null;
+ }
+ return (CsrfToken) session.getAttribute(DEFAULT_CSRF_TOKEN_ATTR_NAME);
+ }
+}
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/WebSecurityConfig.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/WebSecurityConfig.java
new file mode 100644
index 0000000000..94e2c6ddc5
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/WebSecurityConfig.java
@@ -0,0 +1,85 @@
+package io.jsonwebtoken.jjwtfun.config;
+
+import io.jsonwebtoken.JwtException;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.jjwtfun.service.SecretService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.web.csrf.CsrfFilter;
+import org.springframework.security.web.csrf.CsrfToken;
+import org.springframework.security.web.csrf.CsrfTokenRepository;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Arrays;
+
+@Configuration
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Autowired
+ CsrfTokenRepository jwtCsrfTokenRepository;
+
+ @Autowired
+ SecretService secretService;
+
+ // ordered so we can use binary search below
+ private String[] ignoreCsrfAntMatchers = {
+ "/dynamic-builder-compress",
+ "/dynamic-builder-general",
+ "/dynamic-builder-specific",
+ "/set-secrets"
+ };
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .addFilterAfter(new JwtCsrfValidatorFilter(), CsrfFilter.class)
+ .csrf()
+ .csrfTokenRepository(jwtCsrfTokenRepository)
+ .ignoringAntMatchers(ignoreCsrfAntMatchers)
+ .and().authorizeRequests()
+ .antMatchers("/**")
+ .permitAll();
+ }
+
+ private class JwtCsrfValidatorFilter extends OncePerRequestFilter {
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
+ // NOTE: A real implementation should have a nonce cache so the token cannot be reused
+
+ CsrfToken token = (CsrfToken) request.getAttribute("_csrf");
+
+ if (
+ // only care if it's a POST
+ "POST".equals(request.getMethod()) &&
+ // ignore if the request path is in our list
+ Arrays.binarySearch(ignoreCsrfAntMatchers, request.getServletPath()) < 0 &&
+ // make sure we have a token
+ token != null
+ ) {
+ // CsrfFilter already made sure the token matched. Here, we'll make sure it's not expired
+ try {
+ Jwts.parser()
+ .setSigningKeyResolver(secretService.getSigningKeyResolver())
+ .parseClaimsJws(token.getToken());
+ } catch (JwtException e) {
+ // most likely an ExpiredJwtException, but this will handle any
+ request.setAttribute("exception", e);
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("expired-jwt");
+ dispatcher.forward(request, response);
+ }
+ }
+
+ filterChain.doFilter(request, response);
+ }
+ }
+}
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/BaseController.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/BaseController.java
new file mode 100644
index 0000000000..e1e195c6ab
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/BaseController.java
@@ -0,0 +1,23 @@
+package io.jsonwebtoken.jjwtfun.controller;
+
+import io.jsonwebtoken.JwtException;
+import io.jsonwebtoken.MalformedJwtException;
+import io.jsonwebtoken.SignatureException;
+import io.jsonwebtoken.jjwtfun.model.JwtResponse;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+public class BaseController {
+
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ @ExceptionHandler({SignatureException.class, MalformedJwtException.class, JwtException.class})
+ public JwtResponse exception(Exception e) {
+ JwtResponse response = new JwtResponse();
+ response.setStatus(JwtResponse.Status.ERROR);
+ response.setMessage(e.getMessage());
+ response.setExceptionType(e.getClass().getName());
+
+ return response;
+ }
+}
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/DynamicJWTController.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/DynamicJWTController.java
new file mode 100644
index 0000000000..c03c63dd80
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/DynamicJWTController.java
@@ -0,0 +1,108 @@
+package io.jsonwebtoken.jjwtfun.controller;
+
+import io.jsonwebtoken.JwtBuilder;
+import io.jsonwebtoken.JwtException;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.impl.compression.CompressionCodecs;
+import io.jsonwebtoken.jjwtfun.model.JwtResponse;
+import io.jsonwebtoken.jjwtfun.service.SecretService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.UnsupportedEncodingException;
+import java.time.Instant;
+import java.util.Date;
+import java.util.Map;
+
+import static org.springframework.web.bind.annotation.RequestMethod.POST;
+
+@RestController
+public class DynamicJWTController extends BaseController {
+
+ @Autowired
+ SecretService secretService;
+
+ @RequestMapping(value = "/dynamic-builder-general", method = POST)
+ public JwtResponse dynamicBuilderGeneric(@RequestBody Map claims) throws UnsupportedEncodingException {
+ String jws = Jwts.builder()
+ .setClaims(claims)
+ .signWith(
+ SignatureAlgorithm.HS256,
+ secretService.getHS256SecretBytes()
+ )
+ .compact();
+ return new JwtResponse(jws);
+ }
+
+ @RequestMapping(value = "/dynamic-builder-compress", method = POST)
+ public JwtResponse dynamicBuildercompress(@RequestBody Map claims) throws UnsupportedEncodingException {
+ String jws = Jwts.builder()
+ .setClaims(claims)
+ .compressWith(CompressionCodecs.DEFLATE)
+ .signWith(
+ SignatureAlgorithm.HS256,
+ secretService.getHS256SecretBytes()
+ )
+ .compact();
+ return new JwtResponse(jws);
+ }
+
+ @RequestMapping(value = "/dynamic-builder-specific", method = POST)
+ public JwtResponse dynamicBuilderSpecific(@RequestBody Map claims) throws UnsupportedEncodingException {
+ JwtBuilder builder = Jwts.builder();
+
+ claims.forEach((key, value) -> {
+ switch (key) {
+ case "iss":
+ ensureType(key, value, String.class);
+ builder.setIssuer((String) value);
+ break;
+ case "sub":
+ ensureType(key, value, String.class);
+ builder.setSubject((String) value);
+ break;
+ case "aud":
+ ensureType(key, value, String.class);
+ builder.setAudience((String) value);
+ break;
+ case "exp":
+ ensureType(key, value, Long.class);
+ builder.setExpiration(Date.from(Instant.ofEpochSecond(Long.parseLong(value.toString()))));
+ break;
+ case "nbf":
+ ensureType(key, value, Long.class);
+ builder.setNotBefore(Date.from(Instant.ofEpochSecond(Long.parseLong(value.toString()))));
+ break;
+ case "iat":
+ ensureType(key, value, Long.class);
+ builder.setIssuedAt(Date.from(Instant.ofEpochSecond(Long.parseLong(value.toString()))));
+ break;
+ case "jti":
+ ensureType(key, value, String.class);
+ builder.setId((String) value);
+ break;
+ default:
+ builder.claim(key, value);
+ }
+ });
+
+ builder.signWith(SignatureAlgorithm.HS256, secretService.getHS256SecretBytes());
+
+ return new JwtResponse(builder.compact());
+ }
+
+ private void ensureType(String registeredClaim, Object value, Class expectedType) {
+ boolean isCorrectType =
+ expectedType.isInstance(value) ||
+ expectedType == Long.class && value instanceof Integer;
+
+ if (!isCorrectType) {
+ String msg = "Expected type: " + expectedType.getCanonicalName() + " for registered claim: '" +
+ registeredClaim + "', but got value: " + value + " of type: " + value.getClass().getCanonicalName();
+ throw new JwtException(msg);
+ }
+ }
+}
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/FormController.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/FormController.java
new file mode 100644
index 0000000000..54123c63cb
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/FormController.java
@@ -0,0 +1,29 @@
+package io.jsonwebtoken.jjwtfun.controller;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import static org.springframework.web.bind.annotation.RequestMethod.GET;
+import static org.springframework.web.bind.annotation.RequestMethod.POST;
+
+@Controller
+public class FormController {
+
+ @RequestMapping(value = "/jwt-csrf-form", method = GET)
+ public String csrfFormGet() {
+ return "jwt-csrf-form";
+ }
+
+ @RequestMapping(value = "/jwt-csrf-form", method = POST)
+ public String csrfFormPost(@RequestParam(name = "_csrf") String csrf, Model model) {
+ model.addAttribute("csrf", csrf);
+ return "jwt-csrf-form-result";
+ }
+
+ @RequestMapping("/expired-jwt")
+ public String expiredJwt() {
+ return "expired-jwt";
+ }
+}
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/HomeController.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/HomeController.java
new file mode 100644
index 0000000000..57cd14385e
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/HomeController.java
@@ -0,0 +1,32 @@
+package io.jsonwebtoken.jjwtfun.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+public class HomeController {
+
+ @RequestMapping("/")
+ public String home(HttpServletRequest req) {
+ String requestUrl = getUrl(req);
+ return "Available commands (assumes httpie - https://github.com/jkbrzt/httpie):\n\n" +
+ " http " + requestUrl + "/\n\tThis usage message\n\n" +
+ " http " + requestUrl + "/static-builder\n\tbuild JWT from hardcoded claims\n\n" +
+ " http POST " + requestUrl + "/dynamic-builder-general claim-1=value-1 ... [claim-n=value-n]\n\tbuild JWT from passed in claims (using general claims map)\n\n" +
+ " http POST " + requestUrl + "/dynamic-builder-specific claim-1=value-1 ... [claim-n=value-n]\n\tbuild JWT from passed in claims (using specific claims methods)\n\n" +
+ " http POST " + requestUrl + "/dynamic-builder-compress claim-1=value-1 ... [claim-n=value-n]\n\tbuild DEFLATE compressed JWT from passed in claims\n\n" +
+ " http " + requestUrl + "/parser?jwt=\n\tParse passed in JWT\n\n" +
+ " http " + requestUrl + "/parser-enforce?jwt=\n\tParse passed in JWT enforcing the 'iss' registered claim and the 'hasMotorcycle' custom claim\n\n" +
+ " http " + requestUrl + "/get-secrets\n\tShow the signing keys currently in use.\n\n" +
+ " http " + requestUrl + "/refresh-secrets\n\tGenerate new signing keys and show them.\n\n" +
+ " http POST " + requestUrl + "/set-secrets HS256=base64-encoded-value HS384=base64-encoded-value HS512=base64-encoded-value\n\tExplicitly set secrets to use in the application.";
+ }
+
+ private String getUrl(HttpServletRequest req) {
+ return req.getScheme() + "://" +
+ req.getServerName() +
+ ((req.getServerPort() == 80 || req.getServerPort() == 443) ? "" : ":" + req.getServerPort());
+ }
+}
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/SecretsController.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/SecretsController.java
new file mode 100644
index 0000000000..1ca0973c33
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/SecretsController.java
@@ -0,0 +1,35 @@
+package io.jsonwebtoken.jjwtfun.controller;
+
+import io.jsonwebtoken.jjwtfun.service.SecretService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+import static org.springframework.web.bind.annotation.RequestMethod.GET;
+import static org.springframework.web.bind.annotation.RequestMethod.POST;
+
+@RestController
+public class SecretsController extends BaseController {
+
+ @Autowired
+ SecretService secretService;
+
+ @RequestMapping(value = "/get-secrets", method = GET)
+ public Map getSecrets() {
+ return secretService.getSecrets();
+ }
+
+ @RequestMapping(value = "/refresh-secrets", method = GET)
+ public Map refreshSecrets() {
+ return secretService.refreshSecrets();
+ }
+
+ @RequestMapping(value = "/set-secrets", method = POST)
+ public Map setSecrets(@RequestBody Map secrets) {
+ secretService.setSecrets(secrets);
+ return secretService.getSecrets();
+ }
+}
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/StaticJWTController.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/StaticJWTController.java
new file mode 100644
index 0000000000..83f5336978
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/StaticJWTController.java
@@ -0,0 +1,64 @@
+package io.jsonwebtoken.jjwtfun.controller;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jws;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.jjwtfun.model.JwtResponse;
+import io.jsonwebtoken.jjwtfun.service.SecretService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.UnsupportedEncodingException;
+import java.time.Instant;
+import java.util.Date;
+
+import static org.springframework.web.bind.annotation.RequestMethod.GET;
+
+@RestController
+public class StaticJWTController extends BaseController {
+
+ @Autowired
+ SecretService secretService;
+
+ @RequestMapping(value = "/static-builder", method = GET)
+ public JwtResponse fixedBuilder() throws UnsupportedEncodingException {
+ String jws = Jwts.builder()
+ .setIssuer("Stormpath")
+ .setSubject("msilverman")
+ .claim("name", "Micah Silverman")
+ .claim("scope", "admins")
+ .setIssuedAt(Date.from(Instant.ofEpochSecond(1466796822L))) // Fri Jun 24 2016 15:33:42 GMT-0400 (EDT)
+ .setExpiration(Date.from(Instant.ofEpochSecond(4622470422L))) // Sat Jun 24 2116 15:33:42 GMT-0400 (EDT)
+ .signWith(
+ SignatureAlgorithm.HS256,
+ secretService.getHS256SecretBytes()
+ )
+ .compact();
+
+ return new JwtResponse(jws);
+ }
+
+ @RequestMapping(value = "/parser", method = GET)
+ public JwtResponse parser(@RequestParam String jwt) throws UnsupportedEncodingException {
+
+ Jws jws = Jwts.parser()
+ .setSigningKeyResolver(secretService.getSigningKeyResolver())
+ .parseClaimsJws(jwt);
+
+ return new JwtResponse(jws);
+ }
+
+ @RequestMapping(value = "/parser-enforce", method = GET)
+ public JwtResponse parserEnforce(@RequestParam String jwt) throws UnsupportedEncodingException {
+ Jws jws = Jwts.parser()
+ .requireIssuer("Stormpath")
+ .require("hasMotorcycle", true)
+ .setSigningKeyResolver(secretService.getSigningKeyResolver())
+ .parseClaimsJws(jwt);
+
+ return new JwtResponse(jws);
+ }
+}
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/model/JwtResponse.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/model/JwtResponse.java
new file mode 100644
index 0000000000..491f003289
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/model/JwtResponse.java
@@ -0,0 +1,70 @@
+package io.jsonwebtoken.jjwtfun.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jws;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class JwtResponse {
+ private String message;
+ private Status status;
+ private String exceptionType;
+ private String jwt;
+ private Jws jws;
+
+ public enum Status {
+ SUCCESS, ERROR
+ }
+
+ public JwtResponse() {}
+
+ public JwtResponse(String jwt) {
+ this.jwt = jwt;
+ this.status = Status.SUCCESS;
+ }
+
+ public JwtResponse(Jws jws) {
+ this.jws = jws;
+ this.status = Status.SUCCESS;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public void setStatus(Status status) {
+ this.status = status;
+ }
+
+ public String getExceptionType() {
+ return exceptionType;
+ }
+
+ public void setExceptionType(String exceptionType) {
+ this.exceptionType = exceptionType;
+ }
+
+ public String getJwt() {
+ return jwt;
+ }
+
+ public void setJwt(String jwt) {
+ this.jwt = jwt;
+ }
+
+ public Jws getJws() {
+ return jws;
+ }
+
+ public void setJws(Jws jws) {
+ this.jws = jws;
+ }
+}
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/service/SecretService.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/service/SecretService.java
new file mode 100644
index 0000000000..4311afa592
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/service/SecretService.java
@@ -0,0 +1,74 @@
+package io.jsonwebtoken.jjwtfun.service;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.JwsHeader;
+import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.SigningKeyResolver;
+import io.jsonwebtoken.SigningKeyResolverAdapter;
+import io.jsonwebtoken.impl.TextCodec;
+import io.jsonwebtoken.impl.crypto.MacProvider;
+import io.jsonwebtoken.lang.Assert;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.crypto.SecretKey;
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+public class SecretService {
+
+ private Map secrets = new HashMap<>();
+
+ private SigningKeyResolver signingKeyResolver = new SigningKeyResolverAdapter() {
+ @Override
+ public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
+ return TextCodec.BASE64.decode(secrets.get(header.getAlgorithm()));
+ }
+ };
+
+ @PostConstruct
+ public void setup() {
+ refreshSecrets();
+ }
+
+ public SigningKeyResolver getSigningKeyResolver() {
+ return signingKeyResolver;
+ }
+
+ public Map getSecrets() {
+ return secrets;
+ }
+
+ public void setSecrets(Map secrets) {
+ Assert.notNull(secrets);
+ Assert.hasText(secrets.get(SignatureAlgorithm.HS256.getValue()));
+ Assert.hasText(secrets.get(SignatureAlgorithm.HS384.getValue()));
+ Assert.hasText(secrets.get(SignatureAlgorithm.HS512.getValue()));
+
+ this.secrets = secrets;
+ }
+
+ public byte[] getHS256SecretBytes() {
+ return TextCodec.BASE64.decode(secrets.get(SignatureAlgorithm.HS256.getValue()));
+ }
+
+ public byte[] getHS384SecretBytes() {
+ return TextCodec.BASE64.decode(secrets.get(SignatureAlgorithm.HS384.getValue()));
+ }
+
+ public byte[] getHS512SecretBytes() {
+ return TextCodec.BASE64.decode(secrets.get(SignatureAlgorithm.HS384.getValue()));
+ }
+
+
+ public Map refreshSecrets() {
+ SecretKey key = MacProvider.generateKey(SignatureAlgorithm.HS256);
+ secrets.put(SignatureAlgorithm.HS256.getValue(), TextCodec.BASE64.encode(key.getEncoded()));
+ key = MacProvider.generateKey(SignatureAlgorithm.HS384);
+ secrets.put(SignatureAlgorithm.HS384.getValue(), TextCodec.BASE64.encode(key.getEncoded()));
+ key = MacProvider.generateKey(SignatureAlgorithm.HS512);
+ secrets.put(SignatureAlgorithm.HS512.getValue(), TextCodec.BASE64.encode(key.getEncoded()));
+ return secrets;
+ }
+}
diff --git a/jjwt/src/main/resources/application.properties b/jjwt/src/main/resources/application.properties
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/jjwt/src/main/resources/templates/expired-jwt.html b/jjwt/src/main/resources/templates/expired-jwt.html
new file mode 100644
index 0000000000..7bf9ff258e
--- /dev/null
+++ b/jjwt/src/main/resources/templates/expired-jwt.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
JWT CSRF Token expired
+
+
+
Back
+
+
+
+
+
\ No newline at end of file
diff --git a/jjwt/src/main/resources/templates/fragments/head.html b/jjwt/src/main/resources/templates/fragments/head.html
new file mode 100644
index 0000000000..2d5f54e5a0
--- /dev/null
+++ b/jjwt/src/main/resources/templates/fragments/head.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Nothing to see here, move along.
+
+
\ No newline at end of file
diff --git a/jjwt/src/main/resources/templates/jwt-csrf-form-result.html b/jjwt/src/main/resources/templates/jwt-csrf-form-result.html
new file mode 100644
index 0000000000..cfb832bf7c
--- /dev/null
+++ b/jjwt/src/main/resources/templates/jwt-csrf-form-result.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
You made it!
+
+
BLARG
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jjwt/src/main/resources/templates/jwt-csrf-form.html b/jjwt/src/main/resources/templates/jwt-csrf-form.html
new file mode 100644
index 0000000000..235f6063c9
--- /dev/null
+++ b/jjwt/src/main/resources/templates/jwt-csrf-form.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/DemoApplicationTests.java b/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/DemoApplicationTests.java
new file mode 100644
index 0000000000..82138ea23e
--- /dev/null
+++ b/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/DemoApplicationTests.java
@@ -0,0 +1,18 @@
+package io.jsonwebtoken.jjwtfun;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes = JJWTFunApplication.class)
+@WebAppConfiguration
+public class DemoApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/jpa-storedprocedure/.classpath b/jpa-storedprocedure/.classpath
deleted file mode 100644
index fae1a2b37d..0000000000
--- a/jpa-storedprocedure/.classpath
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/jpa-storedprocedure/.project b/jpa-storedprocedure/.project
deleted file mode 100644
index b5ac58ebd1..0000000000
--- a/jpa-storedprocedure/.project
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
- jpa-storedprocedure
-
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
-
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/jsf/pom.xml b/jsf/pom.xml
index b5fbae4cf0..b80bcfb416 100644
--- a/jsf/pom.xml
+++ b/jsf/pom.xml
@@ -31,6 +31,13 @@
${javax.el.version}
+
+
+
+ javax.servlet
+ jstl
+ 1.2
+
diff --git a/jsf/src/main/webapp/el_intro.xhtml b/jsf/src/main/webapp/el_intro.xhtml
index 4ca5e44703..446647497f 100644
--- a/jsf/src/main/webapp/el_intro.xhtml
+++ b/jsf/src/main/webapp/el_intro.xhtml
@@ -1,52 +1,52 @@
-
+
-
- Baeldung | The EL Intro
+
+ Baeldung | The EL Intro
+
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Key
- Value
-
-
- #{header.key}
- #{header.value}
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Key
+ Value
+
+
+ #{header.key}
+ #{header.value}
+
+
+
+
+
+
diff --git a/json-path/.classpath b/json-path/.classpath
deleted file mode 100644
index 2244ed1e21..0000000000
--- a/json-path/.classpath
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/json-path/.project b/json-path/.project
deleted file mode 100644
index caa2c41711..0000000000
--- a/json-path/.project
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
- json-path
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
-
-
diff --git a/json/README.md b/json/README.md
new file mode 100644
index 0000000000..c47eca3e84
--- /dev/null
+++ b/json/README.md
@@ -0,0 +1,7 @@
+=========
+
+## Fast-Json
+
+### Relevant Articles:
+- [Introduction to JSON Schema in Java](http://www.baeldung.com/introduction-to-json-schema-in-java)
+- [A Guide to FastJson](http://www.baeldung.com/????????)
diff --git a/json/pom.xml b/json/pom.xml
index 47f1f25aa2..4d9efe56e4 100644
--- a/json/pom.xml
+++ b/json/pom.xml
@@ -13,6 +13,12 @@
1.3.0
+
+ com.alibaba
+ fastjson
+ 1.2.13
+
+
junit
junit
diff --git a/json/src/test/java/org/baeldung/json/schema/JSONSchemaTest.java b/json/src/test/java/com/baeldung/json/schema/JSONSchemaTest.java
similarity index 88%
rename from json/src/test/java/org/baeldung/json/schema/JSONSchemaTest.java
rename to json/src/test/java/com/baeldung/json/schema/JSONSchemaTest.java
index 273fd48bac..bd4aaee682 100644
--- a/json/src/test/java/org/baeldung/json/schema/JSONSchemaTest.java
+++ b/json/src/test/java/com/baeldung/json/schema/JSONSchemaTest.java
@@ -1,31 +1,32 @@
-package org.baeldung.json.schema;
-
-import org.everit.json.schema.Schema;
-import org.everit.json.schema.loader.SchemaLoader;
-
-import org.json.JSONObject;
-import org.json.JSONTokener;
-import org.junit.Test;
-
-public class JSONSchemaTest {
-
- @Test
- public void givenInvalidInput_whenValidating_thenInvalid() {
-
- JSONObject jsonSchema = new JSONObject(new JSONTokener(JSONSchemaTest.class.getResourceAsStream("/schema.json")));
- JSONObject jsonSubject = new JSONObject(new JSONTokener(JSONSchemaTest.class.getResourceAsStream("/product_invalid.json")));
-
- Schema schema = SchemaLoader.load(jsonSchema);
- schema.validate(jsonSubject);
- }
-
- @Test
- public void givenValidInput_whenValidating_thenValid() {
-
- JSONObject jsonSchema = new JSONObject(new JSONTokener(JSONSchemaTest.class.getResourceAsStream("/schema.json")));
- JSONObject jsonSubject = new JSONObject(new JSONTokener(JSONSchemaTest.class.getResourceAsStream("/product_valid.json")));
-
- Schema schema = SchemaLoader.load(jsonSchema);
- schema.validate(jsonSubject);
- }
-}
+package com.baeldung.json.schema;
+
+import org.everit.json.schema.Schema;
+import org.everit.json.schema.ValidationException;
+import org.everit.json.schema.loader.SchemaLoader;
+
+import org.json.JSONObject;
+import org.json.JSONTokener;
+import org.junit.Test;
+
+public class JSONSchemaTest {
+
+ @Test(expected = ValidationException.class)
+ public void givenInvalidInput_whenValidating_thenInvalid() {
+
+ JSONObject jsonSchema = new JSONObject(new JSONTokener(JSONSchemaTest.class.getResourceAsStream("/schema.json")));
+ JSONObject jsonSubject = new JSONObject(new JSONTokener(JSONSchemaTest.class.getResourceAsStream("/product_invalid.json")));
+
+ Schema schema = SchemaLoader.load(jsonSchema);
+ schema.validate(jsonSubject);
+ }
+
+ @Test
+ public void givenValidInput_whenValidating_thenValid() {
+
+ JSONObject jsonSchema = new JSONObject(new JSONTokener(JSONSchemaTest.class.getResourceAsStream("/schema.json")));
+ JSONObject jsonSubject = new JSONObject(new JSONTokener(JSONSchemaTest.class.getResourceAsStream("/product_valid.json")));
+
+ Schema schema = SchemaLoader.load(jsonSchema);
+ schema.validate(jsonSubject);
+ }
+}
diff --git a/json/src/test/java/fast_json/FastJsonTests.java b/json/src/test/java/fast_json/FastJsonTests.java
new file mode 100644
index 0000000000..7b7e3c0434
--- /dev/null
+++ b/json/src/test/java/fast_json/FastJsonTests.java
@@ -0,0 +1,104 @@
+package fast_json;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.BeanContext;
+import com.alibaba.fastjson.serializer.ContextValueFilter;
+import com.alibaba.fastjson.serializer.NameFilter;
+import com.alibaba.fastjson.serializer.SerializeConfig;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class FastJsonTests {
+ private List listOfPersons;
+
+ @Before
+ public void setUp() {
+ listOfPersons = new ArrayList();
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(2016, 6, 24);
+ listOfPersons.add(new Person(15, "John", "Doe", calendar.getTime()));
+ listOfPersons.add(new Person(20, "Janette", "Doe", calendar.getTime()));
+ }
+
+ @Test
+ public void whenJavaList_thanConvertToJsonCorrect() {
+ String personJsonFormat = JSON.toJSONString(listOfPersons);
+ assertEquals(
+ personJsonFormat,
+ "[{\"FIRST NAME\":\"Doe\",\"LAST NAME\":\"John\",\"DATE OF BIRTH\":"
+ + "\"24/07/2016\"},{\"FIRST NAME\":\"Doe\",\"LAST NAME\":\"Janette\",\"DATE OF BIRTH\":"
+ + "\"24/07/2016\"}]");
+ }
+
+ @Test
+ public void whenJson_thanConvertToObjectCorrect() {
+ String personJsonFormat = JSON.toJSONString(listOfPersons.get(0));
+ Person newPerson = JSON.parseObject(personJsonFormat, Person.class);
+ assertEquals(newPerson.getAge(), 0); // serialize is set to false for age attribute
+ assertEquals(newPerson.getFirstName(), listOfPersons.get(0).getFirstName());
+ assertEquals(newPerson.getLastName(), listOfPersons.get(0).getLastName());
+ }
+
+ @Test
+ public void whenGenerateJson_thanGenerationCorrect() throws ParseException {
+ JSONArray jsonArray = new JSONArray();
+ for (int i = 0; i < 2; i++) {
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("FIRST NAME", "John" + i);
+ jsonObject.put("LAST NAME", "Doe" + i);
+ jsonObject.put("DATE OF BIRTH", "2016/12/12 12:12:12");
+ jsonArray.add(jsonObject);
+ }
+ assertEquals(
+ jsonArray.toString(),
+ "[{\"LAST NAME\":\"Doe0\",\"DATE OF BIRTH\":"
+ + "\"2016/12/12 12:12:12\",\"FIRST NAME\":\"John0\"},{\"LAST NAME\":\"Doe1\","
+ + "\"DATE OF BIRTH\":\"2016/12/12 12:12:12\",\"FIRST NAME\":\"John1\"}]");
+ }
+
+ @Test
+ public void givenContextFilter_whenJavaObject_thanJsonCorrect() {
+ ContextValueFilter valueFilter = new ContextValueFilter() {
+ public Object process(BeanContext context, Object object,
+ String name, Object value) {
+ if (name.equals("DATE OF BIRTH")) {
+ return "NOT TO DISCLOSE";
+ }
+ if (value.equals("John") || value.equals("Doe")) {
+ return ((String) value).toUpperCase();
+ } else {
+ return null;
+ }
+ }
+ };
+ JSON.toJSONString(listOfPersons, valueFilter);
+ }
+
+ @Test
+ public void givenSerializeConfig_whenJavaObject_thanJsonCorrect() {
+ NameFilter formatName = new NameFilter() {
+ public String process(Object object, String name, Object value) {
+ return name.toLowerCase().replace(" ", "_");
+ }
+ };
+ SerializeConfig.getGlobalInstance().addFilter(Person.class, formatName);
+ String jsonOutput = JSON.toJSONStringWithDateFormat(listOfPersons,
+ "yyyy-MM-dd");
+ assertEquals(
+ jsonOutput,
+ "[{\"first_name\":\"Doe\",\"last_name\":\"John\","
+ + "\"date_of_birth\":\"2016-07-24\"},{\"first_name\":\"Doe\",\"last_name\":"
+ + "\"Janette\",\"date_of_birth\":\"2016-07-24\"}]");
+ // resetting custom serializer
+ SerializeConfig.getGlobalInstance().put(Person.class, null);
+ }
+}
diff --git a/json/src/test/java/fast_json/Person.java b/json/src/test/java/fast_json/Person.java
new file mode 100644
index 0000000000..0eac58cdfd
--- /dev/null
+++ b/json/src/test/java/fast_json/Person.java
@@ -0,0 +1,70 @@
+package fast_json;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+import java.util.Date;
+
+public class Person {
+
+ @JSONField(name = "AGE", serialize = false, deserialize = false)
+ private int age;
+
+ @JSONField(name = "LAST NAME", ordinal = 2)
+ private String lastName;
+
+ @JSONField(name = "FIRST NAME", ordinal = 1)
+ private String firstName;
+
+ @JSONField(name = "DATE OF BIRTH", format = "dd/MM/yyyy", ordinal = 3)
+ private Date dateOfBirth;
+
+ public Person() {
+
+ }
+
+ public Person(int age, String lastName, String firstName, Date dateOfBirth) {
+ super();
+ this.age = age;
+ this.lastName = lastName;
+ this.firstName = firstName;
+ this.dateOfBirth = dateOfBirth;
+ }
+
+ @Override
+ public String toString() {
+ return "Person [age=" + age + ", lastName=" + lastName + ", firstName="
+ + firstName + ", dateOfBirth=" + dateOfBirth + "]";
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public Date getDateOfBirth() {
+ return dateOfBirth;
+ }
+
+ public void setDateOfBirth(Date dateOfBirth) {
+ this.dateOfBirth = dateOfBirth;
+ }
+}
diff --git a/mocks/jmockit/README.md b/mocks/jmockit/README.md
index c310463c26..db78b2a3ac 100644
--- a/mocks/jmockit/README.md
+++ b/mocks/jmockit/README.md
@@ -5,3 +5,5 @@
### Relevant Articles:
- [JMockit 101](http://www.baeldung.com/jmockit-101)
+- [A Guide to JMockit Expectations](http://www.baeldung.com/jmockit-expectations)
+- [JMockit Advanced Topics](http://www.baeldung.com/jmockit-advanced-topics)
diff --git a/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java b/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java
new file mode 100644
index 0000000000..4d25f466a6
--- /dev/null
+++ b/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java
@@ -0,0 +1,20 @@
+package org.baeldung.mocks.jmockit;
+
+public class AdvancedCollaborator {
+ int i;
+ private int privateField = 5;
+ public AdvancedCollaborator(){}
+ public AdvancedCollaborator(String string) throws Exception{
+ i = string.length();
+ }
+ public String methodThatCallsPrivateMethod(int i){
+ return privateMethod() + i;
+ }
+ public int methodThatReturnsThePrivateField(){
+ return privateField;
+ }
+ private String privateMethod(){
+ return "default:";
+ }
+ class InnerAdvancedCollaborator{}
+}
diff --git a/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Collaborator.java b/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Collaborator.java
index ef271b9aff..60da12fa7c 100644
--- a/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Collaborator.java
+++ b/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Collaborator.java
@@ -1,9 +1,11 @@
package org.baeldung.mocks.jmockit;
public class Collaborator {
+
public boolean collaborate(String string){
return false;
}
+
public void receive(boolean bool){
//NOOP
}
diff --git a/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/ExpectationsCollaborator.java b/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/ExpectationsCollaborator.java
new file mode 100644
index 0000000000..8209464936
--- /dev/null
+++ b/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/ExpectationsCollaborator.java
@@ -0,0 +1,19 @@
+package org.baeldung.mocks.jmockit;
+
+import java.util.List;
+
+public interface ExpectationsCollaborator {
+ String methodForAny1(String s, int i, Boolean b);
+ void methodForAny2(Long l, List lst);
+ String methodForWith1(String s, int i);
+ void methodForWith2(Boolean b, List l);
+ String methodForNulls1(String s, List l);
+ void methodForNulls2(String s, List l);
+ void methodForTimes1();
+ void methodForTimes2();
+ void methodForTimes3();
+ void methodForArgThat(Object o);
+ String methodReturnsString();
+ int methodReturnsInt();
+ Object methodForDelegate(int i);
+}
diff --git a/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Model.java b/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Model.java
index 54249dcd1d..79ae24c2f5 100644
--- a/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Model.java
+++ b/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Model.java
@@ -1,7 +1,7 @@
package org.baeldung.mocks.jmockit;
public class Model {
- public String getInfo(){
- return "info";
- }
+ public String getInfo() {
+ return "info";
+ }
}
diff --git a/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorTest.java b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorTest.java
new file mode 100644
index 0000000000..aaabe44f66
--- /dev/null
+++ b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorTest.java
@@ -0,0 +1,110 @@
+package org.baeldung.mocks.jmockit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.baeldung.mocks.jmockit.AdvancedCollaborator.InnerAdvancedCollaborator;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import mockit.Deencapsulation;
+import mockit.Expectations;
+import mockit.Invocation;
+import mockit.Mock;
+import mockit.MockUp;
+import mockit.Mocked;
+import mockit.Tested;
+import mockit.integration.junit4.JMockit;
+
+@RunWith(JMockit.class)
+public class AdvancedCollaboratorTest & Comparable>> {
+
+ @Tested
+ private AdvancedCollaborator mock;
+
+ @Mocked
+ private MultiMock multiMock;
+
+ @Test
+ public void testToMockUpPrivateMethod() {
+ new MockUp() {
+ @Mock
+ private String privateMethod() {
+ return "mocked: ";
+ }
+ };
+ String res = mock.methodThatCallsPrivateMethod(1);
+ assertEquals("mocked: 1", res);
+ }
+
+ @Test
+ public void testToMockUpDifficultConstructor() throws Exception {
+ new MockUp() {
+ @Mock
+ public void $init(Invocation invocation, String string) {
+ ((AdvancedCollaborator) invocation.getInvokedInstance()).i = 1;
+ }
+ };
+ AdvancedCollaborator coll = new AdvancedCollaborator(null);
+ assertEquals(1, coll.i);
+ }
+
+ @Test
+ public void testToCallPrivateMethodsDirectly() {
+ Object value = Deencapsulation.invoke(mock, "privateMethod");
+ assertEquals("default:", value);
+ }
+
+ @Test
+ public void testToSetPrivateFieldDirectly() {
+ Deencapsulation.setField(mock, "privateField", 10);
+ assertEquals(10, mock.methodThatReturnsThePrivateField());
+ }
+
+ @Test
+ public void testToGetPrivateFieldDirectly() {
+ int value = Deencapsulation.getField(mock, "privateField");
+ assertEquals(5, value);
+ }
+
+ @Test
+ public void testToCreateNewInstanceDirectly() {
+ AdvancedCollaborator coll = Deencapsulation.newInstance(AdvancedCollaborator.class, "foo");
+ assertEquals(3, coll.i);
+ }
+
+ @Test
+ public void testToCreateNewInnerClassInstanceDirectly() {
+ InnerAdvancedCollaborator innerCollaborator = Deencapsulation.newInnerInstance(InnerAdvancedCollaborator.class, mock);
+ assertNotNull(innerCollaborator);
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testMultipleInterfacesWholeTest() {
+ new Expectations() {
+ {
+ multiMock.get(5); result = "foo";
+ multiMock.compareTo((List) any); result = 0;
+ }
+ };
+ assertEquals("foo", multiMock.get(5));
+ assertEquals(0, multiMock.compareTo(new ArrayList<>()));
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public & Comparable>> void testMultipleInterfacesOneMethod(@Mocked M mock) {
+ new Expectations() {
+ {
+ mock.get(5); result = "foo";
+ mock.compareTo((List) any);
+ result = 0; }
+ };
+ assertEquals("foo", mock.get(5));
+ assertEquals(0, mock.compareTo(new ArrayList<>()));
+ }
+}
diff --git a/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ExpectationsTest.java b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ExpectationsTest.java
new file mode 100644
index 0000000000..1c72647133
--- /dev/null
+++ b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ExpectationsTest.java
@@ -0,0 +1,158 @@
+package org.baeldung.mocks.jmockit;
+
+import mockit.Delegate;
+import mockit.Expectations;
+import mockit.Mocked;
+import mockit.StrictExpectations;
+import mockit.Verifications;
+import mockit.integration.junit4.JMockit;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(JMockit.class)
+@SuppressWarnings("unchecked")
+public class ExpectationsTest {
+
+ @Test
+ public void testForAny(@Mocked ExpectationsCollaborator mock) throws Exception {
+ new Expectations() {{
+ mock.methodForAny1(anyString, anyInt, anyBoolean);
+ result = "any";
+ }};
+
+ assertEquals("any", mock.methodForAny1("barfooxyz", 0, Boolean.FALSE));
+ mock.methodForAny2(2L, new ArrayList<>());
+
+ new Verifications() {{
+ mock.methodForAny2(anyLong, (List) any);
+ }};
+ }
+
+ @Test
+ public void testForWith(@Mocked ExpectationsCollaborator mock) throws Exception {
+ new Expectations() {{
+ mock.methodForWith1(withSubstring("foo"), withNotEqual(1));
+ result = "with";
+ }};
+
+ assertEquals("with", mock.methodForWith1("barfooxyz", 2));
+ mock.methodForWith2(Boolean.TRUE, new ArrayList<>());
+
+ new Verifications() {{
+ mock.methodForWith2(withNotNull(), withInstanceOf(List.class));
+ }};
+ }
+
+ @Test
+ public void testWithNulls(@Mocked ExpectationsCollaborator mock) {
+ new Expectations() {{
+ mock.methodForNulls1(anyString, null);
+ result = "null";
+ }};
+
+ assertEquals("null", mock.methodForNulls1("blablabla", new ArrayList()));
+ mock.methodForNulls2("blablabla", null);
+
+ new Verifications() {{
+ mock.methodForNulls2(anyString, (List) withNull());
+ }};
+ }
+
+ @Test
+ public void testWithTimes(@Mocked ExpectationsCollaborator mock) {
+ new Expectations() {{
+ mock.methodForTimes1();
+ times = 2;
+ mock.methodForTimes2();
+ }};
+
+ mock.methodForTimes1();
+ mock.methodForTimes1();
+ mock.methodForTimes2();
+ mock.methodForTimes3();
+ mock.methodForTimes3();
+ mock.methodForTimes3();
+
+ new Verifications() {{
+ mock.methodForTimes3();
+ minTimes = 1;
+ maxTimes = 3;
+ }};
+ }
+
+ @Test
+ public void testCustomArgumentMatching(@Mocked ExpectationsCollaborator mock) {
+ new Expectations() {{
+ mock.methodForArgThat(withArgThat(new BaseMatcher() {
+ @Override
+ public boolean matches(Object item) {
+ return item instanceof Model && "info".equals(((Model) item).getInfo());
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ }
+ }));
+ }};
+ mock.methodForArgThat(new Model());
+ }
+
+ @Test
+ public void testResultAndReturns(@Mocked ExpectationsCollaborator mock) {
+ new StrictExpectations() {{
+ mock.methodReturnsString();
+ result = "foo";
+ result = new Exception();
+ result = "bar";
+ mock.methodReturnsInt();
+ result = new int[]{1, 2, 3};
+ mock.methodReturnsString();
+ returns("foo", "bar");
+ mock.methodReturnsInt();
+ result = 1;
+ }};
+
+ assertEquals("Should return foo", "foo", mock.methodReturnsString());
+ try {
+ mock.methodReturnsString();
+ } catch (Exception e) {
+ // NOOP
+ }
+ assertEquals("Should return bar", "bar", mock.methodReturnsString());
+ assertEquals("Should return 1", 1, mock.methodReturnsInt());
+ assertEquals("Should return 2", 2, mock.methodReturnsInt());
+ assertEquals("Should return 3", 3, mock.methodReturnsInt());
+ assertEquals("Should return foo", "foo", mock.methodReturnsString());
+ assertEquals("Should return bar", "bar", mock.methodReturnsString());
+ assertEquals("Should return 1", 1, mock.methodReturnsInt());
+ }
+
+ @Test
+ public void testDelegate(@Mocked ExpectationsCollaborator mock) {
+ new Expectations() {{
+ mock.methodForDelegate(anyInt);
+ result = new Delegate() {
+ public int delegate(int i) throws Exception {
+ if (i < 3) {
+ return 5;
+ } else {
+ throw new Exception();
+ }
+ }
+ };
+ }};
+
+ assertEquals("Should return 5", 5, mock.methodForDelegate(1));
+ try {
+ mock.methodForDelegate(3);
+ } catch (Exception e) {
+ }
+ }
+}
diff --git a/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/PerformerTest.java b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/PerformerTest.java
index c99ae844c3..2b1b3be0f7 100644
--- a/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/PerformerTest.java
+++ b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/PerformerTest.java
@@ -21,7 +21,9 @@ public class PerformerTest {
model.getInfo();result = "bar";
collaborator.collaborate("bar"); result = true;
}};
+
performer.perform(model);
+
new Verifications() {{
collaborator.receive(true);
}};
diff --git a/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingTest.java b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingTest.java
new file mode 100644
index 0000000000..729cb30cd2
--- /dev/null
+++ b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingTest.java
@@ -0,0 +1,57 @@
+package org.baeldung.mocks.jmockit;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import mockit.Expectations;
+import mockit.Injectable;
+import mockit.Mocked;
+import mockit.Tested;
+import mockit.Verifications;
+import mockit.integration.junit4.JMockit;
+
+@RunWith(JMockit.class)
+public class ReusingTest {
+
+ @Injectable
+ private Collaborator collaborator;
+
+ @Mocked
+ private Model model;
+
+ @Tested
+ private Performer performer;
+
+ @Before
+ public void setup(){
+ new Expectations(){{
+ model.getInfo(); result = "foo"; minTimes = 0;
+ collaborator.collaborate("foo"); result = true; minTimes = 0;
+ }};
+ }
+
+ @Test
+ public void testWithSetup() {
+ performer.perform(model);
+ verifyTrueCalls(1);
+ }
+
+ protected void verifyTrueCalls(int calls){
+ new Verifications(){{
+ collaborator.receive(true); times = calls;
+ }};
+ }
+
+ final class TrueCallsVerification extends Verifications{
+ public TrueCallsVerification(int calls){
+ collaborator.receive(true); times = calls;
+ }
+ }
+
+ @Test
+ public void testWithFinalClass() {
+ performer.perform(model);
+ new TrueCallsVerification(1);
+ }
+}
diff --git a/mutation-testing/README.md b/mutation-testing/README.md
new file mode 100644
index 0000000000..5dd60620ba
--- /dev/null
+++ b/mutation-testing/README.md
@@ -0,0 +1,6 @@
+=========
+
+## Mutation Testing
+
+### Relevant Articles:
+- [Introduction to Mutation Testing Using the PITest Library](http://www.baeldung.com/java-mutation-testing-with-pitest)
diff --git a/mutation-testing/pom.xml b/mutation-testing/pom.xml
new file mode 100644
index 0000000000..83012ab8fe
--- /dev/null
+++ b/mutation-testing/pom.xml
@@ -0,0 +1,38 @@
+
+ 4.0.0
+ com.baeldung
+ mutation-testing
+ 0.1-SNAPSHOT
+ mutation-testing
+
+
+ org.pitest
+ pitest-parent
+ 1.1.10
+ pom
+
+
+ junit
+ junit
+ 4.9
+
+
+
+
+
+ org.pitest
+ pitest-maven
+ 1.1.10
+
+
+ com.baeldung.testing.mutation.*
+
+
+ com.baeldung.mutation.test.*
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mutation-testing/src/main/java/com/baeldung/testing/mutation/Palindrome.java b/mutation-testing/src/main/java/com/baeldung/testing/mutation/Palindrome.java
new file mode 100644
index 0000000000..0b166f1557
--- /dev/null
+++ b/mutation-testing/src/main/java/com/baeldung/testing/mutation/Palindrome.java
@@ -0,0 +1,15 @@
+package com.baeldung.testing.mutation;
+
+public class Palindrome {
+
+ public boolean isPalindrome(String inputString) {
+ if (inputString.length() == 0) {
+ return true;
+ } else {
+ char firstChar = inputString.charAt(0);
+ char lastChar = inputString.charAt(inputString.length() - 1);
+ String mid = inputString.substring(1, inputString.length() - 1);
+ return (firstChar == lastChar) && isPalindrome(mid);
+ }
+ }
+}
diff --git a/mutation-testing/src/test/java/com/baeldung/mutation/test/TestPalindrome.java b/mutation-testing/src/test/java/com/baeldung/mutation/test/TestPalindrome.java
new file mode 100644
index 0000000000..1410135883
--- /dev/null
+++ b/mutation-testing/src/test/java/com/baeldung/mutation/test/TestPalindrome.java
@@ -0,0 +1,29 @@
+package com.baeldung.mutation.test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.baeldung.testing.mutation.Palindrome;
+
+public class TestPalindrome {
+
+ @Test
+ public void acceptsPalindrome() {
+ Palindrome palindromeTester = new Palindrome();
+ assertTrue(palindromeTester.isPalindrome("noon"));
+ }
+
+ @Test
+ public void rejectsNonPalindrome(){
+ Palindrome palindromeTester = new Palindrome();
+ assertFalse(palindromeTester.isPalindrome("box"));
+ }
+
+ @Test
+ public void rejectsNearPalindrome(){
+ Palindrome palindromeTester = new Palindrome();
+ assertFalse(palindromeTester.isPalindrome("neon"));
+ }
+}
diff --git a/pom.xml b/pom.xml
index fa4777860d..419916de86 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,38 +14,57 @@
assertj
-
+ apache-cxf
+ apache-fop
core-java
core-java-8
+ couchbase-sdk-intro
+ couchbase-sdk-spring-service
+
+ dependency-injection
+ gatling
+
gson
-
+ gson-jackson-performance
guava
guava18
guava19
handling-spring-static-resources
httpclient
+ immutables
jackson
javaxval
+ jjwt
jooq-spring
+ jpa-storedprocedure
+ json
json-path
+ junit5
mockito
mocks
jee7schedule
querydsl
+ rest-assured
rest-testing
resteasy
log4j
spring-all
spring-apache-camel
+ spring-autowire
spring-batch
spring-boot
+ spring-cucumber
spring-data-cassandra
+ spring-data-couchbase-2
+ spring-data-couchbase-2b
spring-data-elasticsearch
+ spring-data-neo4j
spring-data-mongodb
spring-data-redis
+ spring-data-rest
spring-exceptions
spring-freemarker
spring-hibernate3
@@ -59,9 +78,12 @@
spring-openid
spring-protobuf
spring-quartz
+ spring-spel
spring-rest
+ spring-rest-docs
spring-security-basic-auth
+ spring-security-custom-permission
spring-security-mvc-custom
spring-security-mvc-digest-auth
spring-security-mvc-ldap
@@ -77,8 +99,13 @@
spring-zuul
jsf
xml
-
lombok
+ redis
+ webjars
+
+ mutation-testing
+ spring-mvc-velocity
+ xstream
diff --git a/querydsl/.classpath b/querydsl/.classpath
deleted file mode 100644
index 264bb653bb..0000000000
--- a/querydsl/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/querydsl/.project b/querydsl/.project
deleted file mode 100644
index 729f89c323..0000000000
--- a/querydsl/.project
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
- querydsl
-
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/redis/pom.xml b/redis/pom.xml
new file mode 100644
index 0000000000..a5d3af8097
--- /dev/null
+++ b/redis/pom.xml
@@ -0,0 +1,56 @@
+
+
+
+ 4.0.0
+ com.baeldung
+ redis
+ 0.1-SNAPSHOT
+
+ redis
+ http://maven.apache.org
+
+
+
+ redis.clients
+ jedis
+ 2.8.1
+
+
+
+ com.github.kstyrc
+ embedded-redis
+ 0.6
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.5.1
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+ UTF-8
+
+ 4.12
+
+
diff --git a/redis/src/test/java/com/baeldung/JedisTest.java b/redis/src/test/java/com/baeldung/JedisTest.java
new file mode 100644
index 0000000000..766fd7b5e9
--- /dev/null
+++ b/redis/src/test/java/com/baeldung/JedisTest.java
@@ -0,0 +1,225 @@
+package com.baeldung;
+
+import java.io.IOException;
+import java.time.Duration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.JedisPoolConfig;
+import redis.clients.jedis.Pipeline;
+import redis.clients.jedis.Response;
+import redis.clients.jedis.Transaction;
+import redis.embedded.RedisServer;
+
+/**
+ * Unit test for Redis Java library - Jedis.
+ */
+public class JedisTest {
+
+ private Jedis jedis;
+ private static RedisServer redisServer;
+
+ public JedisTest() {
+ jedis = new Jedis();
+ }
+
+ @BeforeClass
+ public static void setUp() throws IOException {
+ redisServer = new RedisServer(6379);
+ redisServer.start();
+ }
+
+ @AfterClass
+ public static void destroy() {
+ redisServer.stop();
+ }
+
+ @After
+ public void flush() {
+ jedis.flushAll();
+ }
+
+ @Test
+ public void givenAString_thenSaveItAsRedisStrings() {
+ String key = "key";
+ String value = "value";
+
+ jedis.set(key, value);
+ String value2 = jedis.get(key);
+
+ Assert.assertEquals(value, value2);
+ }
+
+ @Test
+ public void givenListElements_thenSaveThemInRedisList() {
+ String queue = "queue#tasks";
+
+ String taskOne = "firstTask";
+ String taskTwo = "secondTask";
+ String taskThree = "thirdTask";
+
+ jedis.lpush(queue, taskOne, taskTwo);
+
+ String taskReturnedOne = jedis.rpop(queue);
+
+ jedis.lpush(queue, taskThree);
+ Assert.assertEquals(taskOne, taskReturnedOne);
+
+ String taskReturnedTwo = jedis.rpop(queue);
+ String taskReturnedThree = jedis.rpop(queue);
+
+ Assert.assertEquals(taskTwo, taskReturnedTwo);
+ Assert.assertEquals(taskThree, taskReturnedThree);
+
+ String taskReturnedFour = jedis.rpop(queue);
+ Assert.assertNull(taskReturnedFour);
+ }
+
+ @Test
+ public void givenSetElements_thenSaveThemInRedisSet() {
+ String countries = "countries";
+
+ String countryOne = "Spain";
+ String countryTwo = "Ireland";
+ String countryThree = "Ireland";
+
+ jedis.sadd(countries, countryOne);
+
+ Set countriesSet = jedis.smembers(countries);
+ Assert.assertEquals(1, countriesSet.size());
+
+ jedis.sadd(countries, countryTwo);
+ countriesSet = jedis.smembers(countries);
+ Assert.assertEquals(2, countriesSet.size());
+
+ jedis.sadd(countries, countryThree);
+ countriesSet = jedis.smembers(countries);
+ Assert.assertEquals(2, countriesSet.size());
+
+ boolean exists = jedis.sismember(countries, countryThree);
+ Assert.assertTrue(exists);
+ }
+
+ @Test
+ public void givenObjectFields_thenSaveThemInRedisHash() {
+ String key = "user#1";
+
+ String field = "name";
+ String value = "William";
+
+ String field2 = "job";
+ String value2 = "politician";
+
+ jedis.hset(key, field, value);
+ jedis.hset(key, field2, value2);
+
+ String value3 = jedis.hget(key, field);
+ Assert.assertEquals(value, value3);
+
+ Map fields = jedis.hgetAll(key);
+ String value4 = fields.get(field2);
+ Assert.assertEquals(value2, value4);
+ }
+
+ @Test
+ public void givenARanking_thenSaveItInRedisSortedSet() {
+ String key = "ranking";
+
+ Map scores = new HashMap<>();
+
+ scores.put("PlayerOne", 3000.0);
+ scores.put("PlayerTwo", 1500.0);
+ scores.put("PlayerThree", 8200.0);
+
+ for (String player : scores.keySet()) {
+ jedis.zadd(key, scores.get(player), player);
+ }
+
+ Set players = jedis.zrevrange(key, 0, 1);
+ Assert.assertEquals("PlayerThree", players.iterator().next());
+
+ long rank = jedis.zrevrank(key, "PlayerOne");
+ Assert.assertEquals(1, rank);
+ }
+
+ @Test
+ public void givenMultipleOperationsThatNeedToBeExecutedAtomically_thenWrapThemInATransaction() {
+ String friendsPrefix = "friends#";
+
+ String userOneId = "4352523";
+ String userTwoId = "5552321";
+
+ Transaction t = jedis.multi();
+ t.sadd(friendsPrefix + userOneId, userTwoId);
+ t.sadd(friendsPrefix + userTwoId, userOneId);
+ t.exec();
+
+ boolean exists = jedis.sismember(friendsPrefix + userOneId, userTwoId);
+ Assert.assertTrue(exists);
+
+ exists = jedis.sismember(friendsPrefix + userTwoId, userOneId);
+ Assert.assertTrue(exists);
+ }
+
+ @Test
+ public void givenMultipleIndependentOperations_whenNetworkOptimizationIsImportant_thenWrapThemInAPipeline() {
+ String userOneId = "4352523";
+ String userTwoId = "4849888";
+
+ Pipeline p = jedis.pipelined();
+ p.sadd("searched#" + userOneId, "paris");
+ p.zadd("ranking", 126, userOneId);
+ p.zadd("ranking", 325, userTwoId);
+ Response pipeExists = p.sismember("searched#" + userOneId, "paris");
+ Response> pipeRanking = p.zrange("ranking", 0, -1);
+ p.sync();
+
+ Assert.assertTrue(pipeExists.get());
+ Assert.assertEquals(2, pipeRanking.get().size());
+ }
+
+ @Test
+ public void givenAPoolConfiguration_thenCreateAJedisPool() {
+ final JedisPoolConfig poolConfig = buildPoolConfig();
+
+ try (JedisPool jedisPool = new JedisPool(poolConfig, "localhost"); Jedis jedis = jedisPool.getResource()) {
+
+ // do simple operation to verify that the Jedis resource is working
+ // properly
+ String key = "key";
+ String value = "value";
+
+ jedis.set(key, value);
+ String value2 = jedis.get(key);
+
+ Assert.assertEquals(value, value2);
+
+ // flush Redis
+ jedis.flushAll();
+ }
+ }
+
+ private JedisPoolConfig buildPoolConfig() {
+ final JedisPoolConfig poolConfig = new JedisPoolConfig();
+ poolConfig.setMaxTotal(128);
+ poolConfig.setMaxIdle(128);
+ poolConfig.setMinIdle(16);
+ poolConfig.setTestOnBorrow(true);
+ poolConfig.setTestOnReturn(true);
+ poolConfig.setTestWhileIdle(true);
+ poolConfig.setMinEvictableIdleTimeMillis(Duration.ofSeconds(60).toMillis());
+ poolConfig.setTimeBetweenEvictionRunsMillis(Duration.ofSeconds(30).toMillis());
+ poolConfig.setNumTestsPerEvictionRun(3);
+ poolConfig.setBlockWhenExhausted(true);
+ return poolConfig;
+ }
+}
diff --git a/rest-assured/.gitignore b/rest-assured/.gitignore
new file mode 100644
index 0000000000..862f46031e
--- /dev/null
+++ b/rest-assured/.gitignore
@@ -0,0 +1,16 @@
+*.class
+
+#folders#
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
+
+.externalToolBuilders
+.settings
\ No newline at end of file
diff --git a/rest-assured/README.md b/rest-assured/README.md
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/rest-assured/pom.xml b/rest-assured/pom.xml
new file mode 100644
index 0000000000..47241b18bd
--- /dev/null
+++ b/rest-assured/pom.xml
@@ -0,0 +1,257 @@
+
+ 4.0.0
+ com.baeldung
+ rest-assured
+ 1.0
+ rest-assured
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.3
+
+ 8
+ 8
+
+
+
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1-b06
+
+
+
+
+ javax.servlet
+ servlet-api
+ 2.5
+
+
+
+
+ org.eclipse.jetty
+ jetty-security
+ 9.2.0.M1
+
+
+
+
+ org.eclipse.jetty
+ jetty-servlet
+ 9.2.0.M1
+
+
+
+
+ org.eclipse.jetty
+ jetty-servlets
+ 9.2.0.M1
+
+
+
+
+ org.eclipse.jetty
+ jetty-io
+ 9.2.0.M1
+
+
+
+
+ org.eclipse.jetty
+ jetty-http
+ 9.2.0.M1
+
+
+
+
+
+
+ org.eclipse.jetty
+ jetty-server
+ 9.2.0.M1
+
+
+
+
+ org.eclipse.jetty
+ jetty-util
+ 9.2.0.M1
+
+
+
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.21
+
+
+
+
+ log4j
+ log4j
+ 1.2.17
+
+
+
+ org.slf4j
+ slf4j-log4j12
+ 1.7.21
+
+
+
+
+
+ commons-logging
+ commons-logging
+ 1.2
+
+
+
+ org.apache.httpcomponents
+ httpcore
+ 4.4.5
+
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.4
+
+
+
+
+
+ com.github.fge
+ uri-template
+ 0.9
+
+
+
+
+ com.googlecode.libphonenumber
+ libphonenumber
+ 7.4.5
+
+
+
+ javax.mail
+ mail
+ 1.4.7
+
+
+
+ joda-time
+ joda-time
+ 2.9.4
+
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ 2.8.0
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.8.0
+
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.8.0
+
+
+
+ com.github.fge
+ msg-simple
+ 1.1
+
+
+
+ com.github.fge
+ jackson-coreutils
+ 1.8
+
+
+
+
+
+ com.google.guava
+ guava
+ 18.0
+
+
+ com.github.fge
+ btf
+ 1.2
+
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.2
+
+
+
+ org.codehaus.groovy
+ groovy-all
+ 2.4.7
+
+
+
+ com.github.tomakehurst
+ wiremock
+ 2.1.7
+
+
+ io.rest-assured
+ rest-assured
+ 3.0.0
+ test
+
+
+ io.rest-assured
+ json-schema-validator
+ 3.0.0
+
+
+ com.github.fge
+ json-schema-validator
+ 2.2.6
+
+
+ com.github.fge
+ json-schema-core
+ 1.2.5
+
+
+ junit
+ junit
+ 4.3
+ test
+
+
+
+ org.hamcrest
+ hamcrest-all
+ 1.3
+
+
+
+ commons-collections
+ commons-collections
+ 3.2.2
+
+
+
+
diff --git a/rest-assured/src/test/java/com/baeldung/restassured/RestAssured2Test.java b/rest-assured/src/test/java/com/baeldung/restassured/RestAssured2Test.java
new file mode 100644
index 0000000000..067756823b
--- /dev/null
+++ b/rest-assured/src/test/java/com/baeldung/restassured/RestAssured2Test.java
@@ -0,0 +1,55 @@
+package com.baeldung.restassured;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.configureFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static org.hamcrest.Matchers.hasItems;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static io.restassured.RestAssured.get;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+
+public class RestAssured2Test {
+ private WireMockServer wireMockServer = new WireMockServer();
+
+ private static final String EVENTS_PATH = "/odds";
+ private static final String APPLICATION_JSON = "application/json";
+ private static final String ODDS = getJson();
+
+ @Before
+ public void before() throws Exception {
+ System.out.println("Setting up!");
+ wireMockServer.start();
+ configureFor("localhost", 8080);
+ stubFor(get(urlEqualTo(EVENTS_PATH)).willReturn(
+ aResponse().withStatus(200)
+ .withHeader("Content-Type", APPLICATION_JSON)
+ .withBody(ODDS)));
+ }
+
+ @Test
+ public void givenUrl_whenVerifiesOddPricesAccuratelyByStatus_thenCorrect() {
+ get("/odds").then().body("odds.findAll { it.status > 0 }.price",
+ hasItems(5.25f, 1.2f));
+ }
+
+ private static String getJson() {
+
+ return Util.inputStreamToString(new RestAssured2Test().getClass()
+ .getResourceAsStream("/odds.json"));
+
+ }
+
+ @After
+ public void after() throws Exception {
+ System.out.println("Running: tearDown");
+ wireMockServer.stop();
+ }
+
+}
diff --git a/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredTest.java b/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredTest.java
new file mode 100644
index 0000000000..06f54aae24
--- /dev/null
+++ b/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredTest.java
@@ -0,0 +1,106 @@
+package com.baeldung.restassured;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.configureFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static io.restassured.RestAssured.get;
+import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;
+import static io.restassured.module.jsv.JsonSchemaValidatorSettings.settings;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItems;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.github.fge.jsonschema.SchemaVersion;
+import com.github.fge.jsonschema.cfg.ValidationConfiguration;
+import com.github.fge.jsonschema.main.JsonSchemaFactory;
+import com.github.tomakehurst.wiremock.WireMockServer;
+
+public class RestAssuredTest {
+
+ private WireMockServer wireMockServer = new WireMockServer();
+ private static final String EVENTS_PATH = "/events?id=390";
+ private static final String APPLICATION_JSON = "application/json";
+ private static final String GAME_ODDS = getEventJson();
+
+ @Before
+ public void before() throws Exception {
+ System.out.println("Setting up!");
+ wireMockServer.start();
+ configureFor("localhost", 8080);
+ stubFor(get(urlEqualTo(EVENTS_PATH)).willReturn(
+ aResponse().withStatus(200)
+ .withHeader("Content-Type", APPLICATION_JSON)
+ .withBody(GAME_ODDS)));
+ }
+
+ @Test
+ public void givenUrl_whenCheckingFloatValuePasses_thenCorrect() {
+ get("/events?id=390").then().assertThat()
+ .body("odd.ck", equalTo(12.2f));
+ }
+
+ @Test
+ public void givenUrl_whenSuccessOnGetsResponseAndJsonHasRequiredKV_thenCorrect() {
+
+ get("/events?id=390").then().statusCode(200).assertThat()
+ .body("id", equalTo("390"));
+
+ }
+
+ @Test
+ public void givenUrl_whenJsonResponseHasArrayWithGivenValuesUnderKey_thenCorrect() {
+ get("/events?id=390").then().assertThat()
+ .body("odds.price", hasItems("1.30", "5.25", "2.70", "1.20"));
+ }
+
+ @Test
+ public void givenUrl_whenJsonResponseConformsToSchema_thenCorrect() {
+
+ get("/events?id=390").then().assertThat()
+ .body(matchesJsonSchemaInClasspath("event_0.json"));
+ }
+
+ @Test
+ public void givenUrl_whenValidatesResponseWithInstanceSettings_thenCorrect() {
+ JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory
+ .newBuilder()
+ .setValidationConfiguration(
+ ValidationConfiguration.newBuilder()
+ .setDefaultVersion(SchemaVersion.DRAFTV4)
+ .freeze()).freeze();
+
+ get("/events?id=390")
+ .then()
+ .assertThat()
+ .body(matchesJsonSchemaInClasspath("event_0.json").using(
+ jsonSchemaFactory));
+
+ }
+
+ @Test
+ public void givenUrl_whenValidatesResponseWithStaticSettings_thenCorrect() {
+
+ get("/events?id=390")
+ .then()
+ .assertThat()
+ .body(matchesJsonSchemaInClasspath("event_0.json").using(
+ settings().with().checkedValidation(false)));
+ }
+
+ @After
+ public void after() throws Exception {
+ System.out.println("Running: tearDown");
+ wireMockServer.stop();
+ }
+
+ private static String getEventJson() {
+ return Util.inputStreamToString(RestAssuredTest.class
+ .getResourceAsStream("/event_0.json"));
+ }
+
+}
diff --git a/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXML2Test.java b/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXML2Test.java
new file mode 100644
index 0000000000..597280c7c0
--- /dev/null
+++ b/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXML2Test.java
@@ -0,0 +1,54 @@
+package com.baeldung.restassured;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.configureFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static org.hamcrest.Matchers.hasItems;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static io.restassured.RestAssured.get;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+
+public class RestAssuredXML2Test {
+ private WireMockServer wireMockServer = new WireMockServer();
+
+ private static final String EVENTS_PATH = "/teachers";
+ private static final String APPLICATION_XML = "application/xml";
+ private static final String TEACHERS = getXml();
+
+ @Before
+ public void before() throws Exception {
+ System.out.println("Setting up!");
+ wireMockServer.start();
+ configureFor("localhost", 8080);
+ stubFor(get(urlEqualTo(EVENTS_PATH)).willReturn(
+ aResponse().withStatus(200)
+ .withHeader("Content-Type", APPLICATION_XML)
+ .withBody(TEACHERS)));
+ }
+ @Test
+ public void givenUrl_whenVerifiesScienceTeacherFromXml_thenCorrect() {
+ get("/teachers")
+ .then()
+ .body("teachers.teacher.find { it.@department == 'science' }.subject",
+ hasItems("math", "physics"));
+ }
+ private static String getXml() {
+
+ return Util
+ .inputStreamToString(new RestAssuredXML2Test().getClass().getResourceAsStream("/teachers.xml"));
+
+}
+ @After
+public void after() throws Exception {
+ System.out.println("Running: tearDown");
+ wireMockServer.stop();
+}
+
+}
diff --git a/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXMLTest.java b/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXMLTest.java
new file mode 100644
index 0000000000..315dc76169
--- /dev/null
+++ b/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXMLTest.java
@@ -0,0 +1,99 @@
+package com.baeldung.restassured;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.configureFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static io.restassured.RestAssured.post;
+import static io.restassured.RestAssured.get;
+import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;
+import static io.restassured.module.jsv.JsonSchemaValidatorSettings.settings;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.xml.HasXPath.hasXPath;
+
+import java.io.FileNotFoundException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.github.fge.jsonschema.SchemaVersion;
+import com.github.fge.jsonschema.cfg.ValidationConfiguration;
+import com.github.fge.jsonschema.main.JsonSchemaFactory;
+import com.github.tomakehurst.wiremock.WireMockServer;
+public class RestAssuredXMLTest {
+ private WireMockServer wireMockServer = new WireMockServer();
+ private static final String EVENTS_PATH = "/employees";
+ private static final String APPLICATION_XML = "application/xml";
+ private static final String EMPLOYEES = getXml();
+
+ @Before
+ public void before() throws Exception {
+ System.out.println("Setting up!");
+ wireMockServer.start();
+ configureFor("localhost", 8080);
+ stubFor(post(urlEqualTo(EVENTS_PATH)).willReturn(
+ aResponse().withStatus(200)
+ .withHeader("Content-Type", APPLICATION_XML)
+ .withBody(EMPLOYEES)));
+ }
+ @Test
+ public void givenUrl_whenXmlResponseValueTestsEqual_thenCorrect() {
+ post("/employees").then().assertThat()
+ .body("employees.employee.first-name", equalTo("Jane"));
+ }
+
+ @Test
+ public void givenUrl_whenMultipleXmlValuesTestEqual_thenCorrect() {
+ post("/employees").then().assertThat()
+ .body("employees.employee.first-name", equalTo("Jane"))
+ .body("employees.employee.last-name", equalTo("Daisy"))
+ .body("employees.employee.sex", equalTo("f"));
+ }
+
+ @Test
+ public void givenUrl_whenMultipleXmlValuesTestEqualInShortHand_thenCorrect() {
+ post("/employees")
+ .then()
+ .assertThat()
+ .body("employees.employee.first-name", equalTo("Jane"),
+ "employees.employee.last-name", equalTo("Daisy"),
+ "employees.employee.sex", equalTo("f"));
+ }
+
+ @Test
+ public void givenUrl_whenValidatesXmlUsingXpath_thenCorrect() {
+ post("/employees")
+ .then()
+ .assertThat()
+ .body(hasXPath("/employees/employee/first-name",
+ containsString("Ja")));
+
+ }
+
+ @Test
+ public void givenUrl_whenValidatesXmlUsingXpath2_thenCorrect() {
+ post("/employees")
+ .then()
+ .assertThat()
+ .body(hasXPath("/employees/employee/first-name[text()='Jane']"));
+
+ }
+
+
+ private static String getXml() {
+
+ return Util
+ .inputStreamToString(new RestAssuredXMLTest().getClass().getResourceAsStream("/employees.xml"));
+
+}
+ @After
+public void after() throws Exception {
+ System.out.println("Running: tearDown");
+ wireMockServer.stop();
+}
+}
diff --git a/rest-assured/src/test/java/com/baeldung/restassured/Util.java b/rest-assured/src/test/java/com/baeldung/restassured/Util.java
new file mode 100644
index 0000000000..c75c52eb34
--- /dev/null
+++ b/rest-assured/src/test/java/com/baeldung/restassured/Util.java
@@ -0,0 +1,36 @@
+package com.baeldung.restassured;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Util {
+ public static String inputStreamToString(InputStream is) {
+ BufferedReader br = null;
+ StringBuilder sb = new StringBuilder();
+
+ String line;
+ try {
+
+ br = new BufferedReader(new InputStreamReader(is));
+ while ((line = br.readLine()) != null) {
+ sb.append(line);
+ }
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (br != null) {
+ try {
+ br.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return sb.toString();
+
+ }
+}
diff --git a/rest-assured/src/test/resources/employees.xml b/rest-assured/src/test/resources/employees.xml
new file mode 100644
index 0000000000..388b422210
--- /dev/null
+++ b/rest-assured/src/test/resources/employees.xml
@@ -0,0 +1,7 @@
+
+
+ Jane
+ Daisy
+ f
+
+
\ No newline at end of file
diff --git a/rest-assured/src/test/resources/event_0.json b/rest-assured/src/test/resources/event_0.json
new file mode 100644
index 0000000000..a6e45239ec
--- /dev/null
+++ b/rest-assured/src/test/resources/event_0.json
@@ -0,0 +1,43 @@
+{
+ "id": "390",
+ "odd": {
+ "price": "1.20",
+ "status": 2,
+ "ck": 12.2,
+ "name": "2"
+ },
+ "data": {
+ "countryId": 35,
+ "countryName": "Norway",
+ "leagueName": "Norway 3",
+ "status": 0,
+ "sportName": "Soccer",
+ "time": "2016-06-12T12:00:00Z"
+ },
+ "odds": [{
+ "price": "1.30",
+ "status": 0,
+ "ck": 12.2,
+ "name": "1"
+ },
+ {
+ "price":"5.25",
+ "status": 1,
+ "ck": 13.1,
+ "name": "X"
+ },
+ {
+ "price": "2.70",
+ "status": 0,
+ "ck": 12.2,
+ "name": "0"
+ },
+ {
+ "price": "1.20",
+ "status": 2,
+ "ck": 13.1,
+ "name": "2"
+ }
+
+ ]
+}
\ No newline at end of file
diff --git a/rest-assured/src/test/resources/log4j.properties b/rest-assured/src/test/resources/log4j.properties
new file mode 100644
index 0000000000..d3c6b9e783
--- /dev/null
+++ b/rest-assured/src/test/resources/log4j.properties
@@ -0,0 +1,16 @@
+## Logger configure
+datestamp=yyyy-MM-dd HH:mm:ss
+log4j.rootLogger=TRACE, file, console
+
+log4j.appender.file=org.apache.log4j.RollingFileAppender
+log4j.appender.file.maxFileSize=1GB
+log4j.appender.file.maxBackupIndex=5
+log4j.appender.file.File=log/rest-assured.log
+log4j.appender.file.threshold=TRACE
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{${datestamp}} %5p: [%c] - %m%n
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=INFO
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d{${datestamp}} %5p\: [%c] - %m%n
\ No newline at end of file
diff --git a/rest-assured/src/test/resources/odds.json b/rest-assured/src/test/resources/odds.json
new file mode 100644
index 0000000000..8b3dc166c5
--- /dev/null
+++ b/rest-assured/src/test/resources/odds.json
@@ -0,0 +1,28 @@
+{
+ "odds": [{
+ "price": 1.30,
+ "status": 0,
+ "ck": 12.2,
+ "name": "1"
+ },
+ {
+ "price": 5.25,
+ "status": 1,
+ "ck": 13.1,
+ "name": "X"
+ },
+ {
+ "price": 2.70,
+ "status": 0,
+ "ck": 12.2,
+ "name": "0"
+ },
+ {
+ "price": 1.20,
+ "status": 2,
+ "ck": 13.1,
+ "name": "2"
+ }
+
+ ]
+}
\ No newline at end of file
diff --git a/rest-assured/src/test/resources/teachers.xml b/rest-assured/src/test/resources/teachers.xml
new file mode 100644
index 0000000000..9c073d5a38
--- /dev/null
+++ b/rest-assured/src/test/resources/teachers.xml
@@ -0,0 +1,10 @@
+
+
+ math
+ physics
+
+
+ political education
+ english
+
+
\ No newline at end of file
diff --git a/resteasy/.classpath b/resteasy/.classpath
deleted file mode 100644
index 3c88c332e3..0000000000
--- a/resteasy/.classpath
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/resteasy/.project b/resteasy/.project
deleted file mode 100644
index 7303d59739..0000000000
--- a/resteasy/.project
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
- resteasy-tutorial
-
-
-
-
-
- org.eclipse.wst.jsdt.core.javascriptValidator
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-all/.classpath b/spring-all/.classpath
deleted file mode 100644
index 6b533711d3..0000000000
--- a/spring-all/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-all/.project b/spring-all/.project
deleted file mode 100644
index ce1efa8880..0000000000
--- a/spring-all/.project
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
- spring-all
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-all/.settings/.jsdtscope b/spring-all/.settings/.jsdtscope
deleted file mode 100644
index b46b9207a8..0000000000
--- a/spring-all/.settings/.jsdtscope
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-all/.settings/org.eclipse.jdt.core.prefs b/spring-all/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index b126d6476b..0000000000
--- a/spring-all/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,95 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
-org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.8
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=error
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=error
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
-org.eclipse.jdt.core.compiler.problem.nullReference=warning
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.8
diff --git a/spring-all/.settings/org.eclipse.jdt.ui.prefs b/spring-all/.settings/org.eclipse.jdt.ui.prefs
deleted file mode 100644
index 471e9b0d81..0000000000
--- a/spring-all/.settings/org.eclipse.jdt.ui.prefs
+++ /dev/null
@@ -1,55 +0,0 @@
-#Sat Jan 21 23:04:06 EET 2012
-eclipse.preferences.version=1
-editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-sp_cleanup.add_default_serial_version_id=true
-sp_cleanup.add_generated_serial_version_id=false
-sp_cleanup.add_missing_annotations=true
-sp_cleanup.add_missing_deprecated_annotations=true
-sp_cleanup.add_missing_methods=false
-sp_cleanup.add_missing_nls_tags=false
-sp_cleanup.add_missing_override_annotations=true
-sp_cleanup.add_missing_override_annotations_interface_methods=true
-sp_cleanup.add_serial_version_id=false
-sp_cleanup.always_use_blocks=true
-sp_cleanup.always_use_parentheses_in_expressions=true
-sp_cleanup.always_use_this_for_non_static_field_access=false
-sp_cleanup.always_use_this_for_non_static_method_access=false
-sp_cleanup.convert_to_enhanced_for_loop=true
-sp_cleanup.correct_indentation=true
-sp_cleanup.format_source_code=true
-sp_cleanup.format_source_code_changes_only=true
-sp_cleanup.make_local_variable_final=true
-sp_cleanup.make_parameters_final=true
-sp_cleanup.make_private_fields_final=false
-sp_cleanup.make_type_abstract_if_missing_method=false
-sp_cleanup.make_variable_declarations_final=true
-sp_cleanup.never_use_blocks=false
-sp_cleanup.never_use_parentheses_in_expressions=false
-sp_cleanup.on_save_use_additional_actions=true
-sp_cleanup.organize_imports=true
-sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
-sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
-sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
-sp_cleanup.remove_private_constructors=true
-sp_cleanup.remove_trailing_whitespaces=true
-sp_cleanup.remove_trailing_whitespaces_all=true
-sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
-sp_cleanup.remove_unnecessary_casts=true
-sp_cleanup.remove_unnecessary_nls_tags=false
-sp_cleanup.remove_unused_imports=true
-sp_cleanup.remove_unused_local_variables=false
-sp_cleanup.remove_unused_private_fields=true
-sp_cleanup.remove_unused_private_members=false
-sp_cleanup.remove_unused_private_methods=true
-sp_cleanup.remove_unused_private_types=true
-sp_cleanup.sort_members=false
-sp_cleanup.sort_members_all=false
-sp_cleanup.use_blocks=false
-sp_cleanup.use_blocks_only_for_return_and_throw=false
-sp_cleanup.use_parentheses_in_expressions=false
-sp_cleanup.use_this_for_non_static_field_access=true
-sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
-sp_cleanup.use_this_for_non_static_method_access=true
-sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/spring-all/.settings/org.eclipse.m2e.core.prefs b/spring-all/.settings/org.eclipse.m2e.core.prefs
deleted file mode 100644
index f897a7f1cb..0000000000
--- a/spring-all/.settings/org.eclipse.m2e.core.prefs
+++ /dev/null
@@ -1,4 +0,0 @@
-activeProfiles=
-eclipse.preferences.version=1
-resolveWorkspaceProjects=true
-version=1
diff --git a/spring-all/.settings/org.eclipse.m2e.wtp.prefs b/spring-all/.settings/org.eclipse.m2e.wtp.prefs
deleted file mode 100644
index ef86089622..0000000000
--- a/spring-all/.settings/org.eclipse.m2e.wtp.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.m2e.wtp.enabledProjectSpecificPrefs=false
diff --git a/spring-all/.settings/org.eclipse.wst.common.component b/spring-all/.settings/org.eclipse.wst.common.component
deleted file mode 100644
index 847c6ff698..0000000000
--- a/spring-all/.settings/org.eclipse.wst.common.component
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-all/.settings/org.eclipse.wst.common.project.facet.core.xml b/spring-all/.settings/org.eclipse.wst.common.project.facet.core.xml
deleted file mode 100644
index 991897a4ac..0000000000
--- a/spring-all/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/spring-all/.settings/org.eclipse.wst.jsdt.ui.superType.container b/spring-all/.settings/org.eclipse.wst.jsdt.ui.superType.container
deleted file mode 100644
index 3bd5d0a480..0000000000
--- a/spring-all/.settings/org.eclipse.wst.jsdt.ui.superType.container
+++ /dev/null
@@ -1 +0,0 @@
-org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
diff --git a/spring-all/.settings/org.eclipse.wst.jsdt.ui.superType.name b/spring-all/.settings/org.eclipse.wst.jsdt.ui.superType.name
deleted file mode 100644
index 05bd71b6ec..0000000000
--- a/spring-all/.settings/org.eclipse.wst.jsdt.ui.superType.name
+++ /dev/null
@@ -1 +0,0 @@
-Window
\ No newline at end of file
diff --git a/spring-all/.settings/org.eclipse.wst.validation.prefs b/spring-all/.settings/org.eclipse.wst.validation.prefs
deleted file mode 100644
index 0d0aee4f72..0000000000
--- a/spring-all/.settings/org.eclipse.wst.validation.prefs
+++ /dev/null
@@ -1,15 +0,0 @@
-DELEGATES_PREFERENCE=delegateValidatorList
-USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;
-USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;
-USER_PREFERENCE=overrideGlobalPreferencestruedisableAllValidationfalseversion1.2.402.v201212031633
-disabled=06target
-eclipse.preferences.version=1
-override=true
-suspend=false
-vals/org.eclipse.jst.jsf.ui.JSFAppConfigValidator/global=FF01
-vals/org.eclipse.jst.jsp.core.JSPBatchValidator/global=FF01
-vals/org.eclipse.jst.jsp.core.JSPContentValidator/global=FF01
-vals/org.eclipse.jst.jsp.core.TLDValidator/global=FF01
-vals/org.eclipse.wst.dtd.core.dtdDTDValidator/global=FF01
-vals/org.eclipse.wst.jsdt.web.core.JsBatchValidator/global=TF02
-vf.version=3
diff --git a/spring-all/.settings/org.eclipse.wst.ws.service.policy.prefs b/spring-all/.settings/org.eclipse.wst.ws.service.policy.prefs
deleted file mode 100644
index 9cfcabe16f..0000000000
--- a/spring-all/.settings/org.eclipse.wst.ws.service.policy.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.wst.ws.service.policy.projectEnabled=false
diff --git a/spring-all/.springBeans b/spring-all/.springBeans
deleted file mode 100644
index 7623a7e888..0000000000
--- a/spring-all/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/mvc-servlet.xml
-
-
-
-
diff --git a/spring-all/README.md b/spring-all/README.md
index 47c947a414..0bbb600860 100644
--- a/spring-all/README.md
+++ b/spring-all/README.md
@@ -11,3 +11,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Properties with Spring](http://www.baeldung.com/2012/02/06/properties-with-spring) - checkout the `org.baeldung.properties` package for all scenarios of properties injection and usage
- [Spring Profiles](http://www.baeldung.com/spring-profiles)
- [A Spring Custom Annotation for a Better DAO](http://www.baeldung.com/spring-annotation-bean-pre-processor)
+- [What's New in Spring 4.3?](http://www.baeldung.com/whats-new-in-spring-4-3/)
diff --git a/spring-all/pom.xml b/spring-all/pom.xml
index 8ff09e5e17..b7a8fcc79e 100644
--- a/spring-all/pom.xml
+++ b/spring-all/pom.xml
@@ -10,10 +10,14 @@
org.springframework.boot
spring-boot-starter-parent
- 1.2.6.RELEASE
+ 1.3.6.RELEASE
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
@@ -41,11 +45,6 @@
spring-aspects
-
- org.springframework
- spring-orm
-
-
@@ -88,6 +87,14 @@
runtime
+
+
+
+ com.typesafe.akka
+ akka-actor_2.11
+ 2.4.8
+
+
@@ -147,8 +154,38 @@
mockito-core
test
+
+
+ org.easymock
+ easymock
+ 3.4
+ test
+
+
+
+
+
+
+
+ org.springframework
+ spring-framework-bom
+ ${org.springframework.version}
+ pom
+ import
+
+
+
+ org.springframework
+ spring-core
+ ${org.springframework.version}
+
+
+
+
+
+
spring-all
@@ -217,7 +254,7 @@
- 4.2.5.RELEASE
+ 4.3.1.RELEASE
4.0.4.RELEASE
3.20.0-GA
1.2
diff --git a/spring-all/src/main/java/org/baeldung/akka/AppConfiguration.java b/spring-all/src/main/java/org/baeldung/akka/AppConfiguration.java
new file mode 100644
index 0000000000..9211ae0fdb
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/akka/AppConfiguration.java
@@ -0,0 +1,26 @@
+package org.baeldung.akka;
+
+import akka.actor.ActorSystem;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+import static org.baeldung.akka.SpringExtension.SPRING_EXTENSION_PROVIDER;
+
+@Configuration
+@ComponentScan
+public class AppConfiguration {
+
+ @Autowired
+ private ApplicationContext applicationContext;
+
+ @Bean
+ public ActorSystem actorSystem() {
+ ActorSystem system = ActorSystem.create("akka-spring-demo");
+ SPRING_EXTENSION_PROVIDER.get(system).initialize(applicationContext);
+ return system;
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/akka/GreetingActor.java b/spring-all/src/main/java/org/baeldung/akka/GreetingActor.java
new file mode 100644
index 0000000000..1a9386c769
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/akka/GreetingActor.java
@@ -0,0 +1,43 @@
+package org.baeldung.akka;
+
+import akka.actor.UntypedActor;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+import static org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_PROTOTYPE;
+
+@Component
+@Scope(SCOPE_PROTOTYPE)
+public class GreetingActor extends UntypedActor {
+
+ private GreetingService greetingService;
+
+ public GreetingActor(GreetingService greetingService) {
+ this.greetingService = greetingService;
+ }
+
+ @Override
+ public void onReceive(Object message) throws Throwable {
+ if (message instanceof Greet) {
+ String name = ((Greet) message).getName();
+ getSender().tell(greetingService.greet(name), getSelf());
+ } else {
+ unhandled(message);
+ }
+ }
+
+ public static class Greet {
+
+ private String name;
+
+ public Greet(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/akka/GreetingService.java b/spring-all/src/main/java/org/baeldung/akka/GreetingService.java
new file mode 100644
index 0000000000..801921887d
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/akka/GreetingService.java
@@ -0,0 +1,12 @@
+package org.baeldung.akka;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class GreetingService {
+
+ public String greet(String name) {
+ return "Hello, " + name;
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/akka/SpringActorProducer.java b/spring-all/src/main/java/org/baeldung/akka/SpringActorProducer.java
new file mode 100644
index 0000000000..20813ab60a
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/akka/SpringActorProducer.java
@@ -0,0 +1,28 @@
+package org.baeldung.akka;
+
+import akka.actor.Actor;
+import akka.actor.IndirectActorProducer;
+import org.springframework.context.ApplicationContext;
+
+public class SpringActorProducer implements IndirectActorProducer {
+
+ private ApplicationContext applicationContext;
+
+ private String beanActorName;
+
+ public SpringActorProducer(ApplicationContext applicationContext, String beanActorName) {
+ this.applicationContext = applicationContext;
+ this.beanActorName = beanActorName;
+ }
+
+ @Override
+ public Actor produce() {
+ return (Actor) applicationContext.getBean(beanActorName);
+ }
+
+ @Override
+ public Class extends Actor> actorClass() {
+ return (Class extends Actor>) applicationContext.getType(beanActorName);
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/akka/SpringExtension.java b/spring-all/src/main/java/org/baeldung/akka/SpringExtension.java
new file mode 100644
index 0000000000..624e289812
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/akka/SpringExtension.java
@@ -0,0 +1,33 @@
+package org.baeldung.akka;
+
+import akka.actor.AbstractExtensionId;
+import akka.actor.ExtendedActorSystem;
+import akka.actor.Extension;
+import akka.actor.Props;
+import org.springframework.context.ApplicationContext;
+
+public class SpringExtension extends AbstractExtensionId {
+
+ public static final SpringExtension SPRING_EXTENSION_PROVIDER = new SpringExtension();
+
+ @Override
+ public SpringExt createExtension(ExtendedActorSystem system) {
+ return new SpringExt();
+ }
+
+ public static class SpringExt implements Extension {
+
+ private volatile ApplicationContext applicationContext;
+
+ public void initialize(ApplicationContext applicationContext) {
+ this.applicationContext = applicationContext;
+ }
+
+ public Props props(String actorBeanName) {
+ return Props.create(SpringActorProducer.class, applicationContext, actorBeanName);
+ }
+
+ }
+
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/controller/controller/RestAnnotatedController.java b/spring-all/src/main/java/org/baeldung/controller/controller/RestAnnotatedController.java
new file mode 100644
index 0000000000..48981fd012
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/controller/controller/RestAnnotatedController.java
@@ -0,0 +1,19 @@
+package org.baeldung.controller.controller;
+
+import org.baeldung.controller.student.Student;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class RestAnnotatedController {
+
+ @GetMapping(value = "/annotated/student/{studentId}")
+ public Student getData(@PathVariable Integer studentId) {
+ Student student = new Student();
+ student.setName("Peter");
+ student.setId(studentId);
+
+ return student;
+ }
+}
diff --git a/spring-all/src/main/java/org/baeldung/controller/controller/RestController.java b/spring-all/src/main/java/org/baeldung/controller/controller/RestController.java
new file mode 100644
index 0000000000..95903bcc40
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/controller/controller/RestController.java
@@ -0,0 +1,21 @@
+package org.baeldung.controller.controller;
+
+import org.baeldung.controller.student.Student;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+@Controller
+public class RestController{
+
+ @GetMapping(value="/student/{studentId}")
+ public @ResponseBody Student getTestData(@PathVariable Integer studentId) {
+ Student student = new Student();
+ student.setName("Peter");
+ student.setId(studentId);
+
+ return student;
+
+ }
+}
diff --git a/spring-all/src/main/java/org/baeldung/controller/controller/TestController.java b/spring-all/src/main/java/org/baeldung/controller/controller/TestController.java
new file mode 100644
index 0000000000..12ae4e0ab1
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/controller/controller/TestController.java
@@ -0,0 +1,24 @@
+
+/**
+ * @author Prashant Dutta
+ */
+package org.baeldung.controller.controller;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+@Controller
+@RequestMapping(value = "/test")
+public class TestController {
+
+ @GetMapping
+ public ModelAndView getTestData() {
+ ModelAndView mv = new ModelAndView();
+ mv.setViewName("welcome");
+ mv.getModel().put("data", "Welcome home man");
+
+ return mv;
+ }
+}
\ No newline at end of file
diff --git a/spring-all/src/main/java/org/baeldung/controller/student/Student.java b/spring-all/src/main/java/org/baeldung/controller/student/Student.java
new file mode 100644
index 0000000000..ee706d7028
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/controller/student/Student.java
@@ -0,0 +1,33 @@
+package org.baeldung.controller.student;
+
+public class Student {
+ private String name;
+
+ private int id;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ @Override
+ public int hashCode(){
+ return this.id;
+ }
+
+ @Override
+ public boolean equals(Object obj){
+ return this.name.equals(((Student)obj).getName());
+ }
+}
\ No newline at end of file
diff --git a/spring-all/src/main/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationsTestController.java b/spring-all/src/main/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationsTestController.java
new file mode 100644
index 0000000000..df1d173bd2
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationsTestController.java
@@ -0,0 +1,14 @@
+package org.baeldung.spring43.attributeannotations;
+
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/test")
+public class AttributeAnnotationsTestController {
+
+ @GetMapping
+ public String get(@SessionAttribute String login, @RequestAttribute String query) {
+ return String.format("login = %s, query = %s", login, query);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-all/src/main/java/org/baeldung/spring43/attributeannotations/ParamInterceptor.java b/spring-all/src/main/java/org/baeldung/spring43/attributeannotations/ParamInterceptor.java
new file mode 100644
index 0000000000..9cf6020a93
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/attributeannotations/ParamInterceptor.java
@@ -0,0 +1,17 @@
+package org.baeldung.spring43.attributeannotations;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+public class ParamInterceptor extends HandlerInterceptorAdapter {
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+ request.getSession().setAttribute("login", "john");
+ request.setAttribute("query", "invoices");
+ return super.preHandle(request, response, handler);
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/cache/Foo.java b/spring-all/src/main/java/org/baeldung/spring43/cache/Foo.java
new file mode 100644
index 0000000000..4abd3cc813
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/cache/Foo.java
@@ -0,0 +1,29 @@
+package org.baeldung.spring43.cache;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Foo {
+
+ private static final Logger log = LoggerFactory.getLogger(Foo.class);
+
+ private static final AtomicInteger instanceCount = new AtomicInteger(0);
+
+
+ private final int instanceNum;
+
+ public Foo() {
+ instanceNum = instanceCount.incrementAndGet();
+ }
+
+ public static int getInstanceCount() {
+ return instanceCount.get();
+ }
+
+ public void printInstanceNumber() {
+ log.info("Foo instance number: {}", instanceNum);
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/cache/FooService.java b/spring-all/src/main/java/org/baeldung/spring43/cache/FooService.java
new file mode 100644
index 0000000000..ad4c8b395f
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/cache/FooService.java
@@ -0,0 +1,14 @@
+package org.baeldung.spring43.cache;
+
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+@Service
+public class FooService {
+
+ @Cacheable(cacheNames = "foos", sync = true)
+ public Foo getFoo(String id) {
+ return new Foo();
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/composedmapping/Appointment.java b/spring-all/src/main/java/org/baeldung/spring43/composedmapping/Appointment.java
new file mode 100644
index 0000000000..af06249768
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/composedmapping/Appointment.java
@@ -0,0 +1,5 @@
+package org.baeldung.spring43.composedmapping;
+
+public class Appointment {
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/composedmapping/AppointmentService.java b/spring-all/src/main/java/org/baeldung/spring43/composedmapping/AppointmentService.java
new file mode 100644
index 0000000000..c4c5e82f65
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/composedmapping/AppointmentService.java
@@ -0,0 +1,9 @@
+package org.baeldung.spring43.composedmapping;
+
+import java.util.Map;
+
+public interface AppointmentService {
+
+ Map getAppointmentsForToday();
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/composedmapping/AppointmentsController.java b/spring-all/src/main/java/org/baeldung/spring43/composedmapping/AppointmentsController.java
new file mode 100644
index 0000000000..9f3c8729d8
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/composedmapping/AppointmentsController.java
@@ -0,0 +1,26 @@
+package org.baeldung.spring43.composedmapping;
+
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+@RequestMapping("/appointments")
+public class AppointmentsController {
+
+ private final AppointmentService appointmentService;
+
+ @Autowired
+ public AppointmentsController(AppointmentService appointmentService) {
+ this.appointmentService = appointmentService;
+ }
+
+ @GetMapping
+ public Map get() {
+ return appointmentService.getAppointmentsForToday();
+ }
+
+}
\ No newline at end of file
diff --git a/spring-all/src/main/java/org/baeldung/spring43/ctor/FooRepository.java b/spring-all/src/main/java/org/baeldung/spring43/ctor/FooRepository.java
new file mode 100644
index 0000000000..96dbeb8642
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/ctor/FooRepository.java
@@ -0,0 +1,5 @@
+package org.baeldung.spring43.ctor;
+
+public class FooRepository {
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/ctor/FooService.java b/spring-all/src/main/java/org/baeldung/spring43/ctor/FooService.java
new file mode 100644
index 0000000000..bf92d1bd32
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/ctor/FooService.java
@@ -0,0 +1,15 @@
+package org.baeldung.spring43.ctor;
+
+public class FooService {
+
+ private final FooRepository repository;
+
+ public FooService(FooRepository repository) {
+ this.repository = repository;
+ }
+
+ public FooRepository getRepository() {
+ return repository;
+ }
+
+}
\ No newline at end of file
diff --git a/spring-all/src/main/java/org/baeldung/spring43/defaultmethods/DateHolder.java b/spring-all/src/main/java/org/baeldung/spring43/defaultmethods/DateHolder.java
new file mode 100644
index 0000000000..9ae62cf484
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/defaultmethods/DateHolder.java
@@ -0,0 +1,18 @@
+package org.baeldung.spring43.defaultmethods;
+
+import java.time.LocalDate;
+
+public class DateHolder implements IDateHolder {
+
+ private LocalDate localDate;
+
+ @Override
+ public LocalDate getLocalDate() {
+ return localDate;
+ }
+
+ @Override
+ public void setLocalDate(LocalDate localDate) {
+ this.localDate = localDate;
+ }
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/defaultmethods/IDateHolder.java b/spring-all/src/main/java/org/baeldung/spring43/defaultmethods/IDateHolder.java
new file mode 100644
index 0000000000..e37d27f9fc
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/defaultmethods/IDateHolder.java
@@ -0,0 +1,16 @@
+package org.baeldung.spring43.defaultmethods;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+public interface IDateHolder {
+
+ LocalDate getLocalDate();
+
+ void setLocalDate(LocalDate localDate);
+
+ default void setStringDate(String stringDate) {
+ setLocalDate(LocalDate.parse(stringDate, DateTimeFormatter.ofPattern("dd.MM.yyyy")));
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/depresolution/FooRepository.java b/spring-all/src/main/java/org/baeldung/spring43/depresolution/FooRepository.java
new file mode 100644
index 0000000000..313f6fc8c5
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/depresolution/FooRepository.java
@@ -0,0 +1,8 @@
+package org.baeldung.spring43.depresolution;
+
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class FooRepository {
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/depresolution/FooService.java b/spring-all/src/main/java/org/baeldung/spring43/depresolution/FooService.java
new file mode 100644
index 0000000000..b76fa84749
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/depresolution/FooService.java
@@ -0,0 +1,18 @@
+package org.baeldung.spring43.depresolution;
+
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.stereotype.Service;
+
+@Service
+public class FooService {
+
+ private final FooRepository repository;
+
+ public FooService(ObjectProvider repositoryProvider) {
+ this.repository = repositoryProvider.getIfUnique();
+ }
+
+ public FooRepository getRepository() {
+ return repository;
+ }
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/AppPreferences.java b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/AppPreferences.java
new file mode 100644
index 0000000000..45b90c4609
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/AppPreferences.java
@@ -0,0 +1,10 @@
+package org.baeldung.spring43.scopeannotations;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.annotation.ApplicationScope;
+
+@Component
+@ApplicationScope
+public class AppPreferences extends InstanceCountingService {
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/InstanceCountingService.java b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/InstanceCountingService.java
new file mode 100644
index 0000000000..4fb90566d8
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/InstanceCountingService.java
@@ -0,0 +1,15 @@
+package org.baeldung.spring43.scopeannotations;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class InstanceCountingService {
+
+ private static final AtomicInteger instanceCount = new AtomicInteger(0);
+
+ private final int instanceNumber = instanceCount.incrementAndGet();
+
+ public int getInstanceNumber() {
+ return instanceNumber;
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/LoginAction.java b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/LoginAction.java
new file mode 100644
index 0000000000..60017b4b94
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/LoginAction.java
@@ -0,0 +1,10 @@
+package org.baeldung.spring43.scopeannotations;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.annotation.RequestScope;
+
+@Component
+@RequestScope
+public class LoginAction extends InstanceCountingService {
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/ScopeTestController.java b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/ScopeTestController.java
new file mode 100644
index 0000000000..8f4390dfc0
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/ScopeTestController.java
@@ -0,0 +1,36 @@
+package org.baeldung.spring43.scopeannotations;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/appointments")
+public class ScopeTestController {
+
+ @Autowired
+ private LoginAction loginAction;
+
+ @Autowired
+ private UserPreferences userPreferences;
+
+ @Autowired
+ private AppPreferences appPreferences;
+
+ @GetMapping("/request")
+ public String getRequestNumber() {
+ return Integer.toString(loginAction.getInstanceNumber());
+ }
+
+ @GetMapping("/session")
+ public String getSessionNumber() {
+ return Integer.toString(userPreferences.getInstanceNumber());
+ }
+
+ @GetMapping("/application")
+ public String getApplicationNumber() {
+ return Integer.toString(appPreferences.getInstanceNumber());
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/UserPreferences.java b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/UserPreferences.java
new file mode 100644
index 0000000000..ce49c4b1fe
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/UserPreferences.java
@@ -0,0 +1,10 @@
+package org.baeldung.spring43.scopeannotations;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.annotation.SessionScope;
+
+@Component
+@SessionScope
+public class UserPreferences extends InstanceCountingService {
+
+}
diff --git a/spring-all/src/main/resources/defaultmethods-context.xml b/spring-all/src/main/resources/defaultmethods-context.xml
new file mode 100644
index 0000000000..2b55037405
--- /dev/null
+++ b/spring-all/src/main/resources/defaultmethods-context.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-all/src/main/resources/implicit-ctor-context.xml b/spring-all/src/main/resources/implicit-ctor-context.xml
new file mode 100644
index 0000000000..c978ca17bd
--- /dev/null
+++ b/spring-all/src/main/resources/implicit-ctor-context.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
diff --git a/spring-all/src/main/resources/springAsync-config.xml b/spring-all/src/main/resources/springAsync-config.xml
index 8ed5f1319d..34e8b33f45 100644
--- a/spring-all/src/main/resources/springAsync-config.xml
+++ b/spring-all/src/main/resources/springAsync-config.xml
@@ -9,6 +9,6 @@
-
+
\ No newline at end of file
diff --git a/spring-all/src/main/resources/test-mvc.xml b/spring-all/src/main/resources/test-mvc.xml
new file mode 100644
index 0000000000..15f950ed4f
--- /dev/null
+++ b/spring-all/src/main/resources/test-mvc.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ /WEB-INF/
+
+
+ .jsp
+
+
+
\ No newline at end of file
diff --git a/spring-all/src/main/webapp/WEB-INF/web.xml b/spring-all/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..4e0e7a231c
--- /dev/null
+++ b/spring-all/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,27 @@
+
+
+
+ test-mvc
+
+ org.springframework.web.servlet.DispatcherServlet
+
+ 1
+
+ contextConfigLocation
+ /WEB-INF/test-mvc.xml
+
+
+
+
+ test-mvc
+ /test/*
+
+
+
+ /WEB-INF/index.jsp
+
+
diff --git a/spring-all/src/main/webapp/WEB-INF/welcome.jsp b/spring-all/src/main/webapp/WEB-INF/welcome.jsp
new file mode 100644
index 0000000000..61ee4bc7d6
--- /dev/null
+++ b/spring-all/src/main/webapp/WEB-INF/welcome.jsp
@@ -0,0 +1,12 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+ pageEncoding="UTF-8"%>
+
+
+
+
+Insert title here
+
+
+Data returned is ${data}
+
+
\ No newline at end of file
diff --git a/spring-all/src/test/java/org/baeldung/akka/SpringAkkaTest.java b/spring-all/src/test/java/org/baeldung/akka/SpringAkkaTest.java
new file mode 100644
index 0000000000..6162b02307
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/akka/SpringAkkaTest.java
@@ -0,0 +1,48 @@
+package org.baeldung.akka;
+
+import java.util.concurrent.TimeUnit;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.util.Timeout;
+import org.baeldung.akka.GreetingActor.Greet;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+import scala.concurrent.Await;
+import scala.concurrent.Future;
+import scala.concurrent.duration.FiniteDuration;
+
+import static akka.pattern.Patterns.ask;
+import static org.baeldung.akka.SpringExtension.SPRING_EXTENSION_PROVIDER;
+
+@ContextConfiguration(classes = AppConfiguration.class)
+public class SpringAkkaTest extends AbstractJUnit4SpringContextTests {
+
+ @Autowired
+ private ActorSystem system;
+
+ @Test
+ public void whenCallingGreetingActor_thenActorGreetsTheCaller() throws Exception {
+ ActorRef greeter = system.actorOf(
+ SPRING_EXTENSION_PROVIDER.get(system)
+ .props("greetingActor"), "greeter");
+
+ FiniteDuration duration = FiniteDuration.create(1, TimeUnit.SECONDS);
+ Timeout timeout = Timeout.durationToTimeout(duration);
+
+ Future result = ask(greeter, new Greet("John"), timeout);
+
+ Assert.assertEquals("Hello, John", Await.result(result, duration));
+ }
+
+ @After
+ public void tearDown() {
+ system.shutdown();
+ system.awaitTermination();
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/controller/ControllerTest.java b/spring-all/src/test/java/org/baeldung/controller/ControllerTest.java
new file mode 100644
index 0000000000..f5e41cd5a2
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/controller/ControllerTest.java
@@ -0,0 +1,83 @@
+package org.baeldung.controller;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.servlet.ModelAndView;
+
+import org.baeldung.controller.student.Student;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@WebAppConfiguration
+@ContextConfiguration({"classpath:test-mvc.xml"})
+public class ControllerTest {
+
+ private MockMvc mockMvc;
+
+ @Autowired
+ private WebApplicationContext wac;
+
+ private Student selectedStudent;
+
+ @Before
+ public void setUp() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
+
+ selectedStudent = new Student();
+ selectedStudent.setId(1);
+ selectedStudent.setName("Peter");
+ }
+
+ @Test
+ public void testTestController() throws Exception {
+
+ ModelAndView mv = this.mockMvc.perform(MockMvcRequestBuilders.get("/test/"))
+ .andReturn()
+ .getModelAndView();
+
+ // validate modal data
+ Assert.assertSame(mv.getModelMap().get("data").toString(), "Welcome home man");
+
+ // validate view name
+ Assert.assertSame(mv.getViewName(), "welcome");
+ }
+
+ @Test
+ public void testRestController() throws Exception {
+
+ String responseBody = this.mockMvc.perform(MockMvcRequestBuilders.get("/student/{studentId}", 1))
+ .andReturn().getResponse()
+ .getContentAsString();
+
+ ObjectMapper reader = new ObjectMapper();
+
+ Student studentDetails = reader.readValue(responseBody, Student.class);
+
+ Assert.assertEquals(selectedStudent, studentDetails);
+
+ }
+
+ @Test
+ public void testRestAnnotatedController() throws Exception {
+
+ String responseBody = this.mockMvc.perform(MockMvcRequestBuilders.get("/annotated/student/{studentId}", 1))
+ .andReturn().getResponse()
+ .getContentAsString();
+
+ ObjectMapper reader = new ObjectMapper();
+
+ Student studentDetails = reader.readValue(responseBody, Student.class);
+
+ Assert.assertEquals(selectedStudent, studentDetails);
+ }
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationConfiguration.java
new file mode 100644
index 0000000000..97ae651473
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationConfiguration.java
@@ -0,0 +1,30 @@
+package org.baeldung.spring43.attributeannotations;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.ViewResolver;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.view.InternalResourceViewResolver;
+
+@Configuration
+@ComponentScan
+@EnableWebMvc
+public class AttributeAnnotationConfiguration extends WebMvcConfigurerAdapter {
+
+ @Bean
+ public ViewResolver viewResolver() {
+ InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
+ viewResolver.setPrefix("/WEB-INF/jsp/view/");
+ viewResolver.setSuffix(".jsp");
+ return viewResolver;
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(new ParamInterceptor());
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationTest.java b/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationTest.java
new file mode 100644
index 0000000000..aa3acb113f
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationTest.java
@@ -0,0 +1,45 @@
+package org.baeldung.spring43.attributeannotations;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@ContextConfiguration(classes = AttributeAnnotationConfiguration.class)
+@WebAppConfiguration
+public class AttributeAnnotationTest extends AbstractJUnit4SpringContextTests {
+
+ private MockMvc mockMvc;
+
+ @Autowired
+ private WebApplicationContext wac;
+
+ @Before
+ public void setup() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
+ .build();
+ }
+
+ @Test
+ public void whenInterceptorAddsRequestAndSessionParams_thenParamsInjectedWithAttributesAnnotations() throws Exception {
+ String result = this.mockMvc.perform(get("/test")
+ .accept(MediaType.ALL))
+ .andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ Assert.assertEquals("login = john, query = invoices", result);
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsConfiguration.java
new file mode 100644
index 0000000000..e4610e5a83
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsConfiguration.java
@@ -0,0 +1,25 @@
+package org.baeldung.spring43.cache;
+
+import java.util.Collections;
+
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.concurrent.ConcurrentMapCache;
+import org.springframework.cache.support.SimpleCacheManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan
+@EnableCaching
+public class CacheRefinementsConfiguration {
+
+ @Bean
+ public CacheManager cacheManager() {
+ SimpleCacheManager manager = new SimpleCacheManager();
+ manager.setCaches(Collections.singletonList(new ConcurrentMapCache("foos")));
+ return manager;
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsTest.java b/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsTest.java
new file mode 100644
index 0000000000..bfd6e5047c
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsTest.java
@@ -0,0 +1,31 @@
+package org.baeldung.spring43.cache;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+
+import static org.junit.Assert.assertEquals;
+
+@ContextConfiguration(classes = CacheRefinementsConfiguration.class)
+public class CacheRefinementsTest extends AbstractJUnit4SpringContextTests {
+
+ private ExecutorService executorService = Executors.newFixedThreadPool(10);
+
+ @Autowired
+ private FooService service;
+
+ @Test
+ public void whenMultipleThreadsExecuteCacheableMethodWithSyncTrue_thenMethodIsExecutedOnlyOnce() throws InterruptedException {
+ for (int i = 0; i < 10; i++) {
+ executorService.execute(() -> service.getFoo("test").printInstanceNumber());
+ }
+ executorService.awaitTermination(1, TimeUnit.SECONDS);
+ assertEquals(Foo.getInstanceCount(), 1);
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingConfiguration.java
new file mode 100644
index 0000000000..46bf3d8847
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingConfiguration.java
@@ -0,0 +1,36 @@
+package org.baeldung.spring43.composedmapping;
+
+import java.util.Collections;
+
+import org.easymock.EasyMock;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.ViewResolver;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.view.InternalResourceViewResolver;
+
+import static org.easymock.EasyMock.*;
+
+@Configuration
+@ComponentScan
+@EnableWebMvc
+public class ComposedMappingConfiguration {
+
+ @Bean
+ public ViewResolver viewResolver() {
+ InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
+ viewResolver.setPrefix("/WEB-INF/jsp/view/");
+ viewResolver.setSuffix(".jsp");
+ return viewResolver;
+ }
+
+ @Bean
+ public AppointmentService appointmentBook() {
+ AppointmentService book = EasyMock.mock(AppointmentService.class);
+ EasyMock.expect(book.getAppointmentsForToday()).andReturn(Collections.emptyMap());
+ replay(book);
+ return book;
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingTest.java b/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingTest.java
new file mode 100644
index 0000000000..04fabbc834
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingTest.java
@@ -0,0 +1,44 @@
+package org.baeldung.spring43.composedmapping;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.easymock.EasyMock.verify;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@ContextConfiguration(classes = ComposedMappingConfiguration.class)
+@WebAppConfiguration
+public class ComposedMappingTest extends AbstractJUnit4SpringContextTests {
+
+ @Autowired
+ private AppointmentService appointmentService;
+
+ private MockMvc mockMvc;
+
+ @Autowired
+ private WebApplicationContext wac;
+
+ @Before
+ public void setup() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
+ .build();
+ }
+
+ @Test
+ public void whenRequestingMethodWithGetMapping_thenReceiving200Answer() throws Exception {
+ this.mockMvc.perform(get("/appointments")
+ .accept(MediaType.ALL))
+ .andExpect(status().isOk());
+ verify(appointmentService);
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/ctor/ConfigurationConstructorInjectionTest.java b/spring-all/src/test/java/org/baeldung/spring43/ctor/ConfigurationConstructorInjectionTest.java
new file mode 100644
index 0000000000..82caae15fe
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/ctor/ConfigurationConstructorInjectionTest.java
@@ -0,0 +1,21 @@
+package org.baeldung.spring43.ctor;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+
+import static org.junit.Assert.assertNotNull;
+
+@ContextConfiguration(classes = {FooRepositoryConfiguration.class, FooServiceConfiguration.class})
+public class ConfigurationConstructorInjectionTest extends AbstractJUnit4SpringContextTests {
+
+ @Autowired
+ public FooService fooService;
+
+ @Test
+ public void whenSingleCtorInConfiguration_thenContextLoadsNormally() {
+ assertNotNull(fooService.getRepository());
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/ctor/FooRepositoryConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/ctor/FooRepositoryConfiguration.java
new file mode 100644
index 0000000000..a05a36529f
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/ctor/FooRepositoryConfiguration.java
@@ -0,0 +1,14 @@
+package org.baeldung.spring43.ctor;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class FooRepositoryConfiguration {
+
+ @Bean
+ public FooRepository fooRepository() {
+ return new FooRepository();
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/ctor/FooServiceConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/ctor/FooServiceConfiguration.java
new file mode 100644
index 0000000000..41f1719320
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/ctor/FooServiceConfiguration.java
@@ -0,0 +1,19 @@
+package org.baeldung.spring43.ctor;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class FooServiceConfiguration {
+
+ private final FooRepository repository;
+
+ public FooServiceConfiguration(FooRepository repository) {
+ this.repository = repository;
+ }
+
+ @Bean
+ public FooService fooService() {
+ return new FooService(this.repository);
+ }
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/ctor/ImplicitConstructorTest.java b/spring-all/src/test/java/org/baeldung/spring43/ctor/ImplicitConstructorTest.java
new file mode 100644
index 0000000000..be0cf77a62
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/ctor/ImplicitConstructorTest.java
@@ -0,0 +1,21 @@
+package org.baeldung.spring43.ctor;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+
+import static org.junit.Assert.assertNotNull;
+
+@ContextConfiguration("classpath:implicit-ctor-context.xml")
+public class ImplicitConstructorTest extends AbstractJUnit4SpringContextTests {
+
+ @Autowired
+ private FooService fooService;
+
+ @Test
+ public void whenBeanWithoutAutowiredCtor_thenInjectIntoSingleCtor() {
+ assertNotNull(fooService.getRepository());
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/DefaultMethodsInjectionTest.java b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/DefaultMethodsInjectionTest.java
new file mode 100644
index 0000000000..e29d89a679
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/DefaultMethodsInjectionTest.java
@@ -0,0 +1,23 @@
+package org.baeldung.spring43.defaultmethods;
+
+import java.time.LocalDate;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+
+import static org.junit.Assert.assertEquals;
+
+@ContextConfiguration("classpath:defaultmethods-context.xml")
+public class DefaultMethodsInjectionTest extends AbstractJUnit4SpringContextTests {
+
+ @Autowired
+ private IDateHolder dateHolder;
+
+ @Test
+ public void whenInjectingToDefaultInterfaceMethod_thenInjectionShouldHappen() {
+ assertEquals(LocalDate.of(1982, 10, 15), dateHolder.getLocalDate());
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/ITransactionalTest.java b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/ITransactionalTest.java
new file mode 100644
index 0000000000..c7b95bced4
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/ITransactionalTest.java
@@ -0,0 +1,22 @@
+package org.baeldung.spring43.defaultmethods;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.test.context.transaction.AfterTransaction;
+import org.springframework.test.context.transaction.BeforeTransaction;
+
+public interface ITransactionalTest {
+
+ Logger log = LoggerFactory.getLogger(ITransactionalTest.class);
+
+ @BeforeTransaction
+ default void beforeTransaction() {
+ log.info("Opening transaction");
+ }
+
+ @AfterTransaction
+ default void afterTransaction() {
+ log.info("Closing transaction");
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTest.java b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTest.java
new file mode 100644
index 0000000000..89c96ba1d4
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTest.java
@@ -0,0 +1,14 @@
+package org.baeldung.spring43.defaultmethods;
+
+import org.junit.Test;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
+
+@ContextConfiguration(classes = TransactionalTestConfiguration.class)
+public class TransactionalTest extends AbstractTransactionalJUnit4SpringContextTests implements ITransactionalTest {
+
+ @Test
+ public void whenDefaultMethodAnnotatedWithBeforeTransaction_thenDefaultMethodIsExecuted() {
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTestConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTestConfiguration.java
new file mode 100644
index 0000000000..946b19d00d
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTestConfiguration.java
@@ -0,0 +1,30 @@
+package org.baeldung.spring43.defaultmethods;
+
+
+import javax.sql.DataSource;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.jdbc.datasource.SimpleDriverDataSource;
+import org.springframework.transaction.PlatformTransactionManager;
+
+@Configuration
+public class TransactionalTestConfiguration {
+
+ @Bean
+ public DataSource getDataSource() {
+ SimpleDriverDataSource simpleDriverDataSource = new SimpleDriverDataSource();
+ simpleDriverDataSource.setDriverClass(org.hsqldb.jdbcDriver.class);
+ simpleDriverDataSource.setUrl("jdbc:hsqldb:mem:app-db");
+ simpleDriverDataSource.setUsername("sa");
+ simpleDriverDataSource.setPassword("");
+ return simpleDriverDataSource;
+ }
+
+ @Bean
+ public PlatformTransactionManager transactionManager() {
+ return new DataSourceTransactionManager(getDataSource());
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderConfiguration.java
new file mode 100644
index 0000000000..530c4d9f4a
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderConfiguration.java
@@ -0,0 +1,9 @@
+package org.baeldung.spring43.depresolution;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan
+public class ObjectProviderConfiguration {
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderTest.java b/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderTest.java
new file mode 100644
index 0000000000..eeeb005f81
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderTest.java
@@ -0,0 +1,23 @@
+package org.baeldung.spring43.depresolution;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+
+import static org.junit.Assert.assertNotNull;
+
+@ContextConfiguration(classes = ObjectProviderConfiguration.class)
+public class ObjectProviderTest extends AbstractJUnit4SpringContextTests {
+
+ @Autowired
+ private FooService fooService;
+
+ @Test
+ public void whenArgumentIsObjectProvider_thenObjectProviderInjected() {
+
+ assertNotNull(fooService.getRepository());
+
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsConfiguration.java
new file mode 100644
index 0000000000..24c1ec2f34
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsConfiguration.java
@@ -0,0 +1,23 @@
+package org.baeldung.spring43.scopeannotations;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.ViewResolver;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.view.InternalResourceViewResolver;
+
+@Configuration
+@ComponentScan
+@EnableWebMvc
+public class ScopeAnnotationsConfiguration {
+
+ @Bean
+ public ViewResolver viewResolver() {
+ InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
+ viewResolver.setPrefix("/WEB-INF/jsp/view/");
+ viewResolver.setSuffix(".jsp");
+ return viewResolver;
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsTest.java b/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsTest.java
new file mode 100644
index 0000000000..b696760f68
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsTest.java
@@ -0,0 +1,110 @@
+package org.baeldung.spring43.scopeannotations;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockHttpSession;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@ContextConfiguration(classes = ScopeAnnotationsConfiguration.class)
+@WebAppConfiguration
+public class ScopeAnnotationsTest extends AbstractJUnit4SpringContextTests {
+
+ private MockMvc mockMvc;
+
+ @Autowired
+ private WebApplicationContext wac;
+
+ @Before
+ public void setup() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
+ .build();
+ }
+
+ @Test
+ public void whenDifferentRequests_thenDifferentInstancesOfRequestScopedBeans() throws Exception {
+ MockHttpSession session = new MockHttpSession();
+
+ String requestScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/request")
+ .session(session)
+ .accept(MediaType.ALL)).andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ String requestScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/request")
+ .session(session)
+ .accept(MediaType.ALL)).andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ assertNotEquals(requestScopedServiceInstanceNumber1, requestScopedServiceInstanceNumber2);
+ }
+
+ @Test
+ public void whenDifferentSessions_thenDifferentInstancesOfSessionScopedBeans() throws Exception {
+
+ MockHttpSession session1 = new MockHttpSession();
+ MockHttpSession session2 = new MockHttpSession();
+
+ String sessionScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/session")
+ .session(session1)
+ .accept(MediaType.ALL)).andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+ String sessionScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/session")
+ .session(session1)
+ .accept(MediaType.ALL)).andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+ String sessionScopedServiceInstanceNumber3 = this.mockMvc.perform(get("/appointments/session")
+ .session(session2)
+ .accept(MediaType.ALL)).andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ assertEquals(sessionScopedServiceInstanceNumber1, sessionScopedServiceInstanceNumber2);
+
+ assertNotEquals(sessionScopedServiceInstanceNumber1, sessionScopedServiceInstanceNumber3);
+
+ }
+
+ @Test
+ public void whenDifferentSessionsAndRequests_thenAlwaysSingleApplicationScopedBean() throws Exception {
+
+ MockHttpSession session1 = new MockHttpSession();
+ MockHttpSession session2 = new MockHttpSession();
+
+ String applicationScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/application")
+ .session(session1)
+ .accept(MediaType.ALL)).andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+ String applicationScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/application")
+ .session(session2)
+ .accept(MediaType.ALL)).andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ assertEquals(applicationScopedServiceInstanceNumber1, applicationScopedServiceInstanceNumber2);
+
+ }
+
+}
diff --git a/spring-apache-camel/.classpath b/spring-apache-camel/.classpath
deleted file mode 100644
index 698778fef3..0000000000
--- a/spring-apache-camel/.classpath
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-apache-camel/.project b/spring-apache-camel/.project
deleted file mode 100644
index 7725877f6a..0000000000
--- a/spring-apache-camel/.project
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
- spring-apache-camel
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
-
-
diff --git a/spring-batch/.classpath b/spring-batch/.classpath
deleted file mode 100644
index e7ac9faf11..0000000000
--- a/spring-batch/.classpath
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-batch/.project b/spring-batch/.project
deleted file mode 100644
index 0159a7237c..0000000000
--- a/spring-batch/.project
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
- spring-batch
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
-
-
diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml
index 368dfa19c1..ada02a9965 100644
--- a/spring-boot/pom.xml
+++ b/spring-boot/pom.xml
@@ -12,7 +12,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.3.6.RELEASE
+ 1.4.0.RC1
@@ -60,6 +60,26 @@
spring-boot-starter-test
test
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ com.jayway.jsonpath
+ json-path
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+
+
+ org.subethamail
+ subethasmtp
+ 3.1.7
+ test
+
@@ -96,4 +116,41 @@
+
+
+ spring-snapshots
+ Spring Snapshots
+ https://repo.spring.io/snapshot
+
+ true
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+ false
+
+
+
+
+
+ spring-snapshots
+ Spring Snapshots
+ https://repo.spring.io/snapshot
+
+ true
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+ false
+
+
+
+
diff --git a/spring-boot/src/main/java/org/baeldung/Application.java b/spring-boot/src/main/java/org/baeldung/Application.java
new file mode 100644
index 0000000000..aae0c427a9
--- /dev/null
+++ b/spring-boot/src/main/java/org/baeldung/Application.java
@@ -0,0 +1,13 @@
+package org.baeldung;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.context.ApplicationContext;
+
+@org.springframework.boot.autoconfigure.SpringBootApplication
+public class Application {
+ private static ApplicationContext applicationContext;
+
+ public static void main(String[] args) {
+ applicationContext = SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/spring-boot/src/main/java/org/baeldung/client/Details.java b/spring-boot/src/main/java/org/baeldung/client/Details.java
new file mode 100644
index 0000000000..2ae3adc38f
--- /dev/null
+++ b/spring-boot/src/main/java/org/baeldung/client/Details.java
@@ -0,0 +1,32 @@
+package org.baeldung.client;
+
+public class Details {
+
+ private String name;
+
+ private String login;
+
+ public Details() {
+ }
+
+ public Details(String name, String login) {
+ this.name = name;
+ this.login = login;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLogin() {
+ return login;
+ }
+
+ public void setLogin(String login) {
+ this.login = login;
+ }
+}
diff --git a/spring-boot/src/main/java/org/baeldung/client/DetailsServiceClient.java b/spring-boot/src/main/java/org/baeldung/client/DetailsServiceClient.java
new file mode 100644
index 0000000000..51fa7c6181
--- /dev/null
+++ b/spring-boot/src/main/java/org/baeldung/client/DetailsServiceClient.java
@@ -0,0 +1,20 @@
+package org.baeldung.client;
+
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+@Service
+public class DetailsServiceClient {
+
+ private final RestTemplate restTemplate;
+
+ public DetailsServiceClient(RestTemplateBuilder restTemplateBuilder) {
+ restTemplate = restTemplateBuilder.build();
+ }
+
+ public Details getUserDetails(String name) {
+ return restTemplate.getForObject("/{name}/details", Details.class, name);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java b/spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java
new file mode 100644
index 0000000000..b6f88e7cd5
--- /dev/null
+++ b/spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java
@@ -0,0 +1,38 @@
+package org.baeldung.controller;
+
+import org.baeldung.domain.GenericEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+public class GenericEntityController {
+ private List entityList = new ArrayList<>();
+
+ {
+ entityList.add(new GenericEntity(1l, "entity_1"));
+ entityList.add(new GenericEntity(2l, "entity_2"));
+ entityList.add(new GenericEntity(3l, "entity_3"));
+ entityList.add(new GenericEntity(4l, "entity_4"));
+ }
+
+ @RequestMapping("/entity/all")
+ public List findAll() {
+ return entityList;
+ }
+
+ @RequestMapping(value = "/entity", method = RequestMethod.POST)
+ public GenericEntity addEntity(GenericEntity entity) {
+ entityList.add(entity);
+ return entity;
+ }
+
+ @RequestMapping("/entity/findby/{id}")
+ public GenericEntity findById(@PathVariable Long id) {
+ return entityList.stream().filter(entity -> entity.getId().equals(id)).findFirst().get();
+ }
+}
diff --git a/spring-boot/src/main/java/org/baeldung/domain/GenericEntity.java b/spring-boot/src/main/java/org/baeldung/domain/GenericEntity.java
new file mode 100644
index 0000000000..7b1d27cb66
--- /dev/null
+++ b/spring-boot/src/main/java/org/baeldung/domain/GenericEntity.java
@@ -0,0 +1,42 @@
+package org.baeldung.domain;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class GenericEntity {
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+ private String value;
+
+ public GenericEntity() {
+ }
+
+ public GenericEntity(String value) {
+ this.value = value;
+ }
+
+ public GenericEntity(Long id, String value) {
+ this.id = id;
+ this.value = value;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/spring-boot/src/main/java/org/baeldung/repository/GenericEntityRepository.java b/spring-boot/src/main/java/org/baeldung/repository/GenericEntityRepository.java
new file mode 100644
index 0000000000..7bb1e6dcdc
--- /dev/null
+++ b/spring-boot/src/main/java/org/baeldung/repository/GenericEntityRepository.java
@@ -0,0 +1,7 @@
+package org.baeldung.repository;
+
+import org.baeldung.domain.GenericEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface GenericEntityRepository extends JpaRepository {
+}
diff --git a/spring-boot/src/main/resources/application.properties b/spring-boot/src/main/resources/application.properties
index 8ee0ed29bc..78bcf4cc05 100644
--- a/spring-boot/src/main/resources/application.properties
+++ b/spring-boot/src/main/resources/application.properties
@@ -1,4 +1,4 @@
-server.port=8083
+server.port=8080
server.contextPath=/springbootapp
management.port=8081
management.address=127.0.0.1
diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootApplicationTest.java b/spring-boot/src/test/java/org/baeldung/SpringBootApplicationTest.java
new file mode 100644
index 0000000000..ac7bcd62a9
--- /dev/null
+++ b/spring-boot/src/test/java/org/baeldung/SpringBootApplicationTest.java
@@ -0,0 +1,52 @@
+package org.baeldung;
+
+import org.baeldung.domain.GenericEntity;
+import org.baeldung.repository.GenericEntityRepository;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import java.nio.charset.Charset;
+
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes = Application.class)
+@WebAppConfiguration
+public class SpringBootApplicationTest {
+ @Autowired
+ private WebApplicationContext webApplicationContext;
+ private MockMvc mockMvc;
+
+
+ @Before
+ public void setupMockMvc() {
+ mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
+ .build();
+ }
+
+ @Test
+ public void givenRequestHasBeenMade_whenMeetsAllOfGivenConditions_thenCorrect() throws Exception {
+ MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
+ MediaType.APPLICATION_JSON.getSubtype(),
+ Charset.forName("utf8"));
+
+ mockMvc.perform(MockMvcRequestBuilders.get("/entity/all")).
+ andExpect(MockMvcResultMatchers.status().isOk()).
+ andExpect(MockMvcResultMatchers.content().contentType(contentType)).
+ andExpect(jsonPath("$", hasSize(4)));
+ }
+}
diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootJPATest.java b/spring-boot/src/test/java/org/baeldung/SpringBootJPATest.java
new file mode 100644
index 0000000000..8a6b5139fe
--- /dev/null
+++ b/spring-boot/src/test/java/org/baeldung/SpringBootJPATest.java
@@ -0,0 +1,27 @@
+package org.baeldung;
+
+import org.baeldung.domain.GenericEntity;
+import org.baeldung.repository.GenericEntityRepository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes = Application.class)
+public class SpringBootJPATest {
+ @Autowired
+ private GenericEntityRepository genericEntityRepository;
+
+ @Test
+ public void givenGenericEntityRepository_whenSaveAndRetreiveEntity_thenOK() {
+ GenericEntity genericEntity = genericEntityRepository.save(new GenericEntity("test"));
+ GenericEntity foundedEntity = genericEntityRepository.findOne(genericEntity.getId());
+ assertNotNull(foundedEntity);
+ assertEquals(genericEntity.getValue(), foundedEntity.getValue());
+ }
+}
diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootMailTest.java b/spring-boot/src/test/java/org/baeldung/SpringBootMailTest.java
new file mode 100644
index 0000000000..d36a7906a3
--- /dev/null
+++ b/spring-boot/src/test/java/org/baeldung/SpringBootMailTest.java
@@ -0,0 +1,82 @@
+package org.baeldung;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.web.context.WebApplicationContext;
+import org.subethamail.wiser.Wiser;
+import org.subethamail.wiser.WiserMessage;
+
+import javax.mail.MessagingException;
+import java.io.IOException;
+import java.util.List;
+
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes = Application.class)
+public class SpringBootMailTest {
+ @Autowired
+ private JavaMailSender javaMailSender;
+
+ private Wiser wiser;
+
+ private String userTo = "user2@localhost";
+ private String userFrom = "user1@localhost";
+ private String subject = "Test subject";
+ private String textMail = "Text subject mail";
+
+ @Before
+ public void setUp() throws Exception {
+ final int TEST_PORT = 8025;
+ wiser = new Wiser(TEST_PORT);
+ wiser.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ wiser.stop();
+ }
+
+ @Test
+ public void givenMail_whenSendAndReceived_thenCorrect() throws Exception {
+ SimpleMailMessage message = composeEmailMessage();
+ javaMailSender.send(message);
+ List messages = wiser.getMessages();
+
+ assertThat(messages, hasSize(1));
+ WiserMessage wiserMessage = messages.get(0);
+ assertEquals(userFrom, wiserMessage.getEnvelopeSender());
+ assertEquals(userTo, wiserMessage.getEnvelopeReceiver());
+ assertEquals(subject, getSubject(wiserMessage));
+ assertEquals(textMail, getMessage(wiserMessage));
+ }
+
+ private String getMessage(WiserMessage wiserMessage) throws MessagingException, IOException {
+ return wiserMessage.getMimeMessage().getContent().toString().trim();
+ }
+
+ private String getSubject(WiserMessage wiserMessage) throws MessagingException {
+ return wiserMessage.getMimeMessage().getSubject();
+ }
+
+
+ private SimpleMailMessage composeEmailMessage() {
+ SimpleMailMessage mailMessage = new SimpleMailMessage();
+ mailMessage.setTo(userTo);
+ mailMessage.setReplyTo(userFrom);
+ mailMessage.setFrom(userFrom);
+ mailMessage.setSubject(subject);
+ mailMessage.setText(textMail);
+ return mailMessage;
+ }
+}
diff --git a/spring-boot/src/test/java/org/baeldung/client/DetailsServiceClientTest.java b/spring-boot/src/test/java/org/baeldung/client/DetailsServiceClientTest.java
new file mode 100644
index 0000000000..c594610be2
--- /dev/null
+++ b/spring-boot/src/test/java/org/baeldung/client/DetailsServiceClientTest.java
@@ -0,0 +1,47 @@
+package org.baeldung.client;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.client.MockRestServiceServer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
+
+@RunWith(SpringRunner.class)
+@RestClientTest(DetailsServiceClient.class)
+public class DetailsServiceClientTest {
+
+ @Autowired
+ private DetailsServiceClient client;
+
+ @Autowired
+ private MockRestServiceServer server;
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @Before
+ public void setUp() throws Exception {
+ String detailsString = objectMapper.writeValueAsString(new Details("John Smith", "john"));
+ this.server.expect(requestTo("/john/details"))
+ .andRespond(withSuccess(detailsString, MediaType.APPLICATION_JSON));
+ }
+
+ @Test
+ public void whenCallingGetUserDetails_thenClientExecutesCorrectCall() throws Exception {
+
+ Details details = this.client.getUserDetails("john");
+
+ assertThat(details.getLogin()).isEqualTo("john");
+ assertThat(details.getName()).isEqualTo("John Smith");
+
+ }
+
+}
diff --git a/spring-boot/src/test/resources/application.properties b/spring-boot/src/test/resources/application.properties
new file mode 100644
index 0000000000..14b190629e
--- /dev/null
+++ b/spring-boot/src/test/resources/application.properties
@@ -0,0 +1,3 @@
+spring.mail.host=localhost
+spring.mail.port=8025
+spring.mail.properties.mail.smtp.auth=false
\ No newline at end of file
diff --git a/spring-cucumber/pom.xml b/spring-cucumber/pom.xml
new file mode 100644
index 0000000000..f3b9c983f0
--- /dev/null
+++ b/spring-cucumber/pom.xml
@@ -0,0 +1,89 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ spring-cucumber
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-cucumber
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.3.5.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+ 1.2.4
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ info.cukes
+ cucumber-core
+ ${cucumber.java.version}
+ test
+
+
+
+ info.cukes
+ cucumber-java
+ ${cucumber.java.version}
+ test
+
+
+
+ info.cukes
+ cucumber-junit
+ ${cucumber.java.version}
+ test
+
+
+
+ info.cukes
+ cucumber-spring
+ ${cucumber.java.version}
+ test
+
+
+
+
+ org.apache.commons
+ commons-io
+ 1.3.2
+
+
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/spring-cucumber/src/main/java/com/baeldung/BaeldungController.java b/spring-cucumber/src/main/java/com/baeldung/BaeldungController.java
new file mode 100644
index 0000000000..0bb249b814
--- /dev/null
+++ b/spring-cucumber/src/main/java/com/baeldung/BaeldungController.java
@@ -0,0 +1,22 @@
+package com.baeldung;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class BaeldungController {
+
+ @RequestMapping(method={RequestMethod.GET},value={"/hello"})
+ public String sayHello(HttpServletResponse response){
+ return "hello";
+ }
+
+ @RequestMapping(method={RequestMethod.POST},value={"/baeldung"})
+ public String sayHelloPost(HttpServletResponse response){
+ return "hello";
+ }
+
+}
diff --git a/spring-cucumber/src/main/java/com/baeldung/SpringDemoApplication.java b/spring-cucumber/src/main/java/com/baeldung/SpringDemoApplication.java
new file mode 100644
index 0000000000..d490b23aa2
--- /dev/null
+++ b/spring-cucumber/src/main/java/com/baeldung/SpringDemoApplication.java
@@ -0,0 +1,19 @@
+package com.baeldung;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.context.web.SpringBootServletInitializer;
+
+@SpringBootApplication
+public class SpringDemoApplication extends SpringBootServletInitializer{
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringDemoApplication.class, args);
+ }
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application){
+ return application.sources(SpringDemoApplication.class);
+ }
+}
diff --git a/spring-cucumber/src/main/java/com/baeldung/VersionController.java b/spring-cucumber/src/main/java/com/baeldung/VersionController.java
new file mode 100644
index 0000000000..7c72a78a05
--- /dev/null
+++ b/spring-cucumber/src/main/java/com/baeldung/VersionController.java
@@ -0,0 +1,14 @@
+package com.baeldung;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class VersionController {
+
+ @RequestMapping(method={RequestMethod.GET},value={"/version"})
+ public String getVersion(){
+ return "1.0";
+ }
+}
diff --git a/spring-cucumber/src/main/resources/application.properties b/spring-cucumber/src/main/resources/application.properties
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/spring-cucumber/src/test/java/com/baeldung/CucumberTest.java b/spring-cucumber/src/test/java/com/baeldung/CucumberTest.java
new file mode 100644
index 0000000000..3e950709b3
--- /dev/null
+++ b/spring-cucumber/src/test/java/com/baeldung/CucumberTest.java
@@ -0,0 +1,11 @@
+package com.baeldung;
+
+import cucumber.api.CucumberOptions;
+import cucumber.api.junit.Cucumber;
+import org.junit.runner.RunWith;
+
+
+@RunWith(Cucumber.class)
+@CucumberOptions(features = "src/test/resources")
+public class CucumberTest{
+}
\ No newline at end of file
diff --git a/spring-cucumber/src/test/java/com/baeldung/HeaderSettingRequestCallback.java b/spring-cucumber/src/test/java/com/baeldung/HeaderSettingRequestCallback.java
new file mode 100644
index 0000000000..1ea72868eb
--- /dev/null
+++ b/spring-cucumber/src/test/java/com/baeldung/HeaderSettingRequestCallback.java
@@ -0,0 +1,34 @@
+package com.baeldung;
+
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.client.ClientHttpRequest;
+import org.springframework.web.client.RequestCallback;
+
+import java.io.IOException;
+import java.util.Map;
+
+
+public class HeaderSettingRequestCallback implements RequestCallback{
+ final Map requestHeaders;
+
+ private String body;
+
+ public HeaderSettingRequestCallback(final Map headers){
+ this.requestHeaders = headers;
+ }
+
+ public void setBody(final String postBody ){
+ this.body = postBody;
+ }
+
+ @Override
+ public void doWithRequest(ClientHttpRequest request) throws IOException{
+ final HttpHeaders clientHeaders = request.getHeaders();
+ for( final Map.Entry entry : requestHeaders.entrySet() ){
+ clientHeaders.add(entry.getKey(),entry.getValue());
+ }
+ if( null != body ){
+ request.getBody().write( body.getBytes() );
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-cucumber/src/test/java/com/baeldung/OtherDefs.java b/spring-cucumber/src/test/java/com/baeldung/OtherDefs.java
new file mode 100644
index 0000000000..428343d06a
--- /dev/null
+++ b/spring-cucumber/src/test/java/com/baeldung/OtherDefs.java
@@ -0,0 +1,17 @@
+package com.baeldung;
+
+import cucumber.api.java.en.Given;
+import cucumber.api.java.en.When;
+
+
+public class OtherDefs extends SpringIntegrationTest{
+ @When("^the client calls /baeldung$")
+ public void the_client_issues_POST_hello() throws Throwable{
+ executePost("http://localhost:8080/baeldung");
+ }
+
+ @Given("^the client calls /hello$")
+ public void the_client_issues_GET_hello() throws Throwable{
+ executeGet("http://localhost:8080/hello");
+ }
+}
\ No newline at end of file
diff --git a/spring-cucumber/src/test/java/com/baeldung/ResponseResults.java b/spring-cucumber/src/test/java/com/baeldung/ResponseResults.java
new file mode 100644
index 0000000000..6890faf8b5
--- /dev/null
+++ b/spring-cucumber/src/test/java/com/baeldung/ResponseResults.java
@@ -0,0 +1,34 @@
+package com.baeldung;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+
+import org.apache.commons.io.IOUtils;
+import org.springframework.http.client.ClientHttpResponse;
+
+
+public class ResponseResults{
+ private final ClientHttpResponse theResponse;
+ private final String body;
+
+ protected ResponseResults(final ClientHttpResponse response) throws IOException{
+ this.theResponse = response;
+ final InputStream bodyInputStream = response.getBody();
+ if (null == bodyInputStream){
+ this.body = "{}";
+ }else{
+ final StringWriter stringWriter = new StringWriter();
+ IOUtils.copy(bodyInputStream, stringWriter);
+ this.body = stringWriter.toString();
+ }
+ }
+
+ protected ClientHttpResponse getTheResponse(){
+ return theResponse;
+ }
+
+ protected String getBody(){
+ return body;
+ }
+}
\ No newline at end of file
diff --git a/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java b/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java
new file mode 100644
index 0000000000..5c85dc9400
--- /dev/null
+++ b/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java
@@ -0,0 +1,102 @@
+package com.baeldung;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.IntegrationTest;
+import org.springframework.boot.test.SpringApplicationContextLoader;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.web.client.ResponseErrorHandler;
+import org.springframework.web.client.ResponseExtractor;
+import org.springframework.web.client.RestTemplate;
+
+
+//@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = SpringDemoApplication.class, loader = SpringApplicationContextLoader.class)
+@WebAppConfiguration
+@IntegrationTest
+public class SpringIntegrationTest {
+ protected static ResponseResults latestResponse = null;
+
+ protected RestTemplate restTemplate = null;
+
+ protected void executeGet(String url) throws IOException{
+ final Map headers = new HashMap<>();
+ headers.put("Accept","application/json");
+ final HeaderSettingRequestCallback requestCallback = new HeaderSettingRequestCallback(headers);
+ final ResponseResultErrorHandler errorHandler = new ResponseResultErrorHandler();
+
+ if (restTemplate == null){
+ restTemplate = new RestTemplate();
+ }
+
+ restTemplate.setErrorHandler(errorHandler);
+ latestResponse = restTemplate.execute(url,
+ HttpMethod.GET,
+ requestCallback,
+ new ResponseExtractor(){
+ @Override
+ public ResponseResults extractData(ClientHttpResponse response) throws IOException {
+ if (errorHandler.hadError){
+ return (errorHandler.getResults());
+ } else{
+ return (new ResponseResults(response));
+ }
+ }
+ });
+
+ }
+
+ protected void executePost(String url) throws IOException{
+ final Map headers = new HashMap<>();
+ headers.put("Accept","application/json");
+ final HeaderSettingRequestCallback requestCallback = new HeaderSettingRequestCallback(headers);
+ final ResponseResultErrorHandler errorHandler = new ResponseResultErrorHandler();
+
+ if (restTemplate == null){
+ restTemplate = new RestTemplate();
+ }
+
+ restTemplate.setErrorHandler(errorHandler);
+ latestResponse = restTemplate.execute(url,
+ HttpMethod.POST,
+ requestCallback,
+ new ResponseExtractor(){
+ @Override
+ public ResponseResults extractData(ClientHttpResponse response) throws IOException {
+ if (errorHandler.hadError){
+ return (errorHandler.getResults());
+ } else{
+ return (new ResponseResults(response));
+ }
+ }
+ });
+
+ }
+
+ private class ResponseResultErrorHandler implements ResponseErrorHandler{
+ private ResponseResults results = null;
+ private Boolean hadError = false;
+
+ private ResponseResults getResults(){
+ return results;
+ }
+
+ @Override
+ public boolean hasError(ClientHttpResponse response) throws IOException{
+ hadError = response.getRawStatusCode() >= 400;
+ return hadError;
+ }
+
+ @Override
+ public void handleError(ClientHttpResponse response) throws IOException {
+ results = new ResponseResults(response);
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-cucumber/src/test/java/com/baeldung/StepDefs.java b/spring-cucumber/src/test/java/com/baeldung/StepDefs.java
new file mode 100644
index 0000000000..3ed25bb09b
--- /dev/null
+++ b/spring-cucumber/src/test/java/com/baeldung/StepDefs.java
@@ -0,0 +1,28 @@
+package com.baeldung;
+
+import cucumber.api.java.en.And;
+import cucumber.api.java.en.Then;
+import cucumber.api.java.en.When;
+import org.springframework.http.HttpStatus;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+public class StepDefs extends SpringIntegrationTest{
+
+ @When("^the client calls /version$")
+ public void the_client_issues_GET_version() throws Throwable{
+ executeGet("http://localhost:8080/version");
+ }
+
+ @Then("^the client receives status code of (\\d+)$")
+ public void the_client_receives_status_code_of(int statusCode) throws Throwable{
+ final HttpStatus currentStatusCode = latestResponse.getTheResponse().getStatusCode();
+ assertThat("status code is incorrect : "+ latestResponse.getBody(), currentStatusCode.value(), is(statusCode) );
+ }
+
+ @And("^the client receives server version (.+)$")
+ public void the_client_receives_server_version_body(String version) throws Throwable{
+ assertThat(latestResponse.getBody(), is(version)) ;
+ }
+}
\ No newline at end of file
diff --git a/spring-cucumber/src/test/resources/baelung.feature b/spring-cucumber/src/test/resources/baelung.feature
new file mode 100644
index 0000000000..21f18db3a4
--- /dev/null
+++ b/spring-cucumber/src/test/resources/baelung.feature
@@ -0,0 +1,9 @@
+Feature: the message can be retrieved
+ Scenario: client makes call to POST /baeldung
+ When the client calls /baeldung
+ Then the client receives status code of 200
+ And the client receives server version hello
+ Scenario: client makes call to GET /hello
+ Given the client calls /hello
+ When the client receives status code of 200
+ Then the client receives server version hello
\ No newline at end of file
diff --git a/spring-cucumber/src/test/resources/version.feature b/spring-cucumber/src/test/resources/version.feature
new file mode 100644
index 0000000000..12f77137ff
--- /dev/null
+++ b/spring-cucumber/src/test/resources/version.feature
@@ -0,0 +1,6 @@
+Feature: the version can be retrieved
+ Scenario: client makes call to GET /version
+ When the client calls /version
+ Then the client receives status code of 200
+ And the client receives server version 1.0
+
\ No newline at end of file
diff --git a/spring-data-cassandra/.classpath b/spring-data-cassandra/.classpath
deleted file mode 100644
index 698778fef3..0000000000
--- a/spring-data-cassandra/.classpath
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-data-cassandra/.project b/spring-data-cassandra/.project
deleted file mode 100644
index 239fa4f002..0000000000
--- a/spring-data-cassandra/.project
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
- spring-data-cassandra
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
-
-
diff --git a/spring-data-couchbase-2/.classpath b/spring-data-couchbase-2/.classpath
deleted file mode 100644
index 679a31b6da..0000000000
--- a/spring-data-couchbase-2/.classpath
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-data-couchbase-2/.project b/spring-data-couchbase-2/.project
deleted file mode 100644
index 1690ad8ce2..0000000000
--- a/spring-data-couchbase-2/.project
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
- spring-data-couchbase-2
- This project is a simple template for a jar utility using Spring.
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
-
-
diff --git a/spring-data-couchbase-2/.springBeans b/spring-data-couchbase-2/.springBeans
deleted file mode 100644
index 0c014a97b6..0000000000
--- a/spring-data-couchbase-2/.springBeans
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
- 1
-
-
-
-
-
-
-
-
-
-
- true
- false
-
-
-
-
-
diff --git a/spring-data-couchbase-2b/.classpath b/spring-data-couchbase-2b/.classpath
deleted file mode 100644
index 450036fc00..0000000000
--- a/spring-data-couchbase-2b/.classpath
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-data-couchbase-2b/.project b/spring-data-couchbase-2b/.project
deleted file mode 100644
index 1690ad8ce2..0000000000
--- a/spring-data-couchbase-2b/.project
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
- spring-data-couchbase-2
- This project is a simple template for a jar utility using Spring.
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
-
-
diff --git a/spring-data-couchbase-2b/.springBeans b/spring-data-couchbase-2b/.springBeans
deleted file mode 100644
index 0c014a97b6..0000000000
--- a/spring-data-couchbase-2b/.springBeans
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
- 1
-
-
-
-
-
-
-
-
-
-
- true
- false
-
-
-
-
-
diff --git a/spring-data-elasticsearch/.classpath b/spring-data-elasticsearch/.classpath
deleted file mode 100644
index 6d7587a819..0000000000
--- a/spring-data-elasticsearch/.classpath
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-data-elasticsearch/.project b/spring-data-elasticsearch/.project
deleted file mode 100644
index 09b9a781ed..0000000000
--- a/spring-data-elasticsearch/.project
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
- spring-data-elasticsearch
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
-
-
diff --git a/spring-data-mongodb/.classpath b/spring-data-mongodb/.classpath
deleted file mode 100644
index baf7c98131..0000000000
--- a/spring-data-mongodb/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-data-mongodb/.project b/spring-data-mongodb/.project
deleted file mode 100644
index 2e5a0d4bac..0000000000
--- a/spring-data-mongodb/.project
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
- spring-data-mongodb
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
-
-
diff --git a/spring-data-neo4j/pom.xml b/spring-data-neo4j/pom.xml
index a5a2e9220a..b0cf62ef2e 100644
--- a/spring-data-neo4j/pom.xml
+++ b/spring-data-neo4j/pom.xml
@@ -1,6 +1,6 @@
-
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
4.0.0
com.baeldung
spring-data-neo4j
@@ -32,6 +32,7 @@
org.springframework.boot
spring-boot-starter-test
+ 1.3.6.RELEASE
test
diff --git a/spring-data-redis/.classpath b/spring-data-redis/.classpath
deleted file mode 100644
index 9ae7bca0fc..0000000000
--- a/spring-data-redis/.classpath
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-data-redis/.project b/spring-data-redis/.project
deleted file mode 100644
index 244dfe15fb..0000000000
--- a/spring-data-redis/.project
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
- spring-data-redis
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
-
-
diff --git a/spring-exceptions/.classpath b/spring-exceptions/.classpath
deleted file mode 100644
index 6b533711d3..0000000000
--- a/spring-exceptions/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-exceptions/.project b/spring-exceptions/.project
deleted file mode 100644
index 810b4a9286..0000000000
--- a/spring-exceptions/.project
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
- spring-exceptions
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-exceptions/.springBeans b/spring-exceptions/.springBeans
deleted file mode 100644
index 7623a7e888..0000000000
--- a/spring-exceptions/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/mvc-servlet.xml
-
-
-
-
diff --git a/spring-exceptions/pom.xml b/spring-exceptions/pom.xml
index 554bb0c170..9ed3285018 100644
--- a/spring-exceptions/pom.xml
+++ b/spring-exceptions/pom.xml
@@ -130,6 +130,32 @@
test
+
+ javax.el
+ el-api
+ 2.2
+
+
+
+ org.apache.derby
+ derby
+ 10.12.1.1
+
+
+ org.apache.derby
+ derbyclient
+ 10.12.1.1
+
+
+ org.apache.derby
+ derbynet
+ 10.12.1.1
+
+
+ org.apache.derby
+ derbytools
+ 10.12.1.1
+
diff --git a/spring-exceptions/src/main/java/org/baeldung/ex/nontransientexception/cause/Cause1NonTransientConfig.java b/spring-exceptions/src/main/java/org/baeldung/ex/nontransientexception/cause/Cause1NonTransientConfig.java
new file mode 100644
index 0000000000..3337e4796d
--- /dev/null
+++ b/spring-exceptions/src/main/java/org/baeldung/ex/nontransientexception/cause/Cause1NonTransientConfig.java
@@ -0,0 +1,76 @@
+package org.baeldung.ex.nontransientexception.cause;
+
+import java.util.Properties;
+
+import javax.sql.DataSource;
+
+import org.apache.tomcat.dbcp.dbcp.BasicDataSource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
+import org.springframework.orm.hibernate4.HibernateTransactionManager;
+import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import com.google.common.base.Preconditions;
+
+@Configuration
+@EnableTransactionManagement
+@PropertySource({ "classpath:persistence-derby.properties" })
+@ComponentScan({ "org.baeldung.persistence" })
+public class Cause1NonTransientConfig {
+
+ @Autowired
+ private Environment env;
+
+ public Cause1NonTransientConfig() {
+ super();
+ }
+
+ @Bean
+ public LocalSessionFactoryBean sessionFactory() {
+ final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
+ sessionFactory.setDataSource(restDataSource());
+ sessionFactory.setPackagesToScan(new String[] { "org.baeldung.persistence.model" });
+ sessionFactory.setHibernateProperties(hibernateProperties());
+
+ return sessionFactory;
+ }
+
+ @Bean
+ public DataSource restDataSource() {
+ final BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
+ dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
+ dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
+ dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
+
+ return dataSource;
+ }
+
+ @Bean
+ public HibernateTransactionManager transactionManager() {
+ final HibernateTransactionManager txManager = new HibernateTransactionManager();
+ txManager.setSessionFactory(sessionFactory().getObject());
+
+ return txManager;
+ }
+
+ @Bean
+ public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
+ return new PersistenceExceptionTranslationPostProcessor();
+ }
+
+ final Properties hibernateProperties() {
+ final Properties hibernateProperties = new Properties();
+ hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
+ hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
+ // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
+ return hibernateProperties;
+ }
+
+}
diff --git a/spring-exceptions/src/main/java/org/baeldung/ex/nontransientexception/cause/Cause4NonTransientConfig.java b/spring-exceptions/src/main/java/org/baeldung/ex/nontransientexception/cause/Cause4NonTransientConfig.java
new file mode 100644
index 0000000000..3543526f37
--- /dev/null
+++ b/spring-exceptions/src/main/java/org/baeldung/ex/nontransientexception/cause/Cause4NonTransientConfig.java
@@ -0,0 +1,75 @@
+package org.baeldung.ex.nontransientexception.cause;
+
+import java.util.Properties;
+
+import javax.sql.DataSource;
+
+import org.apache.tomcat.dbcp.dbcp.BasicDataSource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
+import org.springframework.orm.hibernate4.HibernateTransactionManager;
+import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import com.google.common.base.Preconditions;
+
+@Configuration
+@EnableTransactionManagement
+@PropertySource({ "classpath:persistence-derby.properties" })
+@ComponentScan({ "org.baeldung.persistence" })
+public class Cause4NonTransientConfig {
+
+ @Autowired
+ private Environment env;
+
+ public Cause4NonTransientConfig() {
+ super();
+ }
+
+ @Bean
+ public LocalSessionFactoryBean sessionFactory() {
+ final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
+ sessionFactory.setDataSource(restDataSource());
+ sessionFactory.setPackagesToScan(new String[] { "org.baeldung.persistence.model" });
+ sessionFactory.setHibernateProperties(hibernateProperties());
+
+ return sessionFactory;
+ }
+
+ @Bean
+ public DataSource restDataSource() {
+ final BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
+ dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
+ dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
+ dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
+
+ return dataSource;
+ }
+
+ @Bean
+ public HibernateTransactionManager transactionManager() {
+ final HibernateTransactionManager txManager = new HibernateTransactionManager();
+ txManager.setSessionFactory(sessionFactory().getObject());
+
+ return txManager;
+ }
+
+ @Bean
+ public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
+ return new PersistenceExceptionTranslationPostProcessor();
+ }
+
+ final Properties hibernateProperties() {
+ final Properties hibernateProperties = new Properties();
+ hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
+ hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
+ // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
+ return hibernateProperties;
+ }
+}
diff --git a/spring-exceptions/src/main/resources/persistence-derby.properties b/spring-exceptions/src/main/resources/persistence-derby.properties
new file mode 100644
index 0000000000..49fac9877e
--- /dev/null
+++ b/spring-exceptions/src/main/resources/persistence-derby.properties
@@ -0,0 +1,10 @@
+# jdbc.X
+jdbc.driverClassName=org.apache.derby.jdbc.EmbeddedDriver
+jdbc.url=jdbc:derby:memory:spring_exceptions;create=true
+jdbc.user=tutorialuser
+jdbc.pass=tutorialpass
+
+# hibernate.X
+hibernate.dialect=org.hibernate.dialect.DerbyDialect
+hibernate.show_sql=false
+hibernate.hbm2ddl.auto=create
diff --git a/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/CleanupFailureExceptionTest.java b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/CleanupFailureExceptionTest.java
new file mode 100644
index 0000000000..2f0a8fe09d
--- /dev/null
+++ b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/CleanupFailureExceptionTest.java
@@ -0,0 +1,39 @@
+package org.baeldung.ex.nontransientdataaccessexception;
+
+import org.baeldung.ex.nontransientexception.cause.Cause1NonTransientConfig;
+import org.baeldung.persistence.model.Foo;
+import org.baeldung.persistence.service.IFooService;
+import org.hibernate.SessionFactory;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.CleanupFailureDataAccessException;
+import org.springframework.dao.NonTransientDataAccessException;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { Cause1NonTransientConfig.class }, loader = AnnotationConfigContextLoader.class)
+public class CleanupFailureExceptionTest {
+
+ @Autowired
+ private SessionFactory sessionFactory;
+
+ @Autowired
+ private IFooService fooService;
+
+ @Test
+ public void whenCleanupAfterSaving_thenCleanupException() {
+ try {
+ final Foo fooEntity = new Foo("foo");
+ fooService.create(fooEntity);
+ } finally {
+ try {
+ sessionFactory.close();
+ } catch (final NonTransientDataAccessException exc) {
+ throw new CleanupFailureDataAccessException("Closing connection failed", exc.getCause());
+ }
+ }
+ }
+}
diff --git a/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataIntegrityExceptionTest.java b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataIntegrityExceptionTest.java
new file mode 100644
index 0000000000..aa504223f3
--- /dev/null
+++ b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataIntegrityExceptionTest.java
@@ -0,0 +1,26 @@
+package org.baeldung.ex.nontransientdataaccessexception;
+
+import org.baeldung.ex.nontransientexception.cause.Cause1NonTransientConfig;
+import org.baeldung.persistence.model.Foo;
+import org.baeldung.persistence.service.IFooService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { Cause1NonTransientConfig.class }, loader = AnnotationConfigContextLoader.class)
+public class DataIntegrityExceptionTest {
+
+ @Autowired
+ private IFooService fooService;
+
+ @Test(expected = DataIntegrityViolationException.class)
+ public void whenSavingNullValue_thenDataIntegrityException() {
+ final Foo fooEntity = new Foo();
+ fooService.create(fooEntity);
+ }
+}
diff --git a/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataRetrievalExceptionTest.java b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataRetrievalExceptionTest.java
new file mode 100644
index 0000000000..f5e24e3546
--- /dev/null
+++ b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataRetrievalExceptionTest.java
@@ -0,0 +1,28 @@
+package org.baeldung.ex.nontransientdataaccessexception;
+
+import javax.sql.DataSource;
+
+import org.baeldung.ex.nontransientexception.cause.Cause1NonTransientConfig;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataRetrievalFailureException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { Cause1NonTransientConfig.class }, loader = AnnotationConfigContextLoader.class)
+public class DataRetrievalExceptionTest {
+
+ @Autowired
+ private DataSource restDataSource;
+
+ @Test(expected = DataRetrievalFailureException.class)
+ public void whenRetrievingNonExistentValue_thenDataRetrievalException() {
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(restDataSource);
+
+ jdbcTemplate.queryForObject("select * from foo where id=3", Integer.class);
+ }
+}
diff --git a/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataSourceLookupExceptionTest.java b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataSourceLookupExceptionTest.java
new file mode 100644
index 0000000000..036f99ac8f
--- /dev/null
+++ b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataSourceLookupExceptionTest.java
@@ -0,0 +1,24 @@
+package org.baeldung.ex.nontransientdataaccessexception;
+
+import javax.sql.DataSource;
+
+import org.baeldung.ex.nontransientexception.cause.Cause4NonTransientConfig;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException;
+import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { Cause4NonTransientConfig.class }, loader = AnnotationConfigContextLoader.class)
+public class DataSourceLookupExceptionTest {
+
+ @Test(expected = DataSourceLookupFailureException.class)
+ public void whenLookupNonExistentDataSource_thenDataSourceLookupFailureException() {
+ final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
+ dsLookup.setResourceRef(true);
+ final DataSource dataSource = dsLookup.getDataSource("java:comp/env/jdbc/example_db");
+ }
+}
diff --git a/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/InvalidResourceUsageExceptionTest.java b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/InvalidResourceUsageExceptionTest.java
new file mode 100644
index 0000000000..9afe2533de
--- /dev/null
+++ b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/InvalidResourceUsageExceptionTest.java
@@ -0,0 +1,38 @@
+package org.baeldung.ex.nontransientdataaccessexception;
+
+import javax.sql.DataSource;
+
+import org.baeldung.ex.nontransientexception.cause.Cause1NonTransientConfig;
+import org.baeldung.persistence.service.IFooService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.InvalidDataAccessResourceUsageException;
+import org.springframework.jdbc.BadSqlGrammarException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { Cause1NonTransientConfig.class }, loader = AnnotationConfigContextLoader.class)
+public class InvalidResourceUsageExceptionTest {
+ @Autowired
+ private IFooService fooService;
+
+ @Autowired
+ private DataSource restDataSource;
+
+ @Test(expected = InvalidDataAccessResourceUsageException.class)
+ public void whenRetrievingDataUserNoSelectRights_thenInvalidResourceUsageException() {
+ fooService.findAll();
+ }
+
+ @Test(expected = BadSqlGrammarException.class)
+ public void whenIncorrectSql_thenBadSqlGrammarException() {
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(restDataSource);
+
+ jdbcTemplate.queryForObject("select * fro foo where id=3", Integer.class);
+ }
+
+}
diff --git a/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/PermissionDeniedException.java b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/PermissionDeniedException.java
new file mode 100644
index 0000000000..7f91b52e00
--- /dev/null
+++ b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/PermissionDeniedException.java
@@ -0,0 +1,27 @@
+package org.baeldung.ex.nontransientdataaccessexception;
+
+import org.baeldung.ex.nontransientexception.cause.Cause1NonTransientConfig;
+import org.baeldung.persistence.model.Foo;
+import org.baeldung.persistence.service.IFooService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.PermissionDeniedDataAccessException;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { Cause1NonTransientConfig.class }, loader = AnnotationConfigContextLoader.class)
+public class PermissionDeniedException {
+
+ @Autowired
+ private IFooService fooService;
+
+ @Test(expected = PermissionDeniedDataAccessException.class)
+ public void whenRetrievingDataUserNoSelectRights_thenPermissionDeniedException() {
+ final Foo foo = new Foo("foo");
+ fooService.create(foo);
+ }
+
+}
diff --git a/spring-freemarker/.classpath b/spring-freemarker/.classpath
deleted file mode 100644
index 5c3ac53820..0000000000
--- a/spring-freemarker/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-freemarker/.project b/spring-freemarker/.project
deleted file mode 100644
index 1d63e30744..0000000000
--- a/spring-freemarker/.project
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
- spring4-freemarker-example
-
-
-
-
-
- org.eclipse.wst.jsdt.core.javascriptValidator
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-hibernate3/.classpath b/spring-hibernate3/.classpath
deleted file mode 100644
index 5efa587d72..0000000000
--- a/spring-hibernate3/.classpath
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-hibernate3/.project b/spring-hibernate3/.project
deleted file mode 100644
index 1184fb6b23..0000000000
--- a/spring-hibernate3/.project
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
- spring-hibernate3
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-hibernate3/.springBeans b/spring-hibernate3/.springBeans
deleted file mode 100644
index b854542b58..0000000000
--- a/spring-hibernate3/.springBeans
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
- 1
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-hibernate4/.classpath b/spring-hibernate4/.classpath
deleted file mode 100644
index fa5dbd4c0e..0000000000
--- a/spring-hibernate4/.classpath
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-hibernate4/.project b/spring-hibernate4/.project
deleted file mode 100644
index b687191646..0000000000
--- a/spring-hibernate4/.project
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
- spring-hibernate4
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-hibernate4/.springBeans b/spring-hibernate4/.springBeans
deleted file mode 100644
index b854542b58..0000000000
--- a/spring-hibernate4/.springBeans
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
- 1
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-jpa/.classpath b/spring-jpa/.classpath
deleted file mode 100644
index fa5dbd4c0e..0000000000
--- a/spring-jpa/.classpath
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-jpa/.project b/spring-jpa/.project
deleted file mode 100644
index 235ae29ecf..0000000000
--- a/spring-jpa/.project
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
- spring-jpa
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-jpa/.settings/org.eclipse.wst.common.project.facet.core.xml b/spring-jpa/.settings/org.eclipse.wst.common.project.facet.core.xml
index 9ca0d1c1b7..b1c99d7726 100644
--- a/spring-jpa/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ b/spring-jpa/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -3,4 +3,5 @@
+
diff --git a/spring-jpa/.springBeans b/spring-jpa/.springBeans
deleted file mode 100644
index fc808d21d4..0000000000
--- a/spring-jpa/.springBeans
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-katharsis/.classpath b/spring-katharsis/.classpath
deleted file mode 100644
index 9ae7bca0fc..0000000000
--- a/spring-katharsis/.classpath
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-katharsis/.project b/spring-katharsis/.project
deleted file mode 100644
index 3284dc1199..0000000000
--- a/spring-katharsis/.project
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
- spring-katharsis
-
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/spring-katharsis/.springBeans b/spring-katharsis/.springBeans
deleted file mode 100644
index b854542b58..0000000000
--- a/spring-katharsis/.springBeans
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
- 1
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-mockito/.classpath b/spring-mockito/.classpath
deleted file mode 100644
index 6d7587a819..0000000000
--- a/spring-mockito/.classpath
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-mockito/.project b/spring-mockito/.project
deleted file mode 100644
index 5f0e9cacbc..0000000000
--- a/spring-mockito/.project
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
- spring-mockito
-
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/spring-mvc-java/.classpath b/spring-mvc-java/.classpath
deleted file mode 100644
index a642d37ceb..0000000000
--- a/spring-mvc-java/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-mvc-java/.project b/spring-mvc-java/.project
deleted file mode 100644
index 21aa8efe0f..0000000000
--- a/spring-mvc-java/.project
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
- spring-mvc-java
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-mvc-java/.springBeans b/spring-mvc-java/.springBeans
deleted file mode 100644
index 7623a7e888..0000000000
--- a/spring-mvc-java/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/mvc-servlet.xml
-
-
-
-
diff --git a/spring-mvc-java/src/main/java/com/baeldung/circulardependency/CircularDependencyA b/spring-mvc-java/src/main/java/com/baeldung/circulardependency/CircularDependencyA
new file mode 100644
index 0000000000..54b012e347
--- /dev/null
+++ b/spring-mvc-java/src/main/java/com/baeldung/circulardependency/CircularDependencyA
@@ -0,0 +1,29 @@
+package com.baeldung.circulardependency;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CircularDependencyA implements ApplicationContextAware, InitializingBean {
+
+ private CircularDependencyB circB;
+
+ private ApplicationContext context;
+
+ public CircularDependencyB getCircB() {
+ return circB;
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ circB = context.getBean(CircularDependencyB.class);
+ }
+
+ @Override
+ public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
+ context = ctx;
+ }
+}
diff --git a/spring-mvc-java/src/main/java/com/baeldung/circulardependency/CircularDependencyB b/spring-mvc-java/src/main/java/com/baeldung/circulardependency/CircularDependencyB
new file mode 100644
index 0000000000..dc2240d0b5
--- /dev/null
+++ b/spring-mvc-java/src/main/java/com/baeldung/circulardependency/CircularDependencyB
@@ -0,0 +1,22 @@
+package com.baeldung.circulardependency;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CircularDependencyB {
+
+ private CircularDependencyA circA;
+
+ private String message = "Hi!";
+
+ @Autowired
+ public void setCircA(final CircularDependencyA circA) {
+ this.circA = circA;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+}
diff --git a/spring-mvc-java/src/test/java/com/baeldung/circulardependency/CircularDependencyTest b/spring-mvc-java/src/test/java/com/baeldung/circulardependency/CircularDependencyTest
new file mode 100644
index 0000000000..4229f21f10
--- /dev/null
+++ b/spring-mvc-java/src/test/java/com/baeldung/circulardependency/CircularDependencyTest
@@ -0,0 +1,35 @@
+package com.baeldung.circulardependency;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { TestConfig.class })
+public class CircularDependencyTest {
+
+ @Autowired
+ ApplicationContext context;
+
+ @Bean
+ public CircularDependencyA getCircularDependencyA() {
+ return new CircularDependencyA();
+ }
+
+ @Bean
+ public CircularDependencyB getCircularDependencyB() {
+ return new CircularDependencyB();
+ }
+
+ @Test
+ public void givenCircularDependency_whenSetterInjection_thenItWorks() {
+ final CircularDependencyA circA = context.getBean(CircularDependencyA.class);
+
+ Assert.assertEquals("Hi!", circA.getCircB().getMessage());
+ }
+}
diff --git a/spring-mvc-java/src/test/java/com/baeldung/circulardependency/TestConfig b/spring-mvc-java/src/test/java/com/baeldung/circulardependency/TestConfig
new file mode 100644
index 0000000000..a072c5d402
--- /dev/null
+++ b/spring-mvc-java/src/test/java/com/baeldung/circulardependency/TestConfig
@@ -0,0 +1,10 @@
+package com.baeldung.circulardependency;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan(basePackages = { "com.baeldung.circulardependency" })
+public class TestConfig {
+
+}
diff --git a/spring-mvc-no-xml/.classpath b/spring-mvc-no-xml/.classpath
deleted file mode 100644
index 6b533711d3..0000000000
--- a/spring-mvc-no-xml/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-mvc-no-xml/.project b/spring-mvc-no-xml/.project
deleted file mode 100644
index 9e6d801990..0000000000
--- a/spring-mvc-no-xml/.project
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
- spring-mvc-no-xml
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-mvc-no-xml/.springBeans b/spring-mvc-no-xml/.springBeans
deleted file mode 100644
index 7623a7e888..0000000000
--- a/spring-mvc-no-xml/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/mvc-servlet.xml
-
-
-
-
diff --git a/spring-mvc-velocity/pom.xml b/spring-mvc-velocity/pom.xml
new file mode 100644
index 0000000000..6c63e0be18
--- /dev/null
+++ b/spring-mvc-velocity/pom.xml
@@ -0,0 +1,179 @@
+
+ 4.0.0
+ com.baeldung
+ 0.1-SNAPSHOT
+ spring-mvc-velocity
+
+ spring-mvc-velocity
+ war
+
+
+
+
+
+
+ org.springframework
+ spring-web
+ ${org.springframework.version}
+
+
+ org.springframework
+ spring-webmvc
+ ${org.springframework.version}
+
+
+ org.springframework
+ spring-core
+ ${org.springframework.version}
+
+
+ org.springframework
+ spring-context-support
+ ${org.springframework.version}
+
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+ provided
+
+
+
+ org.apache.velocity
+ velocity
+ 1.7
+
+
+
+ org.apache.velocity
+ velocity-tools
+ 2.0
+
+
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+ org.hamcrest
+ hamcrest-core
+ ${org.hamcrest.version}
+ test
+
+
+ org.hamcrest
+ hamcrest-library
+ ${org.hamcrest.version}
+ test
+
+
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+ test
+
+
+
+ org.powermock
+ powermock-module-junit4
+ ${powermock.version}
+ test
+
+
+ org.powermock
+ powermock-api-mockito
+ ${powermock.version}
+ test
+
+
+ org.springframework
+ spring-test
+ ${org.springframework.version}
+ test
+
+
+
+
+
+ spring-mvc-velocity
+
+
+ src/main/resources
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ 1.8
+ 1.8
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ ${maven-war-plugin.version}
+
+ false
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4.1.4.RELEASE
+
+
+
+ 1.3
+ 4.12
+ 1.10.19
+ 1.6.4
+
+ 4.4.1
+ 4.5
+
+ 2.4.1
+
+
+ 3.5.1
+ 2.6
+ 2.19.1
+ 2.7
+ 1.4.18
+
+
+
+
\ No newline at end of file
diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/controller/MainController.java b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/controller/MainController.java
new file mode 100644
index 0000000000..679a455f3f
--- /dev/null
+++ b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/controller/MainController.java
@@ -0,0 +1,42 @@
+package com.baeldung.mvc.velocity.controller;
+
+import com.baeldung.mvc.velocity.domain.Tutorial;
+import com.baeldung.mvc.velocity.service.ITutorialsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import java.util.List;
+
+@Controller
+@RequestMapping("/")
+public class MainController {
+
+ @Autowired
+ private ITutorialsService tutService;
+
+ @RequestMapping(value ="/", method = RequestMethod.GET)
+ public String welcomePage() {
+ return "index";
+ }
+
+
+ @RequestMapping(value ="/list", method = RequestMethod.GET)
+ public String listTutorialsPage(Model model) {
+ List list = tutService.listTutorials();
+ model.addAttribute("tutorials", list);
+ return "list";
+ }
+
+ public ITutorialsService getTutService() {
+ return tutService;
+ }
+
+ public void setTutService(ITutorialsService tutService) {
+ this.tutService = tutService;
+ }
+
+
+}
\ No newline at end of file
diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/domain/Tutorial.java b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/domain/Tutorial.java
new file mode 100644
index 0000000000..ccbaa0e905
--- /dev/null
+++ b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/domain/Tutorial.java
@@ -0,0 +1,33 @@
+package com.baeldung.mvc.velocity.domain;
+
+public class Tutorial {
+
+ private final Integer tutId;
+ private final String title;
+ private final String description;
+ private final String author;
+
+ public Tutorial(Integer tutId, String title, String description, String author) {
+ this.tutId = tutId;
+ this.title = title;
+ this.description = description;
+ this.author = author;
+ }
+
+ public Integer getTutId() {
+ return tutId;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+}
diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/service/ITutorialsService.java b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/service/ITutorialsService.java
new file mode 100644
index 0000000000..24059f2662
--- /dev/null
+++ b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/service/ITutorialsService.java
@@ -0,0 +1,10 @@
+package com.baeldung.mvc.velocity.service;
+
+import com.baeldung.mvc.velocity.domain.Tutorial;
+
+import java.util.List;
+
+public interface ITutorialsService {
+
+ List listTutorials();
+}
diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/service/TutorialsService.java b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/service/TutorialsService.java
new file mode 100644
index 0000000000..f67cc0824f
--- /dev/null
+++ b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/service/TutorialsService.java
@@ -0,0 +1,18 @@
+package com.baeldung.mvc.velocity.service;
+
+import com.baeldung.mvc.velocity.domain.Tutorial;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.List;
+
+@Service
+public class TutorialsService implements ITutorialsService {
+
+ public List listTutorials() {
+ return Arrays.asList(
+ new Tutorial(1, "Guava", "Introduction to Guava", "GuavaAuthor"),
+ new Tutorial(2, "Android", "Introduction to Android", "AndroidAuthor")
+ );
+ }
+}
diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/MainWebAppInitializer.java b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/MainWebAppInitializer.java
new file mode 100644
index 0000000000..a2871716df
--- /dev/null
+++ b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/MainWebAppInitializer.java
@@ -0,0 +1,36 @@
+package com.baeldung.mvc.velocity.spring.config;
+
+import org.springframework.web.WebApplicationInitializer;
+import org.springframework.web.context.ContextLoaderListener;
+import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
+import org.springframework.web.context.support.GenericWebApplicationContext;
+import org.springframework.web.servlet.DispatcherServlet;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+import java.util.Set;
+
+public class MainWebAppInitializer implements WebApplicationInitializer {
+
+ @Override
+ public void onStartup(final ServletContext sc) throws ServletException {
+
+ // Create the 'root' Spring application context
+ final AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
+ root.register(WebConfig.class);
+
+ // Manages the lifecycle of the root application context
+ sc.addListener(new ContextLoaderListener(root));
+
+ // Handles requests into the application
+ final ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet(new GenericWebApplicationContext()));
+ appServlet.setLoadOnStartup(1);
+
+ final Set mappingConflicts = appServlet.addMapping("/");
+ if (!mappingConflicts.isEmpty()) {
+ throw new IllegalStateException("'appServlet' could not be mapped to '/' due " + "to an existing mapping. This is a known issue under Tomcat versions " + "<= 7.0.14; see https://issues.apache.org/bugzilla/show_bug.cgi?id=51278");
+ }
+ }
+
+}
diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/WebConfig.java b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/WebConfig.java
new file mode 100644
index 0000000000..ce8ce1919a
--- /dev/null
+++ b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/WebConfig.java
@@ -0,0 +1,45 @@
+package com.baeldung.mvc.velocity.spring.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.ViewResolver;
+import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.view.velocity.VelocityConfigurer;
+import org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver;
+
+@Configuration
+@EnableWebMvc
+@ComponentScan(basePackages = { "com.baeldung.mvc.velocity.controller", "com.baeldung.mvc.velocity.service"})
+public class WebConfig extends WebMvcConfigurerAdapter {
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
+ }
+
+ @Override
+ public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
+ configurer.enable();
+ }
+
+ @Bean
+ public ViewResolver viewResolver() {
+ final VelocityLayoutViewResolver bean = new VelocityLayoutViewResolver();
+ bean.setCache(true);
+ bean.setPrefix("/WEB-INF/views/");
+ bean.setLayoutUrl("/WEB-INF/layouts/layout.vm");
+ bean.setSuffix(".vm");
+ return bean;
+ }
+
+ @Bean
+ public VelocityConfigurer velocityConfig() {
+ VelocityConfigurer velocityConfigurer = new VelocityConfigurer();
+ velocityConfigurer.setResourceLoaderPath("/");
+ return velocityConfigurer;
+ }
+}
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/fragments/footer.vm b/spring-mvc-velocity/src/main/webapp/WEB-INF/fragments/footer.vm
new file mode 100644
index 0000000000..41bb36ce5e
--- /dev/null
+++ b/spring-mvc-velocity/src/main/webapp/WEB-INF/fragments/footer.vm
@@ -0,0 +1,4 @@
+
+ @Copyright baeldung.com
+
\ No newline at end of file
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/fragments/header.vm b/spring-mvc-velocity/src/main/webapp/WEB-INF/fragments/header.vm
new file mode 100644
index 0000000000..8fffa6cdab
--- /dev/null
+++ b/spring-mvc-velocity/src/main/webapp/WEB-INF/fragments/header.vm
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/layouts/layout.vm b/spring-mvc-velocity/src/main/webapp/WEB-INF/layouts/layout.vm
new file mode 100644
index 0000000000..3bac96aaae
--- /dev/null
+++ b/spring-mvc-velocity/src/main/webapp/WEB-INF/layouts/layout.vm
@@ -0,0 +1,22 @@
+
+
+ Spring with Velocity
+
+
+
+ #parse("/WEB-INF/fragments/header.vm")
+
+
+
+
+
+
+ $screen_content
+
+
+
+
+ #parse("/WEB-INF/fragments/footer.vm")
+
+
+
\ No newline at end of file
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/mvc-servlet.xml b/spring-mvc-velocity/src/main/webapp/WEB-INF/mvc-servlet.xml
new file mode 100644
index 0000000000..8b4fd570fe
--- /dev/null
+++ b/spring-mvc-velocity/src/main/webapp/WEB-INF/mvc-servlet.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/spring-context.xml b/spring-mvc-velocity/src/main/webapp/WEB-INF/spring-context.xml
new file mode 100644
index 0000000000..2f3b0f19bb
--- /dev/null
+++ b/spring-mvc-velocity/src/main/webapp/WEB-INF/spring-context.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/views/index.vm b/spring-mvc-velocity/src/main/webapp/WEB-INF/views/index.vm
new file mode 100644
index 0000000000..8883a50658
--- /dev/null
+++ b/spring-mvc-velocity/src/main/webapp/WEB-INF/views/index.vm
@@ -0,0 +1,4 @@
+Index
+
+Welcome page
+This is just the welcome page
\ No newline at end of file
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/views/list.vm b/spring-mvc-velocity/src/main/webapp/WEB-INF/views/list.vm
new file mode 100644
index 0000000000..9e06a09e4f
--- /dev/null
+++ b/spring-mvc-velocity/src/main/webapp/WEB-INF/views/list.vm
@@ -0,0 +1,19 @@
+Index
+
+Tutorials list
+
+
+ Tutorial Id
+ Tutorial Title
+ Tutorial Description
+ Tutorial Author
+
+#foreach($tut in $tutorials)
+
+ $tut.tutId
+ $tut.title
+ $tut.description
+ $tut.author
+
+#end
+
\ No newline at end of file
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/web_old.xml b/spring-mvc-velocity/src/main/webapp/WEB-INF/web_old.xml
new file mode 100644
index 0000000000..72050c0d37
--- /dev/null
+++ b/spring-mvc-velocity/src/main/webapp/WEB-INF/web_old.xml
@@ -0,0 +1,32 @@
+
+
+
+ Spring MVC Velocity
+
+
+ mvc
+ org.springframework.web.servlet.DispatcherServlet
+
+ contextConfigLocation
+ /WEB-INF/mvc-servlet.xml
+
+ 1
+
+
+
+ mvc
+ /*
+
+
+
+ contextConfigLocation
+ /WEB-INF/spring-context.xml
+
+
+
+ org.springframework.web.context.ContextLoaderListener
+
+
\ No newline at end of file
diff --git a/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/DataContentControllerTest.java b/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/DataContentControllerTest.java
new file mode 100644
index 0000000000..a9fb242755
--- /dev/null
+++ b/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/DataContentControllerTest.java
@@ -0,0 +1,61 @@
+package com.baeldung.mvc.velocity.test;
+
+import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.hasProperty;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.xpath;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import com.baeldung.mvc.velocity.spring.config.WebConfig;
+import com.baeldung.mvc.velocity.test.config.TestConfig;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+// @ContextConfiguration(locations = {"classpath:mvc-servlet.xml"})
+@ContextConfiguration(classes = { TestConfig.class, WebConfig.class })
+@WebAppConfiguration
+public class DataContentControllerTest {
+
+ private MockMvc mockMvc;
+
+ @Autowired
+ private WebApplicationContext webApplicationContext;
+
+ @Before
+ public void setUp() {
+
+
+ mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
+ }
+
+ @Test
+ public void whenCallingList_ThenModelAndContentOK() throws Exception {
+
+ mockMvc.perform(get("/list")).andExpect(status().isOk()).andExpect(view().name("list")).andExpect(model().attribute("tutorials", hasSize(2)))
+ .andExpect(model().attribute("tutorials", hasItem(allOf(hasProperty("tutId", is(1)), hasProperty("author", is("GuavaAuthor")), hasProperty("title", is("Guava"))))))
+ .andExpect(model().attribute("tutorials", hasItem(allOf(hasProperty("tutId", is(2)), hasProperty("author", is("AndroidAuthor")), hasProperty("title", is("Android"))))));
+
+ mockMvc.perform(get("/list")).andExpect(xpath("//table").exists());
+ mockMvc.perform(get("/list")).andExpect(xpath("//td[@id='tutId_1']").exists());
+ }
+
+ @Test
+ public void whenCallingIndex_thenViewOK() throws Exception{
+ mockMvc.perform(get("/")).andExpect(status().isOk()).andExpect(view().name("index")).andExpect(model().size(0));
+ }
+}
diff --git a/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/config/TestConfig.java b/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/config/TestConfig.java
new file mode 100644
index 0000000000..8b84bcdd23
--- /dev/null
+++ b/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/config/TestConfig.java
@@ -0,0 +1,32 @@
+package com.baeldung.mvc.velocity.test.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.ViewResolver;
+import org.springframework.web.servlet.view.velocity.VelocityConfigurer;
+import org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver;
+
+@Configuration
+public class TestConfig {
+
+
+ @Bean
+ public ViewResolver viewResolver() {
+ final VelocityLayoutViewResolver bean = new VelocityLayoutViewResolver();
+ bean.setCache(true);
+ bean.setPrefix("/WEB-INF/views/");
+ bean.setLayoutUrl("/WEB-INF/layouts/layout.vm");
+ bean.setSuffix(".vm");
+ return bean;
+ }
+
+ @Bean
+ public VelocityConfigurer velocityConfig() {
+ VelocityConfigurer velocityConfigurer = new VelocityConfigurer();
+ velocityConfigurer.setResourceLoaderPath("/");
+ return velocityConfigurer;
+ }
+
+
+
+}
diff --git a/spring-mvc-velocity/src/test/resources/mvc-servlet.xml b/spring-mvc-velocity/src/test/resources/mvc-servlet.xml
new file mode 100644
index 0000000000..8b4fd570fe
--- /dev/null
+++ b/spring-mvc-velocity/src/test/resources/mvc-servlet.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-openid/.classpath b/spring-openid/.classpath
deleted file mode 100644
index 0cad5db2d0..0000000000
--- a/spring-openid/.classpath
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-openid/.project b/spring-openid/.project
deleted file mode 100644
index 81874eb896..0000000000
--- a/spring-openid/.project
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
- spring-openid
-
-
-
-
-
- org.eclipse.wst.jsdt.core.javascriptValidator
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-quartz/.classpath b/spring-quartz/.classpath
deleted file mode 100644
index 6d7587a819..0000000000
--- a/spring-quartz/.classpath
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-quartz/.project b/spring-quartz/.project
deleted file mode 100644
index 6adc420837..0000000000
--- a/spring-quartz/.project
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
- spring-quartz
-
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/spring-rest-angular-pagination/StudentDirectory/pom.xml b/spring-rest-angular-pagination/StudentDirectory/pom.xml
new file mode 100644
index 0000000000..8dab851ef2
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/pom.xml
@@ -0,0 +1,86 @@
+
+
+ 4.0.0
+ angular-spring-rest-sample
+ angular-spring-rest-sample
+ com.baeldung
+ 1.0
+ war
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.3.3.RELEASE
+
+
+ 1.12.2.RELEASE
+
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+ provided
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.data
+ spring-data-commons
+
+
+ org.springframework
+ spring-test
+ test
+
+
+ org.apache.commons
+ commons-lang3
+ 3.3
+
+
+ com.google.guava
+ guava
+ 19.0
+
+
+ junit
+ junit
+ test
+
+
+ io.rest-assured
+ rest-assured
+ 3.0.0
+ test
+
+
+ io.rest-assured
+ spring-mock-mvc
+ 3.0.0
+ test
+
+
+
+ angular-spring-rest-sample
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ false
+
+
+
+
+
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/mock/MockStudentData.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/mock/MockStudentData.java
new file mode 100644
index 0000000000..df70780a87
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/mock/MockStudentData.java
@@ -0,0 +1,39 @@
+package org.baeldung.mock;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.baeldung.web.vo.Student;
+
+public class MockStudentData {
+
+ private static List studentList = new ArrayList<>();
+
+ static {
+ studentList.add(new Student("1", "Bryan", "Male", 20));
+ studentList.add(new Student("2", "Ben", "Male", 22));
+ studentList.add(new Student("3", "Lisa", "Female", 24));
+ studentList.add(new Student("4", "Sarah", "Female", 26));
+ studentList.add(new Student("5", "Jay", "Male", 20));
+ studentList.add(new Student("6", "John", "Male", 22));
+ studentList.add(new Student("7", "Jordan", "Male", 24));
+ studentList.add(new Student("8", "Rob", "Male", 26));
+ studentList.add(new Student("9", "Will", "Male", 20));
+ studentList.add(new Student("10", "Shawn", "Male", 22));
+ studentList.add(new Student("11", "Taylor", "Female", 24));
+ studentList.add(new Student("12", "Venus", "Female", 26));
+ studentList.add(new Student("13", "Vince", "Male", 20));
+ studentList.add(new Student("14", "Carol", "Female", 22));
+ studentList.add(new Student("15", "Joana", "Female", 24));
+ studentList.add(new Student("16", "Dion", "Male", 26));
+ studentList.add(new Student("17", "Evans", "Male", 20));
+ studentList.add(new Student("18", "Bart", "Male", 22));
+ studentList.add(new Student("19", "Jenny", "Female", 24));
+ studentList.add(new Student("20", "Kristine", "Female", 26));
+ }
+
+ public static List getMockDataStudents(){
+ return studentList;
+ }
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/exception/MyResourceNotFoundException.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/exception/MyResourceNotFoundException.java
new file mode 100644
index 0000000000..3105d1cb11
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/exception/MyResourceNotFoundException.java
@@ -0,0 +1,27 @@
+package org.baeldung.web.exception;
+
+public class MyResourceNotFoundException extends RuntimeException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4088649120307193208L;
+
+ public MyResourceNotFoundException() {
+ super();
+ }
+
+ public MyResourceNotFoundException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ public MyResourceNotFoundException(final String message) {
+ super(message);
+ }
+
+ public MyResourceNotFoundException(final Throwable cause) {
+ super(cause);
+ }
+
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/main/Application.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/main/Application.java
new file mode 100644
index 0000000000..b3b0dad98a
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/main/Application.java
@@ -0,0 +1,26 @@
+package org.baeldung.web.main;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.web.filter.ShallowEtagHeaderFilter;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+@SpringBootApplication
+@EnableAutoConfiguration
+@ComponentScan("org.baeldung")
+public class Application extends WebMvcConfigurerAdapter {
+
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+ @Bean
+ public ShallowEtagHeaderFilter shallowEtagHeaderFilter() {
+ return new ShallowEtagHeaderFilter();
+ }
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/rest/StudentDirectoryRestController.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/rest/StudentDirectoryRestController.java
new file mode 100644
index 0000000000..5ff24ec0f2
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/rest/StudentDirectoryRestController.java
@@ -0,0 +1,26 @@
+package org.baeldung.web.rest;
+
+import org.baeldung.web.service.StudentService;
+import org.baeldung.web.vo.Student;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class StudentDirectoryRestController {
+
+ @Autowired
+ private StudentService service;
+
+ @RequestMapping(value = "/student/get", params = { "page", "size" }, method = RequestMethod.GET)
+ public Page findPaginated(@RequestParam("page") int page, @RequestParam("size") int size){
+
+ Page resultPage = service.findPaginated(page, size);
+
+ return resultPage;
+ }
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/IOperations.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/IOperations.java
new file mode 100644
index 0000000000..0b408106ce
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/IOperations.java
@@ -0,0 +1,9 @@
+package org.baeldung.web.service;
+
+import org.springframework.data.domain.Page;
+
+public interface IOperations {
+
+ Page findPaginated(int page, int size);
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentService.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentService.java
new file mode 100644
index 0000000000..5c4487254a
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentService.java
@@ -0,0 +1,7 @@
+package org.baeldung.web.service;
+
+import org.baeldung.web.vo.Student;
+
+public interface StudentService extends IOperations{
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentServiceImpl.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentServiceImpl.java
new file mode 100644
index 0000000000..3b6dda6fb1
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentServiceImpl.java
@@ -0,0 +1,36 @@
+package org.baeldung.web.service;
+
+import java.util.List;
+
+import org.baeldung.mock.MockStudentData;
+import org.baeldung.web.exception.MyResourceNotFoundException;
+import org.baeldung.web.vo.Student;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Service;
+
+@Service
+public class StudentServiceImpl implements StudentService {
+
+ private List mockDataStudent = MockStudentData.getMockDataStudents();
+
+ @Override
+ public Page findPaginated(int page, int size){
+ Page studentPage = getPage(page, size);
+ return studentPage;
+ }
+
+ private Page getPage(int page, int size) {
+ page = page != 0?page - 1:page;
+ int from = Math.max(0, page * size);
+ int to = Math.min(mockDataStudent.size(), (page + 1) * size);
+ if(from > to){
+ throw new MyResourceNotFoundException("page number is higher than total pages.");
+ }
+ return new PageImpl(mockDataStudent.subList(from, to),
+ new PageRequest(page,size),
+ mockDataStudent.size());
+ }
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/vo/Student.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/vo/Student.java
new file mode 100644
index 0000000000..11c503815d
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/vo/Student.java
@@ -0,0 +1,60 @@
+package org.baeldung.web.vo;
+
+import java.io.Serializable;
+
+public class Student implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public Student() {
+ }
+
+ public Student(String studentId, String name, String gender, Integer age) {
+ super();
+ this.studentId = studentId;
+ this.name = name;
+ this.gender = gender;
+ this.age = age;
+ }
+
+ private String studentId;
+ private String name;
+ private String gender;
+ private Integer age;
+
+ public String getStudentId() {
+ return studentId;
+ }
+
+ public void setStudentId(String studentId) {
+ this.studentId = studentId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getGender() {
+ return gender;
+ }
+
+ public void setGender(String gender) {
+ this.gender = gender;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/resources/application.properties b/spring-rest-angular-pagination/StudentDirectory/src/main/resources/application.properties
new file mode 100644
index 0000000000..a9bf6ca218
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/resources/application.properties
@@ -0,0 +1 @@
+server.contextPath=/StudentDirectory
\ No newline at end of file
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/WEB-INF/web.xml b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..ff65bd6b96
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,11 @@
+
+
+
+
+ index.html
+
+
+
\ No newline at end of file
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/index.html b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/index.html
new file mode 100644
index 0000000000..56a1273588
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/view/app.js b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/view/app.js
new file mode 100644
index 0000000000..522c49c8cb
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/view/app.js
@@ -0,0 +1,54 @@
+var app = angular.module('app', ['ui.grid','ui.grid.pagination']);
+
+app.controller('StudentCtrl', ['$scope','StudentService', function ($scope,StudentService) {
+ var paginationOptions = {
+ pageNumber: 1,
+ pageSize: 5,
+ sort: null
+ };
+
+ StudentService.getStudents(paginationOptions.pageNumber,
+ paginationOptions.pageSize).success(function(data){
+ $scope.gridOptions.data = data.content;
+ $scope.gridOptions.totalItems = data.totalElements;
+ });
+
+ $scope.gridOptions = {
+ paginationPageSizes: [5, 10, 20],
+ paginationPageSize: paginationOptions.pageSize,
+ enableColumnMenus:false,
+ columnDefs: [
+ { name: 'studentId' },
+ { name: 'name' },
+ { name: 'gender' },
+ { name: 'age' }
+ ],
+ onRegisterApi: function(gridApi) {
+ $scope.gridApi = gridApi;
+ gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ paginationOptions.pageNumber = newPage;
+ paginationOptions.pageSize = pageSize;
+ StudentService.getStudents(newPage,pageSize).success(function(data){
+ $scope.gridOptions.data = data.content;
+ $scope.gridOptions.totalItems = data.totalElements;
+ });
+ });
+ }
+ };
+
+}]);
+
+app.service('StudentService',['$http', function ($http) {
+
+ function getStudents(pageNumber,size) {
+ return $http({
+ method: 'GET',
+ url: 'student/get?page='+pageNumber+'&size='+size
+ });
+ }
+
+ return {
+ getStudents:getStudents
+ };
+
+}]);
\ No newline at end of file
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/test/java/org/baeldung/web/service/StudentServiceTest.java b/spring-rest-angular-pagination/StudentDirectory/src/test/java/org/baeldung/web/service/StudentServiceTest.java
new file mode 100644
index 0000000000..3e476bf0d0
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/test/java/org/baeldung/web/service/StudentServiceTest.java
@@ -0,0 +1,49 @@
+package org.baeldung.web.service;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.baeldung.web.main.Application;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.IntegrationTest;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+
+import io.restassured.RestAssured;
+import io.restassured.response.Response;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes = Application.class)
+@WebAppConfiguration
+@IntegrationTest("server.port:8080")
+public class StudentServiceTest{
+
+ private String getURL() {
+ return "/StudentDirectory/student/get";
+ }
+
+ @Test
+ public void whenResourcesAreRetrievedPaged_then200IsReceived(){
+ Response response = RestAssured.given().get(getURL()+ "?page=0&size=2").andReturn();
+
+ assertTrue(response.getStatusCode() == 200 );
+ }
+
+ @Test
+ public void whenPageOfResourcesAreRetrievedOutOfBounds_then404IsReceived(){
+ String url = getURL()+ "?page=" + RandomStringUtils.randomNumeric(5) + "&size=2";
+ Response response = RestAssured.given().get(url);
+
+ assertTrue(response.getStatusCode() == 500 );
+ }
+
+ @Test
+ public void givenResourcesExist_whenFirstPageIsRetrieved_thenPageContainsResources(){
+ Response response = RestAssured.given().get(getURL() + "?page=1&size=2" );
+ assertFalse(response.getBody().jsonPath().getList("content").isEmpty() );
+ }
+
+}
diff --git a/spring-rest-docs/src/main/java/com/example/CRUDController.java b/spring-rest-docs/src/main/java/com/example/CRUDController.java
index 818b29d3a6..ff8c91d6cd 100644
--- a/spring-rest-docs/src/main/java/com/example/CRUDController.java
+++ b/spring-rest-docs/src/main/java/com/example/CRUDController.java
@@ -17,39 +17,39 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/crud")
public class CRUDController {
-
- @RequestMapping(method=RequestMethod.GET)
- @ResponseStatus(HttpStatus.OK)
- public List read(@RequestBody CrudInput crudInput) {
- List returnList=new ArrayList();
- returnList.add(crudInput);
- return returnList;
- }
-
- @ResponseStatus(HttpStatus.CREATED)
- @RequestMapping(method=RequestMethod.POST)
- public HttpHeaders save(@RequestBody CrudInput crudInput) {
- HttpHeaders httpHeaders = new HttpHeaders();
- httpHeaders.setLocation(linkTo(CRUDController.class).slash(crudInput.getTitle()).toUri());
- return httpHeaders;
- }
-
- @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
- @ResponseStatus(HttpStatus.OK)
- HttpHeaders delete(@RequestBody CrudInput crudInput) {
- HttpHeaders httpHeaders = new HttpHeaders();
- return httpHeaders;
- }
-
- @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
- @ResponseStatus(HttpStatus.ACCEPTED)
- void put(@PathVariable("id") long id, @RequestBody CrudInput crudInput) {
-
- }
-
- @RequestMapping(value = "/{id}", method = RequestMethod.PATCH)
- @ResponseStatus(HttpStatus.NO_CONTENT)
- void patch(@PathVariable("id") long id, @RequestBody CrudInput crudInput) {
-
- }
+
+ @RequestMapping(method = RequestMethod.GET)
+ @ResponseStatus(HttpStatus.OK)
+ public List read(@RequestBody CrudInput crudInput) {
+ List returnList = new ArrayList();
+ returnList.add(crudInput);
+ return returnList;
+ }
+
+ @ResponseStatus(HttpStatus.CREATED)
+ @RequestMapping(method = RequestMethod.POST)
+ public HttpHeaders save(@RequestBody CrudInput crudInput) {
+ HttpHeaders httpHeaders = new HttpHeaders();
+ httpHeaders.setLocation(linkTo(CRUDController.class).slash(crudInput.getTitle()).toUri());
+ return httpHeaders;
+ }
+
+ @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+ @ResponseStatus(HttpStatus.OK)
+ HttpHeaders delete(@RequestBody CrudInput crudInput) {
+ HttpHeaders httpHeaders = new HttpHeaders();
+ return httpHeaders;
+ }
+
+ @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
+ @ResponseStatus(HttpStatus.ACCEPTED)
+ void put(@PathVariable("id") long id, @RequestBody CrudInput crudInput) {
+
+ }
+
+ @RequestMapping(value = "/{id}", method = RequestMethod.PATCH)
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ void patch(@PathVariable("id") long id, @RequestBody CrudInput crudInput) {
+
+ }
}
diff --git a/spring-rest-docs/src/main/java/com/example/CrudInput.java b/spring-rest-docs/src/main/java/com/example/CrudInput.java
index 3d91b7d45a..36ad67eb21 100644
--- a/spring-rest-docs/src/main/java/com/example/CrudInput.java
+++ b/spring-rest-docs/src/main/java/com/example/CrudInput.java
@@ -10,33 +10,32 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class CrudInput {
-
- //@NotBlank
- private final String title;
- private final String body;
+ // @NotBlank
+ private final String title;
- private final List tagUris;
+ private final String body;
- @JsonCreator
- public CrudInput(@JsonProperty("title") String title,
- @JsonProperty("body") String body, @JsonProperty("tags") List tagUris) {
- this.title = title;
- this.body = body;
- this.tagUris = tagUris == null ? Collections.emptyList() : tagUris;
- }
+ private final List tagUris;
- public String getTitle() {
- return title;
- }
+ @JsonCreator
+ public CrudInput(@JsonProperty("title") String title, @JsonProperty("body") String body, @JsonProperty("tags") List tagUris) {
+ this.title = title;
+ this.body = body;
+ this.tagUris = tagUris == null ? Collections. emptyList() : tagUris;
+ }
- public String getBody() {
- return body;
- }
+ public String getTitle() {
+ return title;
+ }
- @JsonProperty("tags")
- public List getTagUris() {
- return this.tagUris;
- }
+ public String getBody() {
+ return body;
+ }
+
+ @JsonProperty("tags")
+ public List getTagUris() {
+ return this.tagUris;
+ }
}
\ No newline at end of file
diff --git a/spring-rest-docs/src/main/java/com/example/IndexController.java b/spring-rest-docs/src/main/java/com/example/IndexController.java
index a6b4537c43..6b896da416 100644
--- a/spring-rest-docs/src/main/java/com/example/IndexController.java
+++ b/spring-rest-docs/src/main/java/com/example/IndexController.java
@@ -1,6 +1,5 @@
package com.example;
-
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import org.springframework.hateoas.ResourceSupport;
@@ -12,11 +11,11 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/")
public class IndexController {
- @RequestMapping(method=RequestMethod.GET)
- public ResourceSupport index() {
- ResourceSupport index = new ResourceSupport();
- index.add(linkTo(CRUDController.class).withRel("crud"));
- return index;
- }
+ @RequestMapping(method = RequestMethod.GET)
+ public ResourceSupport index() {
+ ResourceSupport index = new ResourceSupport();
+ index.add(linkTo(CRUDController.class).withRel("crud"));
+ return index;
+ }
}
\ No newline at end of file
diff --git a/spring-rest-docs/src/main/java/com/example/SpringRestDocsApplication.java b/spring-rest-docs/src/main/java/com/example/SpringRestDocsApplication.java
index dd20ef324e..da09f9accc 100644
--- a/spring-rest-docs/src/main/java/com/example/SpringRestDocsApplication.java
+++ b/spring-rest-docs/src/main/java/com/example/SpringRestDocsApplication.java
@@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringRestDocsApplication {
- public static void main(String[] args) {
- SpringApplication.run(SpringRestDocsApplication.class, args);
- }
+ public static void main(String[] args) {
+ SpringApplication.run(SpringRestDocsApplication.class, args);
+ }
}
diff --git a/spring-rest-docs/src/test/java/com/example/ApiDocumentation.java b/spring-rest-docs/src/test/java/com/example/ApiDocumentation.java
index 195b9dc514..5b753aff0c 100644
--- a/spring-rest-docs/src/test/java/com/example/ApiDocumentation.java
+++ b/spring-rest-docs/src/test/java/com/example/ApiDocumentation.java
@@ -56,55 +56,35 @@ public class ApiDocumentation {
@Before
public void setUp() {
this.document = document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()));
- this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
- .apply(documentationConfiguration(this.restDocumentation))
- .alwaysDo(this.document)
- .build();
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).apply(documentationConfiguration(this.restDocumentation)).alwaysDo(this.document).build();
}
-
@Test
public void headersExample() throws Exception {
- this.document.snippets(responseHeaders(headerWithName("Content-Type")
- .description("The Content-Type of the payload, e.g. `application/hal+json`")));
- this.mockMvc.perform(get("/"))
- .andExpect(status().isOk());
+ this.document.snippets(responseHeaders(headerWithName("Content-Type").description("The Content-Type of the payload, e.g. `application/hal+json`")));
+ this.mockMvc.perform(get("/")).andExpect(status().isOk());
}
@Test
public void indexExample() throws Exception {
- this.document.snippets(
- links(linkWithRel("crud").description("The <>")),
- responseFields(fieldWithPath("_links").description("<> to other resources"))
- );
- this.mockMvc.perform(get("/"))
- .andExpect(status().isOk());
+ this.document.snippets(links(linkWithRel("crud").description("The <>")), responseFields(fieldWithPath("_links").description("<> to other resources")));
+ this.mockMvc.perform(get("/")).andExpect(status().isOk());
}
-
@Test
public void crudGetExample() throws Exception {
Map tag = new HashMap<>();
tag.put("name", "GET");
- String tagLocation = this.mockMvc.perform(get("/crud")
- .contentType(MediaTypes.HAL_JSON)
- .content(this.objectMapper.writeValueAsString(tag)))
- .andExpect(status().isOk())
- .andReturn()
- .getResponse()
- .getHeader("Location");
+ String tagLocation = this.mockMvc.perform(get("/crud").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isOk()).andReturn().getResponse().getHeader("Location");
Map crud = new HashMap<>();
crud.put("title", "Sample Model");
crud.put("body", "http://www.baeldung.com/");
crud.put("tags", singletonList(tagLocation));
- this.mockMvc.perform(get("/crud")
- .contentType(MediaTypes.HAL_JSON)
- .content(this.objectMapper.writeValueAsString(crud)))
- .andExpect(status().isOk());
+ this.mockMvc.perform(get("/crud").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isOk());
}
@Test
@@ -112,13 +92,7 @@ public class ApiDocumentation {
Map tag = new HashMap<>();
tag.put("name", "CREATE");
- String tagLocation = this.mockMvc.perform(post("/crud")
- .contentType(MediaTypes.HAL_JSON)
- .content(this.objectMapper.writeValueAsString(tag)))
- .andExpect(status().isCreated())
- .andReturn()
- .getResponse()
- .getHeader("Location");
+ String tagLocation = this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isCreated()).andReturn().getResponse().getHeader("Location");
Map crud = new HashMap<>();
crud.put("title", "Sample Model");
@@ -126,13 +100,9 @@ public class ApiDocumentation {
crud.put("tags", singletonList(tagLocation));
ConstrainedFields fields = new ConstrainedFields(CrudInput.class);
- this.document.snippets(requestFields(
- fields.withPath("title").description("The title of the note"),
- fields.withPath("body").description("The body of the note"),
- fields.withPath("tags").description("An array of tag resource URIs")));
+ this.document.snippets(requestFields(fields.withPath("title").description("The title of the note"), fields.withPath("body").description("The body of the note"), fields.withPath("tags").description("An array of tag resource URIs")));
this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isCreated());
-
}
@Test
@@ -141,23 +111,14 @@ public class ApiDocumentation {
Map tag = new HashMap<>();
tag.put("name", "DELETE");
- String tagLocation = this.mockMvc.perform(delete("/crud/10")
- .contentType(MediaTypes.HAL_JSON)
- .content(this.objectMapper.writeValueAsString(tag)))
- .andExpect(status().isOk())
- .andReturn()
- .getResponse()
- .getHeader("Location");
+ String tagLocation = this.mockMvc.perform(delete("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isOk()).andReturn().getResponse().getHeader("Location");
Map crud = new HashMap<>();
crud.put("title", "Sample Model");
crud.put("body", "http://www.baeldung.com/");
crud.put("tags", singletonList(tagLocation));
- this.mockMvc.perform(delete("/crud/10")
- .contentType(MediaTypes.HAL_JSON)
- .content(this.objectMapper.writeValueAsString(crud)))
- .andExpect(status().isOk());
+ this.mockMvc.perform(delete("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isOk());
}
@Test
@@ -166,51 +127,31 @@ public class ApiDocumentation {
Map tag = new HashMap<>();
tag.put("name", "PATCH");
- String tagLocation = this.mockMvc.perform(patch("/crud/10")
- .contentType(MediaTypes.HAL_JSON)
- .content(this.objectMapper.writeValueAsString(tag)))
- .andExpect(status().isNoContent())
- .andReturn()
- .getResponse()
- .getHeader("Location");
+ String tagLocation = this.mockMvc.perform(patch("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isNoContent()).andReturn().getResponse().getHeader("Location");
Map crud = new HashMap<>();
crud.put("title", "Sample Model");
crud.put("body", "http://www.baeldung.com/");
crud.put("tags", singletonList(tagLocation));
- this.mockMvc.perform(patch("/crud/10")
- .contentType(MediaTypes.HAL_JSON)
- .content(this.objectMapper.writeValueAsString(crud)))
- .andExpect(status().isNoContent());
+ this.mockMvc.perform(patch("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isNoContent());
}
-
@Test
public void crudPutExample() throws Exception {
Map tag = new HashMap<>();
tag.put("name", "PUT");
- String tagLocation = this.mockMvc.perform(put("/crud/10")
- .contentType(MediaTypes.HAL_JSON)
- .content(this.objectMapper.writeValueAsString(tag)))
- .andExpect(status().isAccepted())
- .andReturn()
- .getResponse()
- .getHeader("Location");
+ String tagLocation = this.mockMvc.perform(put("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isAccepted()).andReturn().getResponse().getHeader("Location");
Map crud = new HashMap<>();
crud.put("title", "Sample Model");
crud.put("body", "http://www.baeldung.com/");
crud.put("tags", singletonList(tagLocation));
- this.mockMvc.perform(put("/crud/10")
- .contentType(MediaTypes.HAL_JSON)
- .content(this.objectMapper.writeValueAsString(crud)))
- .andExpect(status().isAccepted());
+ this.mockMvc.perform(put("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isAccepted());
}
-
@Test
public void contextLoads() {
}
@@ -224,11 +165,8 @@ public class ApiDocumentation {
}
private FieldDescriptor withPath(String path) {
- return fieldWithPath(path)
- .attributes(key("constraints")
- .value(collectionToDelimitedString(this.constraintDescriptions.descriptionsForProperty(path), ". ")));
+ return fieldWithPath(path).attributes(key("constraints").value(collectionToDelimitedString(this.constraintDescriptions.descriptionsForProperty(path), ". ")));
}
}
-
}
diff --git a/spring-rest-docs/src/test/java/com/example/GettingStartedDocumentation.java b/spring-rest-docs/src/test/java/com/example/GettingStartedDocumentation.java
index 7f3c4db1f9..7aea9d303c 100644
--- a/spring-rest-docs/src/test/java/com/example/GettingStartedDocumentation.java
+++ b/spring-rest-docs/src/test/java/com/example/GettingStartedDocumentation.java
@@ -46,113 +46,105 @@ public class GettingStartedDocumentation {
private MockMvc mockMvc;
-
@Before
public void setUp() {
- this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
- .apply(documentationConfiguration(this.restDocumentation))
- .alwaysDo(document("{method-name}/{step}/",
- preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
- .build();
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).apply(documentationConfiguration(this.restDocumentation)).alwaysDo(document("{method-name}/{step}/", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()))).build();
}
@Test
public void index() throws Exception {
- this.mockMvc.perform(get("/").accept(MediaTypes.HAL_JSON))
- .andExpect(status().isOk())
- .andExpect(jsonPath("_links.crud", is(notNullValue())))
- .andExpect(jsonPath("_links.crud", is(notNullValue())));
+ this.mockMvc.perform(get("/").accept(MediaTypes.HAL_JSON)).andExpect(status().isOk()).andExpect(jsonPath("_links.crud", is(notNullValue()))).andExpect(jsonPath("_links.crud", is(notNullValue())));
}
-// String createNote() throws Exception {
-// Map note = new HashMap();
-// note.put("title", "Note creation with cURL");
-// note.put("body", "An example of how to create a note using curl");
-// String noteLocation = this.mockMvc.perform(post("/crud")
-// .contentType(MediaTypes.HAL_JSON)
-// .content(objectMapper.writeValueAsString(note)))
-// .andExpect(status().isCreated())
-// .andExpect(header().string("Location", notNullValue()))
-// .andReturn()
-// .getResponse()
-// .getHeader("Location");
-// return noteLocation;
-// }
-//
-// MvcResult getNote(String noteLocation) throws Exception {
-// return this.mockMvc.perform(get(noteLocation))
-// .andExpect(status().isOk())
-// .andExpect(jsonPath("title", is(notNullValue())))
-// .andExpect(jsonPath("body", is(notNullValue())))
-// .andExpect(jsonPath("_links.crud", is(notNullValue())))
-// .andReturn();
-// }
-//
-//
-// String createTag() throws Exception, JsonProcessingException {
-// Map tag = new HashMap();
-// tag.put("name", "getting-started");
-// String tagLocation = this.mockMvc.perform(post("/crud")
-// .contentType(MediaTypes.HAL_JSON)
-// .content(objectMapper.writeValueAsString(tag)))
-// .andExpect(status().isCreated())
-// .andExpect(header().string("Location", notNullValue()))
-// .andReturn()
-// .getResponse()
-// .getHeader("Location");
-// return tagLocation;
-// }
-//
-// void getTag(String tagLocation) throws Exception {
-// this.mockMvc.perform(get(tagLocation)).andExpect(status().isOk())
-// .andExpect(jsonPath("name", is(notNullValue())))
-// .andExpect(jsonPath("_links.tagged-notes", is(notNullValue())));
-// }
-//
-// String createTaggedNote(String tag) throws Exception {
-// Map note = new HashMap();
-// note.put("title", "Tagged note creation with cURL");
-// note.put("body", "An example of how to create a tagged note using cURL");
-// note.put("tags", Arrays.asList(tag));
-//
-// String noteLocation = this.mockMvc.perform(post("/notes")
-// .contentType(MediaTypes.HAL_JSON)
-// .content(objectMapper.writeValueAsString(note)))
-// .andExpect(status().isCreated())
-// .andExpect(header().string("Location", notNullValue()))
-// .andReturn()
-// .getResponse()
-// .getHeader("Location");
-// return noteLocation;
-// }
-//
-// void getTags(String noteTagsLocation) throws Exception {
-// this.mockMvc.perform(get(noteTagsLocation))
-// .andExpect(status().isOk())
-// .andExpect(jsonPath("_embedded.tags", hasSize(1)));
-// }
-//
-// void tagExistingNote(String noteLocation, String tagLocation) throws Exception {
-// Map update = new HashMap();
-// update.put("tags", Arrays.asList(tagLocation));
-// this.mockMvc.perform(patch(noteLocation)
-// .contentType(MediaTypes.HAL_JSON)
-// .content(objectMapper.writeValueAsString(update)))
-// .andExpect(status().isNoContent());
-// }
-//
-// MvcResult getTaggedExistingNote(String noteLocation) throws Exception {
-// return this.mockMvc.perform(get(noteLocation)).andExpect(status().isOk()).andReturn();
-// }
-//
-// void getTagsForExistingNote(String noteTagsLocation) throws Exception {
-// this.mockMvc.perform(get(noteTagsLocation))
-// .andExpect(status().isOk()).andExpect(jsonPath("_embedded.tags", hasSize(1)));
-// }
-//
-// private String getLink(MvcResult result, String rel)
-// throws UnsupportedEncodingException {
-// return JsonPath.parse(result.getResponse().getContentAsString()).read("_links." + rel + ".href");
-// }
+ // String createNote() throws Exception {
+ // Map note = new HashMap();
+ // note.put("title", "Note creation with cURL");
+ // note.put("body", "An example of how to create a note using curl");
+ // String noteLocation = this.mockMvc.perform(post("/crud")
+ // .contentType(MediaTypes.HAL_JSON)
+ // .content(objectMapper.writeValueAsString(note)))
+ // .andExpect(status().isCreated())
+ // .andExpect(header().string("Location", notNullValue()))
+ // .andReturn()
+ // .getResponse()
+ // .getHeader("Location");
+ // return noteLocation;
+ // }
+ //
+ // MvcResult getNote(String noteLocation) throws Exception {
+ // return this.mockMvc.perform(get(noteLocation))
+ // .andExpect(status().isOk())
+ // .andExpect(jsonPath("title", is(notNullValue())))
+ // .andExpect(jsonPath("body", is(notNullValue())))
+ // .andExpect(jsonPath("_links.crud", is(notNullValue())))
+ // .andReturn();
+ // }
+ //
+ //
+ // String createTag() throws Exception, JsonProcessingException {
+ // Map tag = new HashMap();
+ // tag.put("name", "getting-started");
+ // String tagLocation = this.mockMvc.perform(post("/crud")
+ // .contentType(MediaTypes.HAL_JSON)
+ // .content(objectMapper.writeValueAsString(tag)))
+ // .andExpect(status().isCreated())
+ // .andExpect(header().string("Location", notNullValue()))
+ // .andReturn()
+ // .getResponse()
+ // .getHeader("Location");
+ // return tagLocation;
+ // }
+ //
+ // void getTag(String tagLocation) throws Exception {
+ // this.mockMvc.perform(get(tagLocation)).andExpect(status().isOk())
+ // .andExpect(jsonPath("name", is(notNullValue())))
+ // .andExpect(jsonPath("_links.tagged-notes", is(notNullValue())));
+ // }
+ //
+ // String createTaggedNote(String tag) throws Exception {
+ // Map note = new HashMap();
+ // note.put("title", "Tagged note creation with cURL");
+ // note.put("body", "An example of how to create a tagged note using cURL");
+ // note.put("tags", Arrays.asList(tag));
+ //
+ // String noteLocation = this.mockMvc.perform(post("/notes")
+ // .contentType(MediaTypes.HAL_JSON)
+ // .content(objectMapper.writeValueAsString(note)))
+ // .andExpect(status().isCreated())
+ // .andExpect(header().string("Location", notNullValue()))
+ // .andReturn()
+ // .getResponse()
+ // .getHeader("Location");
+ // return noteLocation;
+ // }
+ //
+ // void getTags(String noteTagsLocation) throws Exception {
+ // this.mockMvc.perform(get(noteTagsLocation))
+ // .andExpect(status().isOk())
+ // .andExpect(jsonPath("_embedded.tags", hasSize(1)));
+ // }
+ //
+ // void tagExistingNote(String noteLocation, String tagLocation) throws Exception {
+ // Map update = new HashMap();
+ // update.put("tags", Arrays.asList(tagLocation));
+ // this.mockMvc.perform(patch(noteLocation)
+ // .contentType(MediaTypes.HAL_JSON)
+ // .content(objectMapper.writeValueAsString(update)))
+ // .andExpect(status().isNoContent());
+ // }
+ //
+ // MvcResult getTaggedExistingNote(String noteLocation) throws Exception {
+ // return this.mockMvc.perform(get(noteLocation)).andExpect(status().isOk()).andReturn();
+ // }
+ //
+ // void getTagsForExistingNote(String noteTagsLocation) throws Exception {
+ // this.mockMvc.perform(get(noteTagsLocation))
+ // .andExpect(status().isOk()).andExpect(jsonPath("_embedded.tags", hasSize(1)));
+ // }
+ //
+ // private String getLink(MvcResult result, String rel)
+ // throws UnsupportedEncodingException {
+ // return JsonPath.parse(result.getResponse().getContentAsString()).read("_links." + rel + ".href");
+ // }
}
diff --git a/spring-rest/.classpath b/spring-rest/.classpath
deleted file mode 100644
index 6b533711d3..0000000000
--- a/spring-rest/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-rest/.project b/spring-rest/.project
deleted file mode 100644
index 525c5e7795..0000000000
--- a/spring-rest/.project
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
- spring-rest
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/spring-rest/.springBeans b/spring-rest/.springBeans
deleted file mode 100644
index a79097f40d..0000000000
--- a/spring-rest/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/api-servlet.xml
-
-
-
-
diff --git a/spring-rest/pom.xml b/spring-rest/pom.xml
index 09a50b9579..e28f7e7e33 100644
--- a/spring-rest/pom.xml
+++ b/spring-rest/pom.xml
@@ -151,11 +151,10 @@
protobuf-java
2.6.1
-
- com.esotericsoftware.kryo
+ com.esotericsoftware
kryo
- 2.24.0
+ 4.0.0
diff --git a/spring-scurity-custom-permission/README.MD b/spring-scurity-custom-permission/README.MD
deleted file mode 100644
index 8fb14fa522..0000000000
--- a/spring-scurity-custom-permission/README.MD
+++ /dev/null
@@ -1,2 +0,0 @@
-###The Course
-The "Learn Spring Security" Classes: http://bit.ly/learnspringsecurity
diff --git a/spring-security-basic-auth/.classpath b/spring-security-basic-auth/.classpath
deleted file mode 100644
index 5778c9435e..0000000000
--- a/spring-security-basic-auth/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-basic-auth/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch b/spring-security-basic-auth/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch
deleted file mode 100644
index 627021fb96..0000000000
--- a/spring-security-basic-auth/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/spring-security-basic-auth/.project b/spring-security-basic-auth/.project
deleted file mode 100644
index 9126103207..0000000000
--- a/spring-security-basic-auth/.project
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
- spring-security-mvc-basic-auth
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/spring-security-basic-auth/.settings/.jsdtscope b/spring-security-basic-auth/.settings/.jsdtscope
deleted file mode 100644
index 7b3f0c8b9f..0000000000
--- a/spring-security-basic-auth/.settings/.jsdtscope
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/spring-security-basic-auth/.settings/org.eclipse.jdt.core.prefs b/spring-security-basic-auth/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index fb671a82a6..0000000000
--- a/spring-security-basic-auth/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,95 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
-org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.8
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=error
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=error
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
-org.eclipse.jdt.core.compiler.problem.nullReference=warning
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.8
diff --git a/spring-security-basic-auth/.settings/org.eclipse.jdt.ui.prefs b/spring-security-basic-auth/.settings/org.eclipse.jdt.ui.prefs
deleted file mode 100644
index 471e9b0d81..0000000000
--- a/spring-security-basic-auth/.settings/org.eclipse.jdt.ui.prefs
+++ /dev/null
@@ -1,55 +0,0 @@
-#Sat Jan 21 23:04:06 EET 2012
-eclipse.preferences.version=1
-editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-sp_cleanup.add_default_serial_version_id=true
-sp_cleanup.add_generated_serial_version_id=false
-sp_cleanup.add_missing_annotations=true
-sp_cleanup.add_missing_deprecated_annotations=true
-sp_cleanup.add_missing_methods=false
-sp_cleanup.add_missing_nls_tags=false
-sp_cleanup.add_missing_override_annotations=true
-sp_cleanup.add_missing_override_annotations_interface_methods=true
-sp_cleanup.add_serial_version_id=false
-sp_cleanup.always_use_blocks=true
-sp_cleanup.always_use_parentheses_in_expressions=true
-sp_cleanup.always_use_this_for_non_static_field_access=false
-sp_cleanup.always_use_this_for_non_static_method_access=false
-sp_cleanup.convert_to_enhanced_for_loop=true
-sp_cleanup.correct_indentation=true
-sp_cleanup.format_source_code=true
-sp_cleanup.format_source_code_changes_only=true
-sp_cleanup.make_local_variable_final=true
-sp_cleanup.make_parameters_final=true
-sp_cleanup.make_private_fields_final=false
-sp_cleanup.make_type_abstract_if_missing_method=false
-sp_cleanup.make_variable_declarations_final=true
-sp_cleanup.never_use_blocks=false
-sp_cleanup.never_use_parentheses_in_expressions=false
-sp_cleanup.on_save_use_additional_actions=true
-sp_cleanup.organize_imports=true
-sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
-sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
-sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
-sp_cleanup.remove_private_constructors=true
-sp_cleanup.remove_trailing_whitespaces=true
-sp_cleanup.remove_trailing_whitespaces_all=true
-sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
-sp_cleanup.remove_unnecessary_casts=true
-sp_cleanup.remove_unnecessary_nls_tags=false
-sp_cleanup.remove_unused_imports=true
-sp_cleanup.remove_unused_local_variables=false
-sp_cleanup.remove_unused_private_fields=true
-sp_cleanup.remove_unused_private_members=false
-sp_cleanup.remove_unused_private_methods=true
-sp_cleanup.remove_unused_private_types=true
-sp_cleanup.sort_members=false
-sp_cleanup.sort_members_all=false
-sp_cleanup.use_blocks=false
-sp_cleanup.use_blocks_only_for_return_and_throw=false
-sp_cleanup.use_parentheses_in_expressions=false
-sp_cleanup.use_this_for_non_static_field_access=true
-sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
-sp_cleanup.use_this_for_non_static_method_access=true
-sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/spring-security-basic-auth/.settings/org.eclipse.m2e.core.prefs b/spring-security-basic-auth/.settings/org.eclipse.m2e.core.prefs
deleted file mode 100644
index f897a7f1cb..0000000000
--- a/spring-security-basic-auth/.settings/org.eclipse.m2e.core.prefs
+++ /dev/null
@@ -1,4 +0,0 @@
-activeProfiles=
-eclipse.preferences.version=1
-resolveWorkspaceProjects=true
-version=1
diff --git a/spring-security-basic-auth/.settings/org.eclipse.m2e.wtp.prefs b/spring-security-basic-auth/.settings/org.eclipse.m2e.wtp.prefs
deleted file mode 100644
index ef86089622..0000000000
--- a/spring-security-basic-auth/.settings/org.eclipse.m2e.wtp.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.m2e.wtp.enabledProjectSpecificPrefs=false
diff --git a/spring-security-basic-auth/.settings/org.eclipse.wst.common.component b/spring-security-basic-auth/.settings/org.eclipse.wst.common.component
deleted file mode 100644
index 9a8276c85b..0000000000
--- a/spring-security-basic-auth/.settings/org.eclipse.wst.common.component
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-basic-auth/.settings/org.eclipse.wst.common.project.facet.core.xml b/spring-security-basic-auth/.settings/org.eclipse.wst.common.project.facet.core.xml
deleted file mode 100644
index f5888c1411..0000000000
--- a/spring-security-basic-auth/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/spring-security-basic-auth/.settings/org.eclipse.wst.jsdt.ui.superType.container b/spring-security-basic-auth/.settings/org.eclipse.wst.jsdt.ui.superType.container
deleted file mode 100644
index 3bd5d0a480..0000000000
--- a/spring-security-basic-auth/.settings/org.eclipse.wst.jsdt.ui.superType.container
+++ /dev/null
@@ -1 +0,0 @@
-org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
diff --git a/spring-security-basic-auth/.settings/org.eclipse.wst.jsdt.ui.superType.name b/spring-security-basic-auth/.settings/org.eclipse.wst.jsdt.ui.superType.name
deleted file mode 100644
index 05bd71b6ec..0000000000
--- a/spring-security-basic-auth/.settings/org.eclipse.wst.jsdt.ui.superType.name
+++ /dev/null
@@ -1 +0,0 @@
-Window
\ No newline at end of file
diff --git a/spring-security-basic-auth/.settings/org.eclipse.wst.validation.prefs b/spring-security-basic-auth/.settings/org.eclipse.wst.validation.prefs
deleted file mode 100644
index 0d0aee4f72..0000000000
--- a/spring-security-basic-auth/.settings/org.eclipse.wst.validation.prefs
+++ /dev/null
@@ -1,15 +0,0 @@
-DELEGATES_PREFERENCE=delegateValidatorList
-USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;
-USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;
-USER_PREFERENCE=overrideGlobalPreferencestruedisableAllValidationfalseversion1.2.402.v201212031633
-disabled=06target
-eclipse.preferences.version=1
-override=true
-suspend=false
-vals/org.eclipse.jst.jsf.ui.JSFAppConfigValidator/global=FF01
-vals/org.eclipse.jst.jsp.core.JSPBatchValidator/global=FF01
-vals/org.eclipse.jst.jsp.core.JSPContentValidator/global=FF01
-vals/org.eclipse.jst.jsp.core.TLDValidator/global=FF01
-vals/org.eclipse.wst.dtd.core.dtdDTDValidator/global=FF01
-vals/org.eclipse.wst.jsdt.web.core.JsBatchValidator/global=TF02
-vf.version=3
diff --git a/spring-security-basic-auth/.settings/org.eclipse.wst.ws.service.policy.prefs b/spring-security-basic-auth/.settings/org.eclipse.wst.ws.service.policy.prefs
deleted file mode 100644
index 9cfcabe16f..0000000000
--- a/spring-security-basic-auth/.settings/org.eclipse.wst.ws.service.policy.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.wst.ws.service.policy.projectEnabled=false
diff --git a/spring-security-basic-auth/.springBeans b/spring-security-basic-auth/.springBeans
deleted file mode 100644
index 7623a7e888..0000000000
--- a/spring-security-basic-auth/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/mvc-servlet.xml
-
-
-
-
diff --git a/spring-security-client/spring-security-jsp-authentication/.classpath b/spring-security-client/spring-security-jsp-authentication/.classpath
deleted file mode 100644
index 0cad5db2d0..0000000000
--- a/spring-security-client/spring-security-jsp-authentication/.classpath
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-client/spring-security-jsp-authentication/.project b/spring-security-client/spring-security-jsp-authentication/.project
deleted file mode 100644
index 6fbbb8518e..0000000000
--- a/spring-security-client/spring-security-jsp-authentication/.project
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
- spring-security-jsp-authenticate
-
-
-
-
-
- org.eclipse.wst.jsdt.core.javascriptValidator
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
-
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-security-client/spring-security-jsp-authorize/.classpath b/spring-security-client/spring-security-jsp-authorize/.classpath
deleted file mode 100644
index 0cad5db2d0..0000000000
--- a/spring-security-client/spring-security-jsp-authorize/.classpath
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-client/spring-security-jsp-authorize/.project b/spring-security-client/spring-security-jsp-authorize/.project
deleted file mode 100644
index a526feb28e..0000000000
--- a/spring-security-client/spring-security-jsp-authorize/.project
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
- spring-security-jsp-authorize
-
-
-
-
-
- org.eclipse.wst.jsdt.core.javascriptValidator
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
-
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-security-client/spring-security-jsp-config/.classpath b/spring-security-client/spring-security-jsp-config/.classpath
deleted file mode 100644
index 0cad5db2d0..0000000000
--- a/spring-security-client/spring-security-jsp-config/.classpath
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-client/spring-security-jsp-config/.project b/spring-security-client/spring-security-jsp-config/.project
deleted file mode 100644
index 9afe120f66..0000000000
--- a/spring-security-client/spring-security-jsp-config/.project
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
- spring-security-jsp-config
-
-
-
-
-
- org.eclipse.wst.jsdt.core.javascriptValidator
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
-
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-security-client/spring-security-mvc/.classpath b/spring-security-client/spring-security-mvc/.classpath
deleted file mode 100644
index 0cad5db2d0..0000000000
--- a/spring-security-client/spring-security-mvc/.classpath
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-client/spring-security-mvc/.project b/spring-security-client/spring-security-mvc/.project
deleted file mode 100644
index d675acbf57..0000000000
--- a/spring-security-client/spring-security-mvc/.project
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
- spring-security-mvc
-
-
-
-
-
- org.eclipse.wst.jsdt.core.javascriptValidator
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
-
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-security-client/spring-security-thymeleaf-authentication/.classpath b/spring-security-client/spring-security-thymeleaf-authentication/.classpath
deleted file mode 100644
index 0cad5db2d0..0000000000
--- a/spring-security-client/spring-security-thymeleaf-authentication/.classpath
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-client/spring-security-thymeleaf-authentication/.project b/spring-security-client/spring-security-thymeleaf-authentication/.project
deleted file mode 100644
index c6b921b16c..0000000000
--- a/spring-security-client/spring-security-thymeleaf-authentication/.project
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
- spring-security-thymeleaf-authentication
-
-
-
-
-
- org.eclipse.wst.jsdt.core.javascriptValidator
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
-
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-security-client/spring-security-thymeleaf-authorize/.classpath b/spring-security-client/spring-security-thymeleaf-authorize/.classpath
deleted file mode 100644
index 0cad5db2d0..0000000000
--- a/spring-security-client/spring-security-thymeleaf-authorize/.classpath
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-client/spring-security-thymeleaf-authorize/.project b/spring-security-client/spring-security-thymeleaf-authorize/.project
deleted file mode 100644
index b722d4072d..0000000000
--- a/spring-security-client/spring-security-thymeleaf-authorize/.project
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
- spring-security-thymeleaf-authorize
-
-
-
-
-
- org.eclipse.wst.jsdt.core.javascriptValidator
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
-
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-security-client/spring-security-thymeleaf-config/.classpath b/spring-security-client/spring-security-thymeleaf-config/.classpath
deleted file mode 100644
index 0cad5db2d0..0000000000
--- a/spring-security-client/spring-security-thymeleaf-config/.classpath
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-client/spring-security-thymeleaf-config/.project b/spring-security-client/spring-security-thymeleaf-config/.project
deleted file mode 100644
index f1e44573c4..0000000000
--- a/spring-security-client/spring-security-thymeleaf-config/.project
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
- spring-security-thymeleaf-config
-
-
-
-
-
- org.eclipse.wst.jsdt.core.javascriptValidator
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
-
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-security-custom-permission/.classpath b/spring-security-custom-permission/.classpath
deleted file mode 100644
index 0cad5db2d0..0000000000
--- a/spring-security-custom-permission/.classpath
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-custom-permission/.project b/spring-security-custom-permission/.project
deleted file mode 100644
index 06b5975e98..0000000000
--- a/spring-security-custom-permission/.project
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
- spring-security-custom-permission
-
-
-
-
-
- org.eclipse.wst.jsdt.core.javascriptValidator
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
-
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
-
-
diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/persistence/model/User.java b/spring-security-custom-permission/src/main/java/org/baeldung/persistence/model/User.java
index 86b81cdcee..112d502105 100644
--- a/spring-security-custom-permission/src/main/java/org/baeldung/persistence/model/User.java
+++ b/spring-security-custom-permission/src/main/java/org/baeldung/persistence/model/User.java
@@ -1,8 +1,5 @@
package org.baeldung.persistence.model;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
import java.util.Set;
import javax.persistence.Column;
@@ -16,14 +13,8 @@ import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
@Entity
-public class User implements UserDetails {
-
- private static final long serialVersionUID = 1L;
+public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@@ -57,7 +48,6 @@ public class User implements UserDetails {
this.id = id;
}
- @Override
public String getUsername() {
return username;
}
@@ -66,7 +56,6 @@ public class User implements UserDetails {
this.username = username;
}
- @Override
public String getPassword() {
return password;
}
@@ -93,37 +82,6 @@ public class User implements UserDetails {
//
- @Override
- public Collection extends GrantedAuthority> getAuthorities() {
- final List authorities = new ArrayList();
- for (final Privilege privilege : this.getPrivileges()) {
- authorities.add(new SimpleGrantedAuthority(privilege.getName()));
- }
- return authorities;
- }
-
- @Override
- public boolean isAccountNonExpired() {
- return true;
- }
-
- @Override
- public boolean isAccountNonLocked() {
- return true;
- }
-
- @Override
- public boolean isCredentialsNonExpired() {
- return true;
- }
-
- @Override
- public boolean isEnabled() {
- return true;
- }
-
- //
-
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomMethodSecurityExpressionRoot.java b/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomMethodSecurityExpressionRoot.java
index a3f4644592..2d84536a14 100644
--- a/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomMethodSecurityExpressionRoot.java
+++ b/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomMethodSecurityExpressionRoot.java
@@ -16,7 +16,7 @@ public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot i
//
public boolean isMember(Long OrganizationId) {
- final User user = (User) this.getPrincipal();
+ final User user = ((MyUserPrincipal) this.getPrincipal()).getUser();
return user.getOrganization().getId().longValue() == OrganizationId.longValue();
}
diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomPermissionEvaluator.java b/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomPermissionEvaluator.java
index e81f9f8939..5d96673a8f 100644
--- a/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomPermissionEvaluator.java
+++ b/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomPermissionEvaluator.java
@@ -10,17 +10,10 @@ public class CustomPermissionEvaluator implements PermissionEvaluator {
@Override
public boolean hasPermission(Authentication auth, Object targetDomainObject, Object permission) {
- System.out.println(auth);
if ((auth == null) || (targetDomainObject == null) || !(permission instanceof String)) {
return false;
}
- String targetType = "";
- if (targetDomainObject instanceof String) {
- targetType = targetDomainObject.toString().toUpperCase();
- } else {
- targetType = targetDomainObject.getClass().getSimpleName().toUpperCase();
- System.out.println(targetType);
- }
+ final String targetType = targetDomainObject.getClass().getSimpleName().toUpperCase();
return hasPrivilege(auth, targetType, permission.toString().toUpperCase());
}
diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/security/MySecurityExpressionRoot.java b/spring-security-custom-permission/src/main/java/org/baeldung/security/MySecurityExpressionRoot.java
index a09d166798..4d3561b325 100644
--- a/spring-security-custom-permission/src/main/java/org/baeldung/security/MySecurityExpressionRoot.java
+++ b/spring-security-custom-permission/src/main/java/org/baeldung/security/MySecurityExpressionRoot.java
@@ -47,6 +47,14 @@ public class MySecurityExpressionRoot implements MethodSecurityExpressionOperati
throw new RuntimeException("method hasAuthority() not allowed");
}
+ //
+ public boolean isMember(Long OrganizationId) {
+ final User user = ((MyUserPrincipal) this.getPrincipal()).getUser();
+ return user.getOrganization().getId().longValue() == OrganizationId.longValue();
+ }
+
+ //
+
@Override
public final boolean hasAnyAuthority(String... authorities) {
return hasAnyAuthorityName(null, authorities);
@@ -168,14 +176,6 @@ public class MySecurityExpressionRoot implements MethodSecurityExpressionOperati
return defaultRolePrefix + role;
}
- //
- public boolean isMember(Long OrganizationId) {
- final User user = (User) this.getPrincipal();
- return user.getOrganization().getId().longValue() == OrganizationId.longValue();
- }
-
- //
-
@Override
public Object getFilterObject() {
return this.filterObject;
diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/security/MyUserDetailsService.java b/spring-security-custom-permission/src/main/java/org/baeldung/security/MyUserDetailsService.java
index 19276a906e..685219728f 100644
--- a/spring-security-custom-permission/src/main/java/org/baeldung/security/MyUserDetailsService.java
+++ b/spring-security-custom-permission/src/main/java/org/baeldung/security/MyUserDetailsService.java
@@ -26,6 +26,6 @@ public class MyUserDetailsService implements UserDetailsService {
if (user == null) {
throw new UsernameNotFoundException(username);
}
- return user;
+ return new MyUserPrincipal(user);
}
}
diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/security/MyUserPrincipal.java b/spring-security-custom-permission/src/main/java/org/baeldung/security/MyUserPrincipal.java
new file mode 100644
index 0000000000..437bb02cdb
--- /dev/null
+++ b/spring-security-custom-permission/src/main/java/org/baeldung/security/MyUserPrincipal.java
@@ -0,0 +1,72 @@
+package org.baeldung.security;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.baeldung.persistence.model.Privilege;
+import org.baeldung.persistence.model.User;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+public class MyUserPrincipal implements UserDetails {
+
+ private static final long serialVersionUID = 1L;
+
+ private final User user;
+
+ //
+
+ public MyUserPrincipal(User user) {
+ this.user = user;
+ }
+
+ //
+
+ @Override
+ public String getUsername() {
+ return user.getUsername();
+ }
+
+ @Override
+ public String getPassword() {
+ return user.getPassword();
+ }
+
+ @Override
+ public Collection extends GrantedAuthority> getAuthorities() {
+ final List authorities = new ArrayList();
+ for (final Privilege privilege : user.getPrivileges()) {
+ authorities.add(new SimpleGrantedAuthority(privilege.getName()));
+ }
+ return authorities;
+ }
+
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isAccountNonLocked() {
+ return true;
+ }
+
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ //
+
+ public User getUser() {
+ return user;
+ }
+
+}
diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/web/MainController.java b/spring-security-custom-permission/src/main/java/org/baeldung/web/MainController.java
index 7e279907c6..4752f7bdd9 100644
--- a/spring-security-custom-permission/src/main/java/org/baeldung/web/MainController.java
+++ b/spring-security-custom-permission/src/main/java/org/baeldung/web/MainController.java
@@ -21,7 +21,8 @@ public class MainController {
@Autowired
private OrganizationRepository organizationRepository;
- @PreAuthorize("hasPermission('Foo', 'read')")
+ // @PostAuthorize("hasPermission(returnObject, 'read')")
+ @PreAuthorize("hasPermission(#id, 'Foo', 'read')")
@RequestMapping(method = RequestMethod.GET, value = "/foos/{id}")
@ResponseBody
public Foo findById(@PathVariable final long id) {
diff --git a/spring-security-mvc-custom/.classpath b/spring-security-mvc-custom/.classpath
deleted file mode 100644
index bbfdf4ade5..0000000000
--- a/spring-security-mvc-custom/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-mvc-custom/.project b/spring-security-mvc-custom/.project
deleted file mode 100644
index 81c640f9e3..0000000000
--- a/spring-security-mvc-custom/.project
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
- spring-security-mvc-custom
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/spring-security-mvc-custom/.springBeans b/spring-security-mvc-custom/.springBeans
deleted file mode 100644
index 7623a7e888..0000000000
--- a/spring-security-mvc-custom/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/mvc-servlet.xml
-
-
-
-
diff --git a/spring-security-mvc-digest-auth/.classpath b/spring-security-mvc-digest-auth/.classpath
deleted file mode 100644
index bbfdf4ade5..0000000000
--- a/spring-security-mvc-digest-auth/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-mvc-digest-auth/.project b/spring-security-mvc-digest-auth/.project
deleted file mode 100644
index f387b771fc..0000000000
--- a/spring-security-mvc-digest-auth/.project
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
- spring-security-mvc-digest-auth
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/spring-security-mvc-digest-auth/.springBeans b/spring-security-mvc-digest-auth/.springBeans
deleted file mode 100644
index 7623a7e888..0000000000
--- a/spring-security-mvc-digest-auth/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/mvc-servlet.xml
-
-
-
-
diff --git a/spring-security-mvc-ldap/.classpath b/spring-security-mvc-ldap/.classpath
deleted file mode 100644
index 6acf3eeeca..0000000000
--- a/spring-security-mvc-ldap/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-mvc-ldap/.project b/spring-security-mvc-ldap/.project
deleted file mode 100644
index 17814c8c03..0000000000
--- a/spring-security-mvc-ldap/.project
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
- spring-security-mvc-ldap
-
-
-
-
-
- org.eclipse.wst.jsdt.core.javascriptValidator
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.hibernate.eclipse.console.hibernateBuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.wst.jsdt.core.jsNature
- org.hibernate.eclipse.console.hibernateNature
-
-
diff --git a/spring-security-mvc-login/.classpath b/spring-security-mvc-login/.classpath
deleted file mode 100644
index bbfdf4ade5..0000000000
--- a/spring-security-mvc-login/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-mvc-login/.project b/spring-security-mvc-login/.project
deleted file mode 100644
index d52a48244a..0000000000
--- a/spring-security-mvc-login/.project
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
- spring-security-mvc-login
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/spring-security-mvc-login/.springBeans b/spring-security-mvc-login/.springBeans
deleted file mode 100644
index 7623a7e888..0000000000
--- a/spring-security-mvc-login/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/mvc-servlet.xml
-
-
-
-
diff --git a/spring-security-mvc-session/.classpath b/spring-security-mvc-session/.classpath
deleted file mode 100644
index bbfdf4ade5..0000000000
--- a/spring-security-mvc-session/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-mvc-session/.project b/spring-security-mvc-session/.project
deleted file mode 100644
index 4670a72a3b..0000000000
--- a/spring-security-mvc-session/.project
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
- spring-security-mvc-session
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/spring-security-mvc-session/.springBeans b/spring-security-mvc-session/.springBeans
deleted file mode 100644
index 7623a7e888..0000000000
--- a/spring-security-mvc-session/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/mvc-servlet.xml
-
-
-
-
diff --git a/spring-security-rest-basic-auth/.classpath b/spring-security-rest-basic-auth/.classpath
deleted file mode 100644
index 5778c9435e..0000000000
--- a/spring-security-rest-basic-auth/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-rest-basic-auth/.project b/spring-security-rest-basic-auth/.project
deleted file mode 100644
index 17907f1636..0000000000
--- a/spring-security-rest-basic-auth/.project
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
- spring-security-rest-basic-auth
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/spring-security-rest-basic-auth/.springBeans b/spring-security-rest-basic-auth/.springBeans
deleted file mode 100644
index a79097f40d..0000000000
--- a/spring-security-rest-basic-auth/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/api-servlet.xml
-
-
-
-
diff --git a/spring-security-rest-custom/.classpath b/spring-security-rest-custom/.classpath
deleted file mode 100644
index 5778c9435e..0000000000
--- a/spring-security-rest-custom/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-rest-custom/.project b/spring-security-rest-custom/.project
deleted file mode 100644
index 801347984e..0000000000
--- a/spring-security-rest-custom/.project
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
- spring-security-rest-custom
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/spring-security-rest-custom/.springBeans b/spring-security-rest-custom/.springBeans
deleted file mode 100644
index f25fc5ab49..0000000000
--- a/spring-security-rest-custom/.springBeans
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
- 1
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-rest-digest-auth/.classpath b/spring-security-rest-digest-auth/.classpath
deleted file mode 100644
index 5778c9435e..0000000000
--- a/spring-security-rest-digest-auth/.classpath
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-rest-digest-auth/.project b/spring-security-rest-digest-auth/.project
deleted file mode 100644
index 7c28666685..0000000000
--- a/spring-security-rest-digest-auth/.project
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
- spring-security-rest-digest-auth
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.springframework.ide.eclipse.core.springnature
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/spring-security-rest-digest-auth/.springBeans b/spring-security-rest-digest-auth/.springBeans
deleted file mode 100644
index a79097f40d..0000000000
--- a/spring-security-rest-digest-auth/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/api-servlet.xml
-
-
-
-
diff --git a/spring-security-rest-full/.classpath b/spring-security-rest-full/.classpath
deleted file mode 100644
index 979639ff7d..0000000000
--- a/spring-security-rest-full/.classpath
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-security-rest-full/.project b/spring-security-rest-full/.project
deleted file mode 100644
index 188b8b07fe..0000000000
--- a/spring-security-rest-full/.project
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
- spring-security-rest-full
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
-
- org.eclipse.ui.externaltools.ExternalToolBuilder
- full,incremental,
-
-
-