Reformat rest of the design patterns - Issue #224
This commit is contained in:
parent
449340bd2b
commit
306b1f3d31
@ -6,21 +6,21 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Double Checked Locking is a concurrency design pattern used to reduce the overhead
|
* Double Checked Locking is a concurrency design pattern used to reduce the overhead of acquiring a
|
||||||
* of acquiring a lock by first testing the locking criterion (the "lock hint") without
|
* lock by first testing the locking criterion (the "lock hint") without actually acquiring the
|
||||||
* actually acquiring the lock. Only if the locking criterion check indicates that
|
* lock. Only if the locking criterion check indicates that locking is required does the actual
|
||||||
* locking is required does the actual locking logic proceed.
|
* locking logic proceed.
|
||||||
* <p>
|
* <p>
|
||||||
* In {@link Inventory} we store the items with a given size. However, we do not store
|
* In {@link Inventory} we store the items with a given size. However, we do not store more items
|
||||||
* more items than the inventory size. To address concurrent access problems we
|
* than the inventory size. To address concurrent access problems we use double checked locking to
|
||||||
* use double checked locking to add item to inventory. In this method, the
|
* add item to inventory. In this method, the thread which gets the lock first adds the item.
|
||||||
* thread which gets the lock first adds the item.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
@ -28,8 +28,7 @@ public class App {
|
|||||||
ExecutorService executorService = Executors.newFixedThreadPool(3);
|
ExecutorService executorService = Executors.newFixedThreadPool(3);
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
executorService.execute(() -> {
|
executorService.execute(() -> {
|
||||||
while (inventory.addItem(new Item()))
|
while (inventory.addItem(new Item()));
|
||||||
;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,8 +28,7 @@ public class Inventory {
|
|||||||
try {
|
try {
|
||||||
if (items.size() < inventorySize) {
|
if (items.size() < inventorySize) {
|
||||||
items.add(item);
|
items.add(item);
|
||||||
System.out.println(Thread.currentThread()
|
System.out.println(Thread.currentThread() + ": items.size()=" + items.size()
|
||||||
+ ": items.size()=" + items.size()
|
|
||||||
+ ", inventorySize=" + inventorySize);
|
+ ", inventorySize=" + inventorySize);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -39,5 +38,4 @@ public class Inventory {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,20 +6,20 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* When a message with a parameter is sent to an object, the resultant behaviour is defined by the
|
* When a message with a parameter is sent to an object, the resultant behaviour is defined by the
|
||||||
* implementation of that method in the receiver. Sometimes the behaviour must also be determined
|
* implementation of that method in the receiver. Sometimes the behaviour must also be determined by
|
||||||
* by the type of the parameter.
|
* the type of the parameter.
|
||||||
* <p>
|
* <p>
|
||||||
* One way to implement this would be to create multiple instanceof-checks for the methods parameter.
|
* One way to implement this would be to create multiple instanceof-checks for the methods
|
||||||
* However, this creates a maintenance issue. When new types are added we would also need to change
|
* parameter. However, this creates a maintenance issue. When new types are added we would also need
|
||||||
* the method's implementation and add a new instanceof-check. This violates the single responsibility
|
* to change the method's implementation and add a new instanceof-check. This violates the single
|
||||||
* principle - a class should have only one reason to change.
|
* responsibility principle - a class should have only one reason to change.
|
||||||
* <p>
|
* <p>
|
||||||
* Instead of the instanceof-checks a better way is to make another virtual call on the parameter
|
* Instead of the instanceof-checks a better way is to make another virtual call on the parameter
|
||||||
* object. This way new functionality can be easily added without the need to modify existing
|
* object. This way new functionality can be easily added without the need to modify existing
|
||||||
* implementation (open-closed principle).
|
* implementation (open-closed principle).
|
||||||
* <p>
|
* <p>
|
||||||
* In this example we have hierarchy of objects ({@link GameObject}) that can collide to each other. Each
|
* In this example we have hierarchy of objects ({@link GameObject}) that can collide to each other.
|
||||||
* object has its own coordinates which are checked against the other objects' coordinates. If
|
* Each object has its own coordinates which are checked against the other objects' coordinates. If
|
||||||
* there is an overlap, then the objects collide utilizing the Double Dispatch pattern.
|
* there is an overlap, then the objects collide utilizing the Double Dispatch pattern.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -27,6 +27,7 @@ public class App {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
@ -40,7 +41,10 @@ public class App {
|
|||||||
System.out.println("");
|
System.out.println("");
|
||||||
|
|
||||||
// collision check
|
// collision check
|
||||||
objects.stream().forEach(o1 -> objects.stream().forEach(o2 -> { if (o1 != o2 && o1.intersectsWith(o2)) o1.collision(o2); } ));
|
objects.stream().forEach(o1 -> objects.stream().forEach(o2 -> {
|
||||||
|
if (o1 != o2 && o1.intersectsWith(o2))
|
||||||
|
o1.collision(o2);
|
||||||
|
}));
|
||||||
System.out.println("");
|
System.out.println("");
|
||||||
|
|
||||||
// output eventual object statuses
|
// output eventual object statuses
|
||||||
|
@ -2,8 +2,7 @@ package com.iluwatar.doubledispatch;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Game objects have coordinates and some
|
* Game objects have coordinates and some other status information.
|
||||||
* other status information.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class GameObject extends Rectangle {
|
public abstract class GameObject extends Rectangle {
|
||||||
|
@ -18,21 +18,25 @@ public class Meteoroid extends GameObject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collisionResolve(FlamingAsteroid asteroid) {
|
public void collisionResolve(FlamingAsteroid asteroid) {
|
||||||
System.out.println(String.format("%s hits %s.", asteroid.getClass().getSimpleName(), this.getClass().getSimpleName()));
|
System.out.println(String.format("%s hits %s.", asteroid.getClass().getSimpleName(), this
|
||||||
|
.getClass().getSimpleName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collisionResolve(Meteoroid meteoroid) {
|
public void collisionResolve(Meteoroid meteoroid) {
|
||||||
System.out.println(String.format("%s hits %s.", meteoroid.getClass().getSimpleName(), this.getClass().getSimpleName()));
|
System.out.println(String.format("%s hits %s.", meteoroid.getClass().getSimpleName(), this
|
||||||
|
.getClass().getSimpleName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collisionResolve(SpaceStationMir mir) {
|
public void collisionResolve(SpaceStationMir mir) {
|
||||||
System.out.println(String.format("%s hits %s.", mir.getClass().getSimpleName(), this.getClass().getSimpleName()));
|
System.out.println(String.format("%s hits %s.", mir.getClass().getSimpleName(), this.getClass()
|
||||||
|
.getSimpleName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collisionResolve(SpaceStationIss iss) {
|
public void collisionResolve(SpaceStationIss iss) {
|
||||||
System.out.println(String.format("%s hits %s.", iss.getClass().getSimpleName(), this.getClass().getSimpleName()));
|
System.out.println(String.format("%s hits %s.", iss.getClass().getSimpleName(), this.getClass()
|
||||||
|
.getSimpleName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,7 @@ package com.iluwatar.doubledispatch;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Rectangle has coordinates and can be checked for overlap against
|
* Rectangle has coordinates and can be checked for overlap against other Rectangles.
|
||||||
* other Rectangles.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Rectangle {
|
public class Rectangle {
|
||||||
@ -23,18 +22,22 @@ public class Rectangle {
|
|||||||
public int getLeft() {
|
public int getLeft() {
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTop() {
|
public int getTop() {
|
||||||
return top;
|
return top;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRight() {
|
public int getRight() {
|
||||||
return right;
|
return right;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBottom() {
|
public int getBottom() {
|
||||||
return bottom;
|
return bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean intersectsWith(Rectangle r) {
|
boolean intersectsWith(Rectangle r) {
|
||||||
return !(r.getLeft() > getRight() || r.getRight() < getLeft() || r.getTop() > getBottom() || r.getBottom() < getTop());
|
return !(r.getLeft() > getRight() || r.getRight() < getLeft() || r.getTop() > getBottom() || r
|
||||||
|
.getBottom() < getTop());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -18,34 +18,31 @@ public class SpaceStationMir extends GameObject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collisionResolve(FlamingAsteroid asteroid) {
|
public void collisionResolve(FlamingAsteroid asteroid) {
|
||||||
System.out.println(String.format("%s hits %s. %s is damaged! %s is set on fire!",
|
System.out.println(String.format("%s hits %s. %s is damaged! %s is set on fire!", asteroid
|
||||||
asteroid.getClass().getSimpleName(), this.getClass().getSimpleName(),
|
.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass()
|
||||||
this.getClass().getSimpleName(), this.getClass().getSimpleName()));
|
.getSimpleName(), this.getClass().getSimpleName()));
|
||||||
setDamaged(true);
|
setDamaged(true);
|
||||||
setOnFire(true);
|
setOnFire(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collisionResolve(Meteoroid meteoroid) {
|
public void collisionResolve(Meteoroid meteoroid) {
|
||||||
System.out.println(String.format("%s hits %s. %s is damaged!",
|
System.out.println(String.format("%s hits %s. %s is damaged!", meteoroid.getClass()
|
||||||
meteoroid.getClass().getSimpleName(), this.getClass().getSimpleName(),
|
.getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName()));
|
||||||
this.getClass().getSimpleName()));
|
|
||||||
setDamaged(true);
|
setDamaged(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collisionResolve(SpaceStationMir mir) {
|
public void collisionResolve(SpaceStationMir mir) {
|
||||||
System.out.println(String.format("%s hits %s. %s is damaged!",
|
System.out.println(String.format("%s hits %s. %s is damaged!", mir.getClass().getSimpleName(),
|
||||||
mir.getClass().getSimpleName(), this.getClass().getSimpleName(),
|
this.getClass().getSimpleName(), this.getClass().getSimpleName()));
|
||||||
this.getClass().getSimpleName()));
|
|
||||||
setDamaged(true);
|
setDamaged(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collisionResolve(SpaceStationIss iss) {
|
public void collisionResolve(SpaceStationIss iss) {
|
||||||
System.out.println(String.format("%s hits %s. %s is damaged!",
|
System.out.println(String.format("%s hits %s. %s is damaged!", iss.getClass().getSimpleName(),
|
||||||
iss.getClass().getSimpleName(), this.getClass().getSimpleName(),
|
this.getClass().getSimpleName(), this.getClass().getSimpleName()));
|
||||||
this.getClass().getSimpleName()));
|
|
||||||
setDamaged(true);
|
setDamaged(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,22 +5,23 @@ import java.util.List;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* A system with lots of objects can lead to complexities when a client wants to subscribe
|
* A system with lots of objects can lead to complexities when a client wants to subscribe to
|
||||||
* to events. The client has to find and register for each object individually, if each
|
* events. The client has to find and register for each object individually, if each object has
|
||||||
* object has multiple events then each event requires a separate subscription.
|
* multiple events then each event requires a separate subscription.
|
||||||
* <p>
|
* <p>
|
||||||
* An Event Aggregator acts as a single source of events for many objects. It registers
|
* An Event Aggregator acts as a single source of events for many objects. It registers for all the
|
||||||
* for all the events of the many objects allowing clients to register with just the aggregator.
|
* events of the many objects allowing clients to register with just the aggregator.
|
||||||
* <p>
|
* <p>
|
||||||
* In the example {@link LordBaelish}, {@link LordVarys} and {@link Scout} deliver events to
|
* In the example {@link LordBaelish}, {@link LordVarys} and {@link Scout} deliver events to
|
||||||
* {@link KingsHand}. {@link KingsHand}, the event aggregator, then delivers the events
|
* {@link KingsHand}. {@link KingsHand}, the event aggregator, then delivers the events to
|
||||||
* to {@link KingJoffrey}.
|
* {@link KingJoffrey}.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -7,7 +7,8 @@ package com.iluwatar.event.aggregator;
|
|||||||
*/
|
*/
|
||||||
public enum Event {
|
public enum Event {
|
||||||
|
|
||||||
STARK_SIGHTED("Stark sighted"), WARSHIPS_APPROACHING("Warships approaching"), TRAITOR_DETECTED("Traitor detected");
|
STARK_SIGHTED("Stark sighted"), WARSHIPS_APPROACHING("Warships approaching"), TRAITOR_DETECTED(
|
||||||
|
"Traitor detected");
|
||||||
|
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
@ -2,8 +2,7 @@ package com.iluwatar.event.aggregator;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* KingsHand observes events from multiple sources and delivers them
|
* KingsHand observes events from multiple sources and delivers them to listeners.
|
||||||
* to listeners.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class KingsHand extends EventEmitter implements EventObserver {
|
public class KingsHand extends EventEmitter implements EventObserver {
|
||||||
|
@ -7,7 +7,8 @@ package com.iluwatar.event.aggregator;
|
|||||||
*/
|
*/
|
||||||
public enum Weekday {
|
public enum Weekday {
|
||||||
|
|
||||||
MONDAY("Monday"), TUESDAY("Tuesday"), WEDNESDAY("Wednesday"), THURSDAY("Thursday"), FRIDAY("Friday"), SATURDAY("Saturday"), SUNDAY("Sunday");
|
MONDAY("Monday"), TUESDAY("Tuesday"), WEDNESDAY("Wednesday"), THURSDAY("Thursday"), FRIDAY(
|
||||||
|
"Friday"), SATURDAY("Saturday"), SUNDAY("Sunday");
|
||||||
|
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
package com.iluwatar.event.aggregator;
|
package com.iluwatar.event.aggregator;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.iluwatar.event.aggregator.App;
|
import com.iluwatar.event.aggregator.App;
|
||||||
|
@ -4,19 +4,20 @@ import java.io.FileWriter;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Execute Around idiom specifies some code to be executed before and after
|
* The Execute Around idiom specifies some code to be executed before and after a method. Typically
|
||||||
* a method. Typically the idiom is used when the API has methods to be executed in
|
* the idiom is used when the API has methods to be executed in pairs, such as resource
|
||||||
* pairs, such as resource allocation/deallocation or lock acquisition/release.
|
* allocation/deallocation or lock acquisition/release.
|
||||||
* <p>
|
* <p>
|
||||||
* In this example, we have {@link SimpleFileWriter} class that opens and closes the file
|
* In this example, we have {@link SimpleFileWriter} class that opens and closes the file for the
|
||||||
* for the user. The user specifies only what to do with the file by providing the
|
* user. The user specifies only what to do with the file by providing the {@link FileWriterAction}
|
||||||
* {@link FileWriterAction} implementation.
|
* implementation.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
|
@ -5,9 +5,8 @@ import java.io.IOException;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* SimpleFileWriter handles opening and closing file for the user. The user
|
* SimpleFileWriter handles opening and closing file for the user. The user only has to specify what
|
||||||
* only has to specify what to do with the file resource through {@link FileWriterAction}
|
* to do with the file resource through {@link FileWriterAction} parameter.
|
||||||
* parameter.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SimpleFileWriter {
|
public class SimpleFileWriter {
|
||||||
|
@ -2,21 +2,22 @@ package com.iluwatar.facade;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* The Facade design pattern is often used when a system is very complex or difficult
|
* The Facade design pattern is often used when a system is very complex or difficult to understand
|
||||||
* to understand because the system has a large number of interdependent classes or
|
* because the system has a large number of interdependent classes or its source code is
|
||||||
* its source code is unavailable. This pattern hides the complexities of the larger
|
* unavailable. This pattern hides the complexities of the larger system and provides a simpler
|
||||||
* system and provides a simpler interface to the client. It typically involves a single
|
* interface to the client. It typically involves a single wrapper class which contains a set of
|
||||||
* wrapper class which contains a set of members required by client. These members access
|
* members required by client. These members access the system on behalf of the facade client and
|
||||||
* the system on behalf of the facade client and hide the implementation details.
|
* hide the implementation details.
|
||||||
* <p>
|
* <p>
|
||||||
* In this example the Facade is ({@link DwarvenGoldmineFacade}) and it provides a simpler
|
* In this example the Facade is ({@link DwarvenGoldmineFacade}) and it provides a simpler interface
|
||||||
* interface to the goldmine subsystem.
|
* to the goldmine subsystem.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -16,5 +16,4 @@ public class DwarvenCartOperator extends DwarvenMineWorker {
|
|||||||
public String name() {
|
public String name() {
|
||||||
return "Dwarf cart operator";
|
return "Dwarf cart operator";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,5 +16,4 @@ public class DwarvenGoldDigger extends DwarvenMineWorker {
|
|||||||
public String name() {
|
public String name() {
|
||||||
return "Dwarf gold digger";
|
return "Dwarf gold digger";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,10 @@ import java.util.List;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* DwarvenGoldmineFacade provides a single interface
|
* DwarvenGoldmineFacade provides a single interface through which users can operate the subsystems.
|
||||||
* through which users can operate the subsystems.
|
|
||||||
*
|
*
|
||||||
* This makes the goldmine easier to operate and
|
* This makes the goldmine easier to operate and cuts the dependencies from the goldmine user to the
|
||||||
* cuts the dependencies from the goldmine user to
|
* subsystems.
|
||||||
* the subsystems.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DwarvenGoldmineFacade {
|
public class DwarvenGoldmineFacade {
|
||||||
@ -37,7 +35,8 @@ public class DwarvenGoldmineFacade {
|
|||||||
makeActions(workers, DwarvenMineWorker.Action.GO_HOME, DwarvenMineWorker.Action.GO_TO_SLEEP);
|
makeActions(workers, DwarvenMineWorker.Action.GO_HOME, DwarvenMineWorker.Action.GO_TO_SLEEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void makeActions(Collection<DwarvenMineWorker> workers, DwarvenMineWorker.Action... actions) {
|
private void makeActions(Collection<DwarvenMineWorker> workers,
|
||||||
|
DwarvenMineWorker.Action... actions) {
|
||||||
for (DwarvenMineWorker worker : workers) {
|
for (DwarvenMineWorker worker : workers) {
|
||||||
worker.action(actions);
|
worker.action(actions);
|
||||||
}
|
}
|
||||||
|
@ -16,5 +16,4 @@ public class DwarvenTunnelDigger extends DwarvenMineWorker {
|
|||||||
public String name() {
|
public String name() {
|
||||||
return "Dwarven tunnel digger";
|
return "Dwarven tunnel digger";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,23 +2,23 @@ package com.iluwatar.factory.method;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* The Factory Method is a creational design pattern which uses factory methods to deal
|
* The Factory Method is a creational design pattern which uses factory methods to deal with the
|
||||||
* with the problem of creating objects without specifying the exact class of object
|
* problem of creating objects without specifying the exact class of object that will be created.
|
||||||
* that will be created. This is done by creating objects via calling a factory
|
* This is done by creating objects via calling a factory method either specified in an interface
|
||||||
* method either specified in an interface and implemented by child classes, or implemented
|
* and implemented by child classes, or implemented in a base class and optionally overridden by
|
||||||
* in a base class and optionally overridden by derived classes—rather than by calling a
|
* derived classes—rather than by calling a constructor.
|
||||||
* constructor.
|
|
||||||
* <p>
|
* <p>
|
||||||
* In this Factory Method example we have an interface ({@link Blacksmith}) with a method for
|
* In this Factory Method example we have an interface ({@link Blacksmith}) with a method for
|
||||||
* creating objects ({@link Blacksmith#manufactureWeapon}). The concrete subclasses
|
* creating objects ({@link Blacksmith#manufactureWeapon}). The concrete subclasses (
|
||||||
* ({@link OrcBlacksmith}, {@link ElfBlacksmith}) then override the method to produce
|
* {@link OrcBlacksmith}, {@link ElfBlacksmith}) then override the method to produce objects of
|
||||||
* objects of their liking.
|
* their liking.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -17,5 +17,4 @@ public class ElfWeapon implements Weapon {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "Elven " + weaponType;
|
return "Elven " + weaponType;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,5 +10,4 @@ public class OrcBlacksmith implements Blacksmith {
|
|||||||
public Weapon manufactureWeapon(WeaponType weaponType) {
|
public Weapon manufactureWeapon(WeaponType weaponType) {
|
||||||
return new OrcWeapon(weaponType);
|
return new OrcWeapon(weaponType);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,5 +17,4 @@ public class OrcWeapon implements Weapon {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "Orcish " + weaponType;
|
return "Orcish " + weaponType;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,15 @@ import java.util.function.Predicate;
|
|||||||
import static java.lang.String.valueOf;
|
import static java.lang.String.valueOf;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Fluent Interface pattern is useful when you want to provide an easy readable, flowing API. Those
|
* The Fluent Interface pattern is useful when you want to provide an easy readable, flowing API.
|
||||||
* interfaces tend to mimic domain specific languages, so they can nearly be read as human languages.
|
* Those interfaces tend to mimic domain specific languages, so they can nearly be read as human
|
||||||
|
* languages.
|
||||||
* <p>
|
* <p>
|
||||||
* In this example two implementations of a {@link FluentIterable} interface are given. The
|
* In this example two implementations of a {@link FluentIterable} interface are given. The
|
||||||
* {@link SimpleFluentIterable} evaluates eagerly and would be too costly for real world applications.
|
* {@link SimpleFluentIterable} evaluates eagerly and would be too costly for real world
|
||||||
* The {@link LazyFluentIterable} is evaluated on termination. Their usage is demonstrated with a
|
* applications. The {@link LazyFluentIterable} is evaluated on termination. Their usage is
|
||||||
* simple number list that is filtered, transformed and collected. The result is printed afterwards.
|
* demonstrated with a simple number list that is filtered, transformed and collected. The result is
|
||||||
|
* printed afterwards.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
@ -25,10 +27,8 @@ public class App {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
List<Integer> integerList = new ArrayList<>();
|
List<Integer> integerList = new ArrayList<>();
|
||||||
integerList.addAll(Arrays.asList(
|
integerList.addAll(Arrays.asList(1, -61, 14, -22, 18, -87, 6, 64, -82, 26, -98, 97, 45, 23, 2,
|
||||||
1, -61, 14, -22, 18, -87, 6, 64, -82, 26, -98, 97,
|
-68, 45));
|
||||||
45, 23, 2, -68, 45
|
|
||||||
));
|
|
||||||
|
|
||||||
prettyPrint("The initial list contains: ", integerList);
|
prettyPrint("The initial list contains: ", integerList);
|
||||||
|
|
||||||
|
@ -7,7 +7,8 @@ package com.iluwatar.flux.action;
|
|||||||
*/
|
*/
|
||||||
public enum Content {
|
public enum Content {
|
||||||
|
|
||||||
PRODUCTS("Products - This page lists the company's products."), COMPANY("Company - This page displays information about the company.");
|
PRODUCTS("Products - This page lists the company's products."), COMPANY(
|
||||||
|
"Company - This page displays information about the company.");
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
|
@ -11,13 +11,14 @@ import com.iluwatar.flux.view.MenuView;
|
|||||||
*
|
*
|
||||||
* Flux is the application architecture that Facebook uses for building client-side web
|
* Flux is the application architecture that Facebook uses for building client-side web
|
||||||
* applications. Flux eschews MVC in favor of a unidirectional data flow. When a user interacts with
|
* applications. Flux eschews MVC in favor of a unidirectional data flow. When a user interacts with
|
||||||
* a React view, the view propagates an action through a central dispatcher, to the various stores that
|
* a React view, the view propagates an action through a central dispatcher, to the various stores
|
||||||
* hold the application's data and business logic, which updates all of the views that are affected.
|
* that hold the application's data and business logic, which updates all of the views that are
|
||||||
|
* affected.
|
||||||
* <p>
|
* <p>
|
||||||
* This example has two views: menu and content. They represent typical main menu and content area of
|
* This example has two views: menu and content. They represent typical main menu and content area
|
||||||
* a web page. When menu item is clicked it triggers events through the dispatcher. The events are
|
* of a web page. When menu item is clicked it triggers events through the dispatcher. The events
|
||||||
* received and handled by the stores updating their data as needed. The stores then notify the views
|
* are received and handled by the stores updating their data as needed. The stores then notify the
|
||||||
* that they should rerender themselves.
|
* views that they should rerender themselves.
|
||||||
* <p>
|
* <p>
|
||||||
* http://facebook.github.io/flux/docs/overview.html
|
* http://facebook.github.io/flux/docs/overview.html
|
||||||
*
|
*
|
||||||
@ -26,6 +27,7 @@ public class App {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -21,8 +21,7 @@ public class Dispatcher {
|
|||||||
|
|
||||||
private List<Store> stores = new LinkedList<>();
|
private List<Store> stores = new LinkedList<>();
|
||||||
|
|
||||||
private Dispatcher() {
|
private Dispatcher() {}
|
||||||
}
|
|
||||||
|
|
||||||
public static Dispatcher getInstance() {
|
public static Dispatcher getInstance() {
|
||||||
return instance;
|
return instance;
|
||||||
|
@ -5,8 +5,7 @@ import java.util.List;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* AlchemistShop holds potions on its shelves.
|
* AlchemistShop holds potions on its shelves. It uses PotionFactory to provide the potions.
|
||||||
* It uses PotionFactory to provide the potions.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class AlchemistShop {
|
public class AlchemistShop {
|
||||||
|
@ -2,22 +2,23 @@ package com.iluwatar.flyweight;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Flyweight pattern is useful when the program needs a huge amount of objects.
|
* Flyweight pattern is useful when the program needs a huge amount of objects. It provides means to
|
||||||
* It provides means to decrease resource usage by sharing object instances.
|
* decrease resource usage by sharing object instances.
|
||||||
* <p>
|
* <p>
|
||||||
* In this example {@link AlchemistShop} has great amount of potions on its shelves.
|
* In this example {@link AlchemistShop} has great amount of potions on its shelves. To fill the
|
||||||
* To fill the shelves {@link AlchemistShop} uses {@link PotionFactory} (which represents
|
* shelves {@link AlchemistShop} uses {@link PotionFactory} (which represents the Flyweight in this
|
||||||
* the Flyweight in this example). Internally {@link PotionFactory} holds a map
|
* example). Internally {@link PotionFactory} holds a map of the potions and lazily creates new ones
|
||||||
* of the potions and lazily creates new ones when requested.
|
* when requested.
|
||||||
* <p>
|
* <p>
|
||||||
* To enable safe sharing, between clients and threads, Flyweight objects must
|
* To enable safe sharing, between clients and threads, Flyweight objects must be immutable.
|
||||||
* be immutable. Flyweight objects are by definition value objects.
|
* Flyweight objects are by definition value objects.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -9,8 +9,6 @@ public class HealingPotion implements Potion {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drink() {
|
public void drink() {
|
||||||
System.out.println("You feel healed. (Potion="
|
System.out.println("You feel healed. (Potion=" + System.identityHashCode(this) + ")");
|
||||||
+ System.identityHashCode(this) + ")");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,6 @@ public class HolyWaterPotion implements Potion {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drink() {
|
public void drink() {
|
||||||
System.out.println("You feel blessed. (Potion="
|
System.out.println("You feel blessed. (Potion=" + System.identityHashCode(this) + ")");
|
||||||
+ System.identityHashCode(this) + ")");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,6 @@ public class InvisibilityPotion implements Potion {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drink() {
|
public void drink() {
|
||||||
System.out.println("You become invisible. (Potion="
|
System.out.println("You become invisible. (Potion=" + System.identityHashCode(this) + ")");
|
||||||
+ System.identityHashCode(this) + ")");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,6 @@ public class PoisonPotion implements Potion {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drink() {
|
public void drink() {
|
||||||
System.out.println("Urgh! This is poisonous. (Potion="
|
System.out.println("Urgh! This is poisonous. (Potion=" + System.identityHashCode(this) + ")");
|
||||||
+ System.identityHashCode(this) + ")");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,9 @@ import java.util.Map;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* PotionFactory is the Flyweight in this example.
|
* PotionFactory is the Flyweight in this example. It minimizes memory use by sharing object
|
||||||
* It minimizes memory use by sharing object instances.
|
* instances. It holds a map of potion instances and new potions are created only when none of the
|
||||||
* It holds a map of potion instances and new potions
|
* type already exists.
|
||||||
* are created only when none of the type already exists.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class PotionFactory {
|
public class PotionFactory {
|
||||||
|
@ -9,7 +9,6 @@ public class StrengthPotion implements Potion {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drink() {
|
public void drink() {
|
||||||
System.out.println("You feel strong. (Potion="
|
System.out.println("You feel strong. (Potion=" + System.identityHashCode(this) + ")");
|
||||||
+ System.identityHashCode(this) + ")");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,63 +8,62 @@ import java.util.concurrent.LinkedBlockingQueue;
|
|||||||
* {@link AsyncTask} and {@link AsynchronousService}.
|
* {@link AsyncTask} and {@link AsynchronousService}.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* <i>PROBLEM</i>
|
* <i>PROBLEM</i> <br/>
|
||||||
* <br/>
|
* A concurrent system have a mixture of short duration, mid duration and long duration tasks. Mid
|
||||||
* A concurrent system have a mixture of short duration, mid duration and long duration tasks.
|
* or long duration tasks should be performed asynchronously to meet quality of service
|
||||||
* Mid or long duration tasks should be performed asynchronously to meet quality of service
|
|
||||||
* requirements.
|
* requirements.
|
||||||
*
|
*
|
||||||
* <p><i>INTENT</i>
|
* <p>
|
||||||
* <br/>
|
* <i>INTENT</i> <br/>
|
||||||
* The intent of this pattern is to separate the the synchronous and asynchronous processing
|
* The intent of this pattern is to separate the the synchronous and asynchronous processing in the
|
||||||
* in the concurrent application by introducing two intercommunicating layers - one for sync
|
* concurrent application by introducing two intercommunicating layers - one for sync and one for
|
||||||
* and one for async. This simplifies the programming without unduly affecting the performance.
|
* async. This simplifies the programming without unduly affecting the performance.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* <i>APPLICABILITY</i>
|
* <i>APPLICABILITY</i> <br/>
|
||||||
* <br/>
|
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>UNIX network subsystems - In operating systems network operations are carried out
|
* <li>UNIX network subsystems - In operating systems network operations are carried out
|
||||||
* asynchronously with help of hardware level interrupts.</li>
|
* asynchronously with help of hardware level interrupts.</li>
|
||||||
* <li>CORBA - At the asynchronous layer one thread is associated with each socket that is
|
* <li>CORBA - At the asynchronous layer one thread is associated with each socket that is connected
|
||||||
* connected to the client. Thread blocks waiting for CORBA requests from the client. On receiving
|
* to the client. Thread blocks waiting for CORBA requests from the client. On receiving request it
|
||||||
* request it is inserted in the queuing layer which is then picked up by synchronous layer which
|
* is inserted in the queuing layer which is then picked up by synchronous layer which processes the
|
||||||
* processes the request and sends response back to the client.</li>
|
* request and sends response back to the client.</li>
|
||||||
* <li>Android AsyncTask framework - Framework provides a way to execute long running blocking calls,
|
* <li>Android AsyncTask framework - Framework provides a way to execute long running blocking
|
||||||
* such as downloading a file, in background threads so that the UI thread remains free to respond
|
* calls, such as downloading a file, in background threads so that the UI thread remains free to
|
||||||
* to user inputs.</i>
|
* respond to user inputs.</i>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* <i>IMPLEMENTATION</i>
|
* <i>IMPLEMENTATION</i> <br/>
|
||||||
* <br/>
|
* The main method creates an asynchronous service which does not block the main thread while the
|
||||||
* The main method creates an asynchronous service which does not block the main thread while
|
* task is being performed. The main thread continues its work which is similar to Async Method
|
||||||
* the task is being performed. The main thread continues its work which is similar to Async Method
|
* Invocation pattern. The difference between them is that there is a queuing layer between
|
||||||
* Invocation pattern. The difference between them is that there is a queuing layer between Asynchronous
|
* Asynchronous layer and synchronous layer, which allows for different communication patterns
|
||||||
* layer and synchronous layer, which allows for different communication patterns between both layers.
|
* between both layers. Such as Priority Queue can be used as queuing layer to prioritize the way
|
||||||
* Such as Priority Queue can be used as queuing layer to prioritize the way tasks are executed.
|
* tasks are executed. Our implementation is just one simple way of implementing this pattern, there
|
||||||
* Our implementation is just one simple way of implementing this pattern, there are many variants possible
|
* are many variants possible as described in its applications.
|
||||||
* as described in its applications.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
AsynchronousService service = new AsynchronousService(new LinkedBlockingQueue<>());
|
AsynchronousService service = new AsynchronousService(new LinkedBlockingQueue<>());
|
||||||
/*
|
/*
|
||||||
* A new task to calculate sum is received but as this is main thread, it should not block.
|
* A new task to calculate sum is received but as this is main thread, it should not block. So
|
||||||
* So it passes it to the asynchronous task layer to compute and proceeds with handling other
|
* it passes it to the asynchronous task layer to compute and proceeds with handling other
|
||||||
* incoming requests. This is particularly useful when main thread is waiting on Socket to receive
|
* incoming requests. This is particularly useful when main thread is waiting on Socket to
|
||||||
* new incoming requests and does not wait for particular request to be completed before responding
|
* receive new incoming requests and does not wait for particular request to be completed before
|
||||||
* to new request.
|
* responding to new request.
|
||||||
*/
|
*/
|
||||||
service.execute(new ArithmeticSumTask(1000));
|
service.execute(new ArithmeticSumTask(1000));
|
||||||
|
|
||||||
/* New task received, lets pass that to async layer for computation. So both requests will be
|
/*
|
||||||
|
* New task received, lets pass that to async layer for computation. So both requests will be
|
||||||
* executed in parallel.
|
* executed in parallel.
|
||||||
*/
|
*/
|
||||||
service.execute(new ArithmeticSumTask(500));
|
service.execute(new ArithmeticSumTask(500));
|
||||||
@ -85,8 +84,8 @@ public class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the long running task that is performed in background. In our example
|
* This is the long running task that is performed in background. In our example the long
|
||||||
* the long running task is calculating arithmetic sum with artificial delay.
|
* running task is calculating arithmetic sum with artificial delay.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Long call() throws Exception {
|
public Long call() throws Exception {
|
||||||
@ -94,11 +93,10 @@ public class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This will be called in context of the main thread where some validations can be
|
* This will be called in context of the main thread where some validations can be done
|
||||||
* done regarding the inputs. Such as it must be greater than 0. It's a small
|
* regarding the inputs. Such as it must be greater than 0. It's a small computation which can
|
||||||
* computation which can be performed in main thread. If we did validated the input
|
* be performed in main thread. If we did validated the input in background thread then we pay
|
||||||
* in background thread then we pay the cost of context switching
|
* the cost of context switching which is much more than validating it in main thread.
|
||||||
* which is much more than validating it in main thread.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onPreCall() {
|
public void onPreCall() {
|
||||||
|
@ -3,41 +3,41 @@ package com.iluwatar.halfsynchalfasync;
|
|||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents some computation that is performed asynchronously and its result.
|
* Represents some computation that is performed asynchronously and its result. The computation is
|
||||||
* The computation is typically done is background threads and the result is posted
|
* typically done is background threads and the result is posted back in form of callback. The
|
||||||
* back in form of callback. The callback does not implement {@code isComplete}, {@code cancel}
|
* callback does not implement {@code isComplete}, {@code cancel} as it is out of scope of this
|
||||||
* as it is out of scope of this pattern.
|
* pattern.
|
||||||
*
|
*
|
||||||
* @param <O> type of result
|
* @param <O> type of result
|
||||||
*/
|
*/
|
||||||
public interface AsyncTask<O> extends Callable<O> {
|
public interface AsyncTask<O> extends Callable<O> {
|
||||||
/**
|
/**
|
||||||
* Is called in context of caller thread before call to {@link #call()}. Large
|
* Is called in context of caller thread before call to {@link #call()}. Large tasks should not be
|
||||||
* tasks should not be performed in this method as it will block the caller thread.
|
* performed in this method as it will block the caller thread. Small tasks such as validations
|
||||||
* Small tasks such as validations can be performed here so that the performance penalty
|
* can be performed here so that the performance penalty of context switching is not incurred in
|
||||||
* of context switching is not incurred in case of invalid requests.
|
* case of invalid requests.
|
||||||
*/
|
*/
|
||||||
void onPreCall();
|
void onPreCall();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback called after the result is successfully computed by {@link #call()}. In our
|
* A callback called after the result is successfully computed by {@link #call()}. In our
|
||||||
* implementation this method is called in context of background thread but in some variants,
|
* implementation this method is called in context of background thread but in some variants, such
|
||||||
* such as Android where only UI thread can change the state of UI widgets, this method is called
|
* as Android where only UI thread can change the state of UI widgets, this method is called in
|
||||||
* in context of UI thread.
|
* context of UI thread.
|
||||||
*/
|
*/
|
||||||
void onPostCall(O result);
|
void onPostCall(O result);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback called if computing the task resulted in some exception. This method
|
* A callback called if computing the task resulted in some exception. This method is called when
|
||||||
* is called when either of {@link #call()} or {@link #onPreCall()} throw any exception.
|
* either of {@link #call()} or {@link #onPreCall()} throw any exception.
|
||||||
*
|
*
|
||||||
* @param throwable error cause
|
* @param throwable error cause
|
||||||
*/
|
*/
|
||||||
void onError(Throwable throwable);
|
void onError(Throwable throwable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is where the computation of task should reside. This method is called in context
|
* This is where the computation of task should reside. This method is called in context of
|
||||||
* of background thread.
|
* background thread.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
O call() throws Exception;
|
O call() throws Exception;
|
||||||
|
@ -9,25 +9,25 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the asynchronous layer which does not block when a new request arrives. It just passes
|
* This is the asynchronous layer which does not block when a new request arrives. It just passes
|
||||||
* the request to the synchronous layer which consists of a queue i.e. a {@link BlockingQueue} and
|
* the request to the synchronous layer which consists of a queue i.e. a {@link BlockingQueue} and a
|
||||||
* a pool of threads i.e. {@link ThreadPoolExecutor}. Out of this pool of worker threads one of the
|
* pool of threads i.e. {@link ThreadPoolExecutor}. Out of this pool of worker threads one of the
|
||||||
* thread picks up the task and executes it synchronously in background and the result is posted back
|
* thread picks up the task and executes it synchronously in background and the result is posted
|
||||||
* to the caller via callback.
|
* back to the caller via callback.
|
||||||
*/
|
*/
|
||||||
public class AsynchronousService {
|
public class AsynchronousService {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This represents the queuing layer as well as synchronous layer of the pattern. The thread
|
* This represents the queuing layer as well as synchronous layer of the pattern. The thread pool
|
||||||
* pool contains worker threads which execute the tasks in blocking/synchronous manner. Long
|
* contains worker threads which execute the tasks in blocking/synchronous manner. Long running
|
||||||
* running tasks should be performed in the background which does not affect the performance of
|
* tasks should be performed in the background which does not affect the performance of main
|
||||||
* main thread.
|
* thread.
|
||||||
*/
|
*/
|
||||||
private ExecutorService service;
|
private ExecutorService service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an asynchronous service using {@code workQueue} as communication channel between
|
* Creates an asynchronous service using {@code workQueue} as communication channel between
|
||||||
* asynchronous layer and synchronous layer. Different types of queues such as Priority queue,
|
* asynchronous layer and synchronous layer. Different types of queues such as Priority queue, can
|
||||||
* can be used to control the pattern of communication between the layers.
|
* be used to control the pattern of communication between the layers.
|
||||||
*/
|
*/
|
||||||
public AsynchronousService(BlockingQueue<Runnable> workQueue) {
|
public AsynchronousService(BlockingQueue<Runnable> workQueue) {
|
||||||
service = new ThreadPoolExecutor(10, 10, 10, TimeUnit.SECONDS, workQueue);
|
service = new ThreadPoolExecutor(10, 10, 10, TimeUnit.SECONDS, workQueue);
|
||||||
@ -38,8 +38,8 @@ public class AsynchronousService {
|
|||||||
* A non-blocking method which performs the task provided in background and returns immediately.
|
* A non-blocking method which performs the task provided in background and returns immediately.
|
||||||
* <p>
|
* <p>
|
||||||
* On successful completion of task the result is posted back using callback method
|
* On successful completion of task the result is posted back using callback method
|
||||||
* {@link AsyncTask#onPostCall(Object)}, if task execution is unable to complete normally
|
* {@link AsyncTask#onPostCall(Object)}, if task execution is unable to complete normally due to
|
||||||
* due to some exception then the reason for error is posted back using callback method
|
* some exception then the reason for error is posted back using callback method
|
||||||
* {@link AsyncTask#onError(Throwable)}.
|
* {@link AsyncTask#onError(Throwable)}.
|
||||||
* <p>
|
* <p>
|
||||||
* NOTE: The results are posted back in the context of background thread in this implementation.
|
* NOTE: The results are posted back in the context of background thread in this implementation.
|
||||||
@ -57,11 +57,11 @@ public class AsynchronousService {
|
|||||||
protected void done() {
|
protected void done() {
|
||||||
super.done();
|
super.done();
|
||||||
try {
|
try {
|
||||||
/* called in context of background thread. There is other variant possible
|
/*
|
||||||
* where result is posted back and sits in the queue of caller thread which
|
* called in context of background thread. There is other variant possible where result is
|
||||||
* then picks it up for processing. An example of such a system is Android OS,
|
* posted back and sits in the queue of caller thread which then picks it up for
|
||||||
* where the UI elements can only be updated using UI thread. So result must be
|
* processing. An example of such a system is Android OS, where the UI elements can only
|
||||||
* posted back in UI thread.
|
* be updated using UI thread. So result must be posted back in UI thread.
|
||||||
*/
|
*/
|
||||||
task.onPostCall(get());
|
task.onPostCall(get());
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
package com.iluwatar.intercepting.filter;
|
package com.iluwatar.intercepting.filter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for order processing filters.
|
* Base class for order processing filters. Handles chain management.
|
||||||
* Handles chain management.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractFilter implements Filter {
|
public abstract class AbstractFilter implements Filter {
|
||||||
|
|
||||||
private Filter next;
|
private Filter next;
|
||||||
|
|
||||||
public AbstractFilter() {
|
public AbstractFilter() {}
|
||||||
}
|
|
||||||
|
|
||||||
public AbstractFilter(Filter next) {
|
public AbstractFilter(Filter next) {
|
||||||
this.next = next;
|
this.next = next;
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package com.iluwatar.intercepting.filter;
|
package com.iluwatar.intercepting.filter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concrete implementation of filter
|
* Concrete implementation of filter This filter is responsible for checking/filtering the input in
|
||||||
* This filter is responsible for checking/filtering the input in the address field.
|
* the address field.
|
||||||
|
*
|
||||||
* @author joshzambales
|
* @author joshzambales
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -2,32 +2,27 @@ package com.iluwatar.intercepting.filter;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* When a request enters a Web application, it often must pass several entrance
|
* When a request enters a Web application, it often must pass several entrance tests prior to the
|
||||||
* tests prior to the main processing stage. For example,
|
* main processing stage. For example, - Has the client been authenticated? - Does the client have a
|
||||||
* - Has the client been authenticated?
|
* valid session? - Is the client's IP address from a trusted network? - Does the request path
|
||||||
* - Does the client have a valid session?
|
* violate any constraints? - What encoding does the client use to send the data? - Do we support
|
||||||
* - Is the client's IP address from a trusted network?
|
* the browser type of the client? Some of these checks are tests, resulting in a yes or no answer
|
||||||
* - Does the request path violate any constraints?
|
* that determines whether processing will continue. Other checks manipulate the incoming data
|
||||||
* - What encoding does the client use to send the data?
|
|
||||||
* - Do we support the browser type of the client?
|
|
||||||
* Some of these checks are tests, resulting in a yes or no answer that determines
|
|
||||||
* whether processing will continue. Other checks manipulate the incoming data
|
|
||||||
* stream into a form suitable for processing.
|
* stream into a form suitable for processing.
|
||||||
* <p>
|
* <p>
|
||||||
* The classic solution consists of a series of conditional checks, with any failed
|
* The classic solution consists of a series of conditional checks, with any failed check aborting
|
||||||
* check aborting the request. Nested if/else statements are a standard strategy,
|
* the request. Nested if/else statements are a standard strategy, but this solution leads to code
|
||||||
* but this solution leads to code fragility and a copy-and-paste style of programming,
|
* fragility and a copy-and-paste style of programming, because the flow of the filtering and the
|
||||||
* because the flow of the filtering and the action of the filters is compiled into
|
* action of the filters is compiled into the application.
|
||||||
* the application.
|
|
||||||
* <p>
|
* <p>
|
||||||
* The key to solving this problem in a flexible and unobtrusive manner is to have a
|
* The key to solving this problem in a flexible and unobtrusive manner is to have a simple
|
||||||
* simple mechanism for adding and removing processing components, in which each
|
* mechanism for adding and removing processing components, in which each component completes a
|
||||||
* component completes a specific filtering action. This is the Intercepting Filter
|
* specific filtering action. This is the Intercepting Filter pattern in action.
|
||||||
* pattern in action.
|
|
||||||
* <p>
|
* <p>
|
||||||
* In this example we check whether the order request is valid through pre-processing
|
* In this example we check whether the order request is valid through pre-processing done via
|
||||||
* done via {@link Filter}. Each field has its own corresponding {@link Filter}
|
* {@link Filter}. Each field has its own corresponding {@link Filter}
|
||||||
* <p>
|
* <p>
|
||||||
|
*
|
||||||
* @author joshzambales
|
* @author joshzambales
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -35,6 +30,7 @@ public class App{
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -15,9 +15,11 @@ import javax.swing.JTextField;
|
|||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Client class is responsible for handling the input and running them through filters inside the {@link FilterManager}.
|
* The Client class is responsible for handling the input and running them through filters inside
|
||||||
|
* the {@link FilterManager}.
|
||||||
*
|
*
|
||||||
* This is where {@link Filter}s come to play as the client pre-processes the request before being displayed in the {@link Target}.
|
* This is where {@link Filter}s come to play as the client pre-processes the request before being
|
||||||
|
* displayed in the {@link Target}.
|
||||||
*
|
*
|
||||||
* @author joshzambales
|
* @author joshzambales
|
||||||
*
|
*
|
||||||
@ -85,8 +87,8 @@ public class Client extends JFrame {
|
|||||||
processButton.addActionListener(new ActionListener() {
|
processButton.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
Order order = new Order(jtFields[0].getText(), jtFields[1]
|
Order order =
|
||||||
.getText(), jtAreas[0].getText(),
|
new Order(jtFields[0].getText(), jtFields[1].getText(), jtAreas[0].getText(),
|
||||||
jtFields[2].getText(), jtAreas[1].getText());
|
jtFields[2].getText(), jtAreas[1].getText());
|
||||||
jl.setText(sendRequest(order));
|
jl.setText(sendRequest(order));
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package com.iluwatar.intercepting.filter;
|
package com.iluwatar.intercepting.filter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concrete implementation of filter
|
* Concrete implementation of filter This filter checks for the contact field in which it checks if
|
||||||
* This filter checks for the contact field in which it checks if the input consist of numbers
|
* the input consist of numbers and it also checks if the input follows the length constraint (11
|
||||||
* and it also checks if the input follows the length constraint (11 digits)
|
* digits)
|
||||||
|
*
|
||||||
* @author joshzambales
|
* @author joshzambales
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -12,8 +13,7 @@ public class ContactFilter extends AbstractFilter {
|
|||||||
@Override
|
@Override
|
||||||
public String execute(Order order) {
|
public String execute(Order order) {
|
||||||
String result = super.execute(order);
|
String result = super.execute(order);
|
||||||
if (order.getContactNumber() == null
|
if (order.getContactNumber() == null || order.getContactNumber().isEmpty()
|
||||||
|| order.getContactNumber().isEmpty()
|
|
||||||
|| order.getContactNumber().matches(".*[^\\d]+.*")
|
|| order.getContactNumber().matches(".*[^\\d]+.*")
|
||||||
|| order.getContactNumber().length() != 11) {
|
|| order.getContactNumber().length() != 11) {
|
||||||
return result + "Invalid contact number! ";
|
return result + "Invalid contact number! ";
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package com.iluwatar.intercepting.filter;
|
package com.iluwatar.intercepting.filter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concrete implementation of filter
|
* Concrete implementation of filter This checks for the deposit code
|
||||||
* This checks for the deposit code
|
*
|
||||||
* @author joshzambales
|
* @author joshzambales
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package com.iluwatar.intercepting.filter;
|
package com.iluwatar.intercepting.filter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters perform certain tasks prior or after execution of
|
* Filters perform certain tasks prior or after execution of request by request handler. In this
|
||||||
* request by request handler. In this case, before the request is handled by
|
* case, before the request is handled by the target, the request undergoes through each Filter
|
||||||
* the target, the request undergoes through each Filter
|
|
||||||
*
|
*
|
||||||
* @author joshzambales
|
* @author joshzambales
|
||||||
*
|
*
|
||||||
@ -12,6 +11,7 @@ public interface Filter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute order processing filter.
|
* Execute order processing filter.
|
||||||
|
*
|
||||||
* @param order
|
* @param order
|
||||||
* @return empty string on success, otherwise error message.
|
* @return empty string on success, otherwise error message.
|
||||||
*/
|
*/
|
||||||
@ -19,18 +19,21 @@ public interface Filter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set next filter in chain after this.
|
* Set next filter in chain after this.
|
||||||
|
*
|
||||||
* @param filter
|
* @param filter
|
||||||
*/
|
*/
|
||||||
void setNext(Filter filter);
|
void setNext(Filter filter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get next filter in chain after this.
|
* Get next filter in chain after this.
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Filter getNext();
|
Filter getNext();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get last filter in the chain.
|
* Get last filter in the chain.
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Filter getLast();
|
Filter getLast();
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package com.iluwatar.intercepting.filter;
|
package com.iluwatar.intercepting.filter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concrete implementation of filter. This filter checks if the input in the Name
|
* Concrete implementation of filter. This filter checks if the input in the Name field is valid.
|
||||||
* field is valid. (alphanumeric)
|
* (alphanumeric)
|
||||||
*
|
*
|
||||||
* @author joshzambales
|
* @author joshzambales
|
||||||
*
|
*
|
||||||
@ -12,7 +12,8 @@ public class NameFilter extends AbstractFilter {
|
|||||||
@Override
|
@Override
|
||||||
public String execute(Order order) {
|
public String execute(Order order) {
|
||||||
String result = super.execute(order);
|
String result = super.execute(order);
|
||||||
if (order.getName() == null || order.getName().isEmpty() || order.getName().matches(".*[^\\w|\\s]+.*")) {
|
if (order.getName() == null || order.getName().isEmpty()
|
||||||
|
|| order.getName().matches(".*[^\\w|\\s]+.*")) {
|
||||||
return result + "Invalid order! ";
|
return result + "Invalid order! ";
|
||||||
} else {
|
} else {
|
||||||
return result;
|
return result;
|
||||||
|
@ -12,8 +12,7 @@ public class Order {
|
|||||||
private String depositNumber;
|
private String depositNumber;
|
||||||
private String order;
|
private String order;
|
||||||
|
|
||||||
public Order() {
|
public Order() {}
|
||||||
}
|
|
||||||
|
|
||||||
public Order(String name, String contactNumber, String address, String depositNumber, String order) {
|
public Order(String name, String contactNumber, String address, String depositNumber, String order) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -33,8 +33,9 @@ public class Target extends JFrame {
|
|||||||
super("Order System");
|
super("Order System");
|
||||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||||
setSize(640, 480);
|
setSize(640, 480);
|
||||||
dtm = new DefaultTableModel(new Object[] { "Name", "Contact Number",
|
dtm =
|
||||||
"Address", "Deposit Number", "Order" }, 0);
|
new DefaultTableModel(new Object[] {"Name", "Contact Number", "Address", "Deposit Number",
|
||||||
|
"Order"}, 0);
|
||||||
jt = new JTable(dtm);
|
jt = new JTable(dtm);
|
||||||
del = new JButton("Delete");
|
del = new JButton("Delete");
|
||||||
setup();
|
setup();
|
||||||
@ -59,8 +60,7 @@ public class Target extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void execute(String[] request) {
|
public void execute(String[] request) {
|
||||||
dtm.addRow(new Object[] { request[0], request[1], request[2],
|
dtm.addRow(new Object[] {request[0], request[1], request[2], request[3], request[4]});
|
||||||
request[3], request[4] });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DListener implements ActionListener {
|
class DListener implements ActionListener {
|
||||||
|
@ -4,14 +4,13 @@ import java.util.Stack;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* The Interpreter pattern is a design pattern that specifies how to evaluate sentences
|
* The Interpreter pattern is a design pattern that specifies how to evaluate sentences in a
|
||||||
* in a language. The basic idea is to have a class for each symbol (terminal or nonterminal)
|
* language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a
|
||||||
* in a specialized computer language. The syntax tree of a sentence in the language is an
|
* specialized computer language. The syntax tree of a sentence in the language is an instance of
|
||||||
* instance of the composite pattern and is used to evaluate (interpret) the sentence for a
|
* the composite pattern and is used to evaluate (interpret) the sentence for a client.
|
||||||
* client.
|
|
||||||
* <p>
|
* <p>
|
||||||
* In this example we use the Interpreter pattern to break sentences into expressions
|
* In this example we use the Interpreter pattern to break sentences into expressions (
|
||||||
* ({@link Expression}) that can be evaluated and as a whole form the result.
|
* {@link Expression}) that can be evaluated and as a whole form the result.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
@ -20,8 +19,8 @@ public class App {
|
|||||||
*
|
*
|
||||||
* Program entry point.
|
* Program entry point.
|
||||||
* <p>
|
* <p>
|
||||||
* Expressions can be evaluated using prefix, infix or postfix notations
|
* Expressions can be evaluated using prefix, infix or postfix notations This sample uses postfix,
|
||||||
* This sample uses postfix, where operator comes after the operands
|
* where operator comes after the operands
|
||||||
*
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*
|
*
|
||||||
@ -35,36 +34,28 @@ public class App {
|
|||||||
if (isOperator(s)) {
|
if (isOperator(s)) {
|
||||||
Expression rightExpression = stack.pop();
|
Expression rightExpression = stack.pop();
|
||||||
Expression leftExpression = stack.pop();
|
Expression leftExpression = stack.pop();
|
||||||
System.out
|
System.out.println(String.format("popped from stack left: %d right: %d",
|
||||||
.println(String.format(
|
leftExpression.interpret(), rightExpression.interpret()));
|
||||||
"popped from stack left: %d right: %d",
|
Expression operator = getOperatorInstance(s, leftExpression, rightExpression);
|
||||||
leftExpression.interpret(),
|
|
||||||
rightExpression.interpret()));
|
|
||||||
Expression operator = getOperatorInstance(s, leftExpression,
|
|
||||||
rightExpression);
|
|
||||||
System.out.println(String.format("operator: %s", operator));
|
System.out.println(String.format("operator: %s", operator));
|
||||||
int result = operator.interpret();
|
int result = operator.interpret();
|
||||||
NumberExpression resultExpression = new NumberExpression(result);
|
NumberExpression resultExpression = new NumberExpression(result);
|
||||||
stack.push(resultExpression);
|
stack.push(resultExpression);
|
||||||
System.out.println(String.format("push result to stack: %d",
|
System.out.println(String.format("push result to stack: %d", resultExpression.interpret()));
|
||||||
resultExpression.interpret()));
|
|
||||||
} else {
|
} else {
|
||||||
Expression i = new NumberExpression(s);
|
Expression i = new NumberExpression(s);
|
||||||
stack.push(i);
|
stack.push(i);
|
||||||
System.out.println(String.format("push to stack: %d",
|
System.out.println(String.format("push to stack: %d", i.interpret()));
|
||||||
i.interpret()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out
|
System.out.println(String.format("result: %d", stack.pop().interpret()));
|
||||||
.println(String.format("result: %d", stack.pop().interpret()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isOperator(String s) {
|
public static boolean isOperator(String s) {
|
||||||
return s.equals("+") || s.equals("-") || s.equals("*");
|
return s.equals("+") || s.equals("-") || s.equals("*");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Expression getOperatorInstance(String s, Expression left,
|
public static Expression getOperatorInstance(String s, Expression left, Expression right) {
|
||||||
Expression right) {
|
|
||||||
switch (s) {
|
switch (s) {
|
||||||
case "+":
|
case "+":
|
||||||
return new PlusExpression(left, right);
|
return new PlusExpression(left, right);
|
||||||
|
@ -10,8 +10,7 @@ public class MultiplyExpression extends Expression {
|
|||||||
private Expression leftExpression;
|
private Expression leftExpression;
|
||||||
private Expression rightExpression;
|
private Expression rightExpression;
|
||||||
|
|
||||||
public MultiplyExpression(Expression leftExpression,
|
public MultiplyExpression(Expression leftExpression, Expression rightExpression) {
|
||||||
Expression rightExpression) {
|
|
||||||
this.leftExpression = leftExpression;
|
this.leftExpression = leftExpression;
|
||||||
this.rightExpression = rightExpression;
|
this.rightExpression = rightExpression;
|
||||||
}
|
}
|
||||||
|
@ -26,5 +26,4 @@ public class NumberExpression extends Expression {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "number";
|
return "number";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,5 +24,4 @@ public class PlusExpression extends Expression {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "+";
|
return "+";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,19 +2,19 @@ package com.iluwatar.iterator;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* The Iterator pattern is a design pattern in which an iterator is used to
|
* The Iterator pattern is a design pattern in which an iterator is used to traverse a container and
|
||||||
* traverse a container and access the container's elements. The Iterator pattern
|
* access the container's elements. The Iterator pattern decouples algorithms from containers.
|
||||||
* decouples algorithms from containers.
|
|
||||||
* <p>
|
* <p>
|
||||||
* In this example the Iterator ({@link ItemIterator}) adds abstraction layer on
|
* In this example the Iterator ({@link ItemIterator}) adds abstraction layer on top of a collection
|
||||||
* top of a collection ({@link TreasureChest}). This way the collection can change
|
* ({@link TreasureChest}). This way the collection can change its internal implementation without
|
||||||
* its internal implementation without affecting its clients.
|
* affecting its clients.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -44,8 +44,7 @@ public class TreasureChestItemIterator implements ItemIterator {
|
|||||||
tempIdx = -1;
|
tempIdx = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (type.equals(ItemType.ANY)
|
if (type.equals(ItemType.ANY) || items.get(tempIdx).getType().equals(type)) {
|
||||||
|| items.get(tempIdx).getType().equals(type)) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,32 +4,31 @@ import java.util.Arrays;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Layers is an architectural style where software responsibilities are
|
* Layers is an architectural style where software responsibilities are divided among the different
|
||||||
* divided among the different layers of the application.
|
* layers of the application.
|
||||||
* <p>
|
* <p>
|
||||||
* This example demonstrates a traditional 3-layer architecture consisting of data access
|
* This example demonstrates a traditional 3-layer architecture consisting of data access layer,
|
||||||
* layer, business layer and presentation layer.
|
* business layer and presentation layer.
|
||||||
* <p>
|
* <p>
|
||||||
* The data access layer is formed of Spring Data repositories <code>CakeDao</code>, <code>CakeToppingDao</code> and
|
* The data access layer is formed of Spring Data repositories <code>CakeDao</code>,
|
||||||
* <code>CakeLayerDao</code>. The repositories can be used for CRUD operations on cakes, cake toppings
|
* <code>CakeToppingDao</code> and <code>CakeLayerDao</code>. The repositories can be used for CRUD
|
||||||
* and cake layers respectively.
|
* operations on cakes, cake toppings and cake layers respectively.
|
||||||
* <p>
|
* <p>
|
||||||
* The business layer is built on top of the data access layer. <code>CakeBakingService</code> offers
|
* The business layer is built on top of the data access layer. <code>CakeBakingService</code>
|
||||||
* methods to retrieve available cake toppings and cake layers and baked cakes. Also the
|
* offers methods to retrieve available cake toppings and cake layers and baked cakes. Also the
|
||||||
* service is used to create new cakes out of cake toppings and cake layers.
|
* service is used to create new cakes out of cake toppings and cake layers.
|
||||||
* <p>
|
* <p>
|
||||||
* The presentation layer is built on the business layer and in this example it simply lists
|
* The presentation layer is built on the business layer and in this example it simply lists the
|
||||||
* the cakes that have been baked.
|
* cakes that have been baked.
|
||||||
* <p>
|
* <p>
|
||||||
* We have applied so called strict layering which means that the layers can only access
|
* We have applied so called strict layering which means that the layers can only access the classes
|
||||||
* the classes directly beneath them. This leads the solution to create an additional set of
|
* directly beneath them. This leads the solution to create an additional set of DTOs (
|
||||||
* DTOs (<code>CakeInfo</code>, <code>CakeToppingInfo</code>, <code>CakeLayerInfo</code>)
|
* <code>CakeInfo</code>, <code>CakeToppingInfo</code>, <code>CakeLayerInfo</code>) to translate
|
||||||
* to translate data between layers. In other words, <code>CakeBakingService</code> cannot
|
* data between layers. In other words, <code>CakeBakingService</code> cannot return entities (
|
||||||
* return entities (<code>Cake</code>, <code>CakeTopping</code>, <code>CakeLayer</code>)
|
* <code>Cake</code>, <code>CakeTopping</code>, <code>CakeLayer</code>) directly since these reside
|
||||||
* directly since these reside on data access layer but instead translates these into business
|
* on data access layer but instead translates these into business layer DTOs (<code>CakeInfo</code>, <code>CakeToppingInfo</code>, <code>CakeLayerInfo</code>) and returns them instead. This way
|
||||||
* layer DTOs (<code>CakeInfo</code>, <code>CakeToppingInfo</code>, <code>CakeLayerInfo</code>)
|
* the presentation layer does not have any knowledge of other layers than the business layer and
|
||||||
* and returns them instead. This way the presentation layer does not have any knowledge of
|
* thus is not affected by changes to them.
|
||||||
* other layers than the business layer and thus is not affected by changes to them.
|
|
||||||
*
|
*
|
||||||
* @see Cake
|
* @see Cake
|
||||||
* @see CakeTopping
|
* @see CakeTopping
|
||||||
@ -49,6 +48,7 @@ public class App {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Application entry point
|
* Application entry point
|
||||||
|
*
|
||||||
* @param args Command line parameters
|
* @param args Command line parameters
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
@ -63,6 +63,7 @@ public class App {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the example data
|
* Initializes the example data
|
||||||
|
*
|
||||||
* @param cakeBakingService
|
* @param cakeBakingService
|
||||||
*/
|
*/
|
||||||
private static void initializeData(CakeBakingService cakeBakingService) {
|
private static void initializeData(CakeBakingService cakeBakingService) {
|
||||||
@ -76,17 +77,18 @@ public class App {
|
|||||||
cakeBakingService.saveNewTopping(new CakeToppingInfo("candies", 350));
|
cakeBakingService.saveNewTopping(new CakeToppingInfo("candies", 350));
|
||||||
cakeBakingService.saveNewTopping(new CakeToppingInfo("cherry", 350));
|
cakeBakingService.saveNewTopping(new CakeToppingInfo("cherry", 350));
|
||||||
|
|
||||||
CakeInfo cake1 = new CakeInfo(new CakeToppingInfo("candies", 0),
|
CakeInfo cake1 =
|
||||||
Arrays.asList(new CakeLayerInfo("chocolate", 0), new CakeLayerInfo("banana", 0),
|
new CakeInfo(new CakeToppingInfo("candies", 0), Arrays.asList(new CakeLayerInfo(
|
||||||
new CakeLayerInfo("strawberry", 0)));
|
"chocolate", 0), new CakeLayerInfo("banana", 0), new CakeLayerInfo("strawberry", 0)));
|
||||||
try {
|
try {
|
||||||
cakeBakingService.bakeNewCake(cake1);
|
cakeBakingService.bakeNewCake(cake1);
|
||||||
} catch (CakeBakingException e) {
|
} catch (CakeBakingException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
CakeInfo cake2 = new CakeInfo(new CakeToppingInfo("cherry", 0),
|
CakeInfo cake2 =
|
||||||
Arrays.asList(new CakeLayerInfo("vanilla", 0), new CakeLayerInfo("lemon", 0),
|
new CakeInfo(new CakeToppingInfo("cherry", 0), Arrays.asList(
|
||||||
new CakeLayerInfo("strawberry", 0)));
|
new CakeLayerInfo("vanilla", 0), new CakeLayerInfo("lemon", 0), new CakeLayerInfo(
|
||||||
|
"strawberry", 0)));
|
||||||
try {
|
try {
|
||||||
cakeBakingService.bakeNewCake(cake2);
|
cakeBakingService.bakeNewCake(cake2);
|
||||||
} catch (CakeBakingException e) {
|
} catch (CakeBakingException e) {
|
||||||
|
@ -9,8 +9,7 @@ public class CakeBakingException extends Exception {
|
|||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public CakeBakingException() {
|
public CakeBakingException() {}
|
||||||
}
|
|
||||||
|
|
||||||
public CakeBakingException(String message) {
|
public CakeBakingException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
@ -11,6 +11,7 @@ public interface CakeBakingService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Bakes new cake according to parameters
|
* Bakes new cake according to parameters
|
||||||
|
*
|
||||||
* @param cakeInfo
|
* @param cakeInfo
|
||||||
* @throws CakeBakingException
|
* @throws CakeBakingException
|
||||||
*/
|
*/
|
||||||
@ -18,30 +19,35 @@ public interface CakeBakingService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all cakes
|
* Get all cakes
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<CakeInfo> getAllCakes();
|
List<CakeInfo> getAllCakes();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store new cake topping
|
* Store new cake topping
|
||||||
|
*
|
||||||
* @param toppingInfo
|
* @param toppingInfo
|
||||||
*/
|
*/
|
||||||
void saveNewTopping(CakeToppingInfo toppingInfo);
|
void saveNewTopping(CakeToppingInfo toppingInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get available cake toppings
|
* Get available cake toppings
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<CakeToppingInfo> getAvailableToppings();
|
List<CakeToppingInfo> getAvailableToppings();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add new cake layer
|
* Add new cake layer
|
||||||
|
*
|
||||||
* @param layerInfo
|
* @param layerInfo
|
||||||
*/
|
*/
|
||||||
void saveNewLayer(CakeLayerInfo layerInfo);
|
void saveNewLayer(CakeLayerInfo layerInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get available cake layers
|
* Get available cake layers
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<CakeLayerInfo> getAvailableLayers();
|
List<CakeLayerInfo> getAvailableLayers();
|
||||||
|
@ -31,15 +31,18 @@ public class CakeBakingServiceImpl implements CakeBakingService {
|
|||||||
@Override
|
@Override
|
||||||
public void bakeNewCake(CakeInfo cakeInfo) throws CakeBakingException {
|
public void bakeNewCake(CakeInfo cakeInfo) throws CakeBakingException {
|
||||||
List<CakeToppingInfo> allToppings = getAvailableToppings();
|
List<CakeToppingInfo> allToppings = getAvailableToppings();
|
||||||
List<CakeToppingInfo> matchingToppings = allToppings.stream()
|
List<CakeToppingInfo> matchingToppings =
|
||||||
.filter((t) -> t.name.equals(cakeInfo.cakeToppingInfo.name)).collect(Collectors.toList());
|
allToppings.stream().filter((t) -> t.name.equals(cakeInfo.cakeToppingInfo.name))
|
||||||
|
.collect(Collectors.toList());
|
||||||
if (matchingToppings.isEmpty()) {
|
if (matchingToppings.isEmpty()) {
|
||||||
throw new CakeBakingException(String.format("Topping %s is not available", cakeInfo.cakeToppingInfo.name));
|
throw new CakeBakingException(String.format("Topping %s is not available",
|
||||||
|
cakeInfo.cakeToppingInfo.name));
|
||||||
}
|
}
|
||||||
List<CakeLayer> allLayers = getAvailableLayerEntities();
|
List<CakeLayer> allLayers = getAvailableLayerEntities();
|
||||||
Set<CakeLayer> foundLayers = new HashSet<>();
|
Set<CakeLayer> foundLayers = new HashSet<>();
|
||||||
for (CakeLayerInfo info : cakeInfo.cakeLayerInfos) {
|
for (CakeLayerInfo info : cakeInfo.cakeLayerInfos) {
|
||||||
Optional<CakeLayer> found = allLayers.stream().filter((layer) -> layer.getName().equals(info.name)).findFirst();
|
Optional<CakeLayer> found =
|
||||||
|
allLayers.stream().filter((layer) -> layer.getName().equals(info.name)).findFirst();
|
||||||
if (!found.isPresent()) {
|
if (!found.isPresent()) {
|
||||||
throw new CakeBakingException(String.format("Layer %s is not available", info.name));
|
throw new CakeBakingException(String.format("Layer %s is not available", info.name));
|
||||||
} else {
|
} else {
|
||||||
@ -135,8 +138,9 @@ public class CakeBakingServiceImpl implements CakeBakingService {
|
|||||||
Iterator<Cake> iterator = cakeBean.findAll().iterator();
|
Iterator<Cake> iterator = cakeBean.findAll().iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
Cake cake = iterator.next();
|
Cake cake = iterator.next();
|
||||||
CakeToppingInfo cakeToppingInfo = new CakeToppingInfo(cake.getTopping().getId(),
|
CakeToppingInfo cakeToppingInfo =
|
||||||
cake.getTopping().getName(), cake.getTopping().getCalories());
|
new CakeToppingInfo(cake.getTopping().getId(), cake.getTopping().getName(), cake
|
||||||
|
.getTopping().getCalories());
|
||||||
ArrayList<CakeLayerInfo> cakeLayerInfos = new ArrayList<CakeLayerInfo>();
|
ArrayList<CakeLayerInfo> cakeLayerInfos = new ArrayList<CakeLayerInfo>();
|
||||||
for (CakeLayer layer : cake.getLayers()) {
|
for (CakeLayer layer : cake.getLayers()) {
|
||||||
cakeLayerInfos.add(new CakeLayerInfo(layer.getId(), layer.getName(), layer.getCalories()));
|
cakeLayerInfos.add(new CakeLayerInfo(layer.getId(), layer.getName(), layer.getCalories()));
|
||||||
|
@ -34,7 +34,7 @@ public class CakeInfo {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("CakeInfo id=%d topping=%s layers=%s totalCalories=%d", id.get(), cakeToppingInfo,
|
return String.format("CakeInfo id=%d topping=%s layers=%s totalCalories=%d", id.get(),
|
||||||
cakeLayerInfos, calculateTotalCalories());
|
cakeToppingInfo, cakeLayerInfos, calculateTotalCalories());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,7 @@ public class CakeLayer {
|
|||||||
@ManyToOne(cascade = CascadeType.ALL)
|
@ManyToOne(cascade = CascadeType.ALL)
|
||||||
private Cake cake;
|
private Cake cake;
|
||||||
|
|
||||||
public CakeLayer() {
|
public CakeLayer() {}
|
||||||
}
|
|
||||||
|
|
||||||
public CakeLayer(String name, int calories) {
|
public CakeLayer(String name, int calories) {
|
||||||
this.setName(name);
|
this.setName(name);
|
||||||
|
@ -25,8 +25,7 @@ public class CakeTopping {
|
|||||||
@OneToOne(cascade = CascadeType.ALL)
|
@OneToOne(cascade = CascadeType.ALL)
|
||||||
private Cake cake;
|
private Cake cake;
|
||||||
|
|
||||||
public CakeTopping() {
|
public CakeTopping() {}
|
||||||
}
|
|
||||||
|
|
||||||
public CakeTopping(String name, int calories) {
|
public CakeTopping(String name, int calories) {
|
||||||
this.setName(name);
|
this.setName(name);
|
||||||
|
@ -4,17 +4,16 @@ package com.iluwatar.lazy.loading;
|
|||||||
*
|
*
|
||||||
* Lazy loading idiom defers object creation until needed.
|
* Lazy loading idiom defers object creation until needed.
|
||||||
* <p>
|
* <p>
|
||||||
* This example shows different implementations of the pattern
|
* This example shows different implementations of the pattern with increasing sophistication.
|
||||||
* with increasing sophistication.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Additional information and lazy loading flavours are described in
|
* Additional information and lazy loading flavours are described in
|
||||||
* http://martinfowler.com/eaaCatalog/lazyLoad.html
|
* http://martinfowler.com/eaaCatalog/lazyLoad.html
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App
|
public class App {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -2,8 +2,7 @@ package com.iluwatar.lazy.loading;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Simple implementation of the lazy loading idiom.
|
* Simple implementation of the lazy loading idiom. However, this is not thread safe.
|
||||||
* However, this is not thread safe.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class HolderNaive {
|
public class HolderNaive {
|
||||||
|
@ -2,9 +2,8 @@ package com.iluwatar.lazy.loading;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Same as HolderNaive but with added synchronization.
|
* Same as HolderNaive but with added synchronization. This implementation is thread safe, but each
|
||||||
* This implementation is thread safe, but each {@link #getHeavy()}
|
* {@link #getHeavy()} call costs additional synchronization overhead.
|
||||||
* call costs additional synchronization overhead.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class HolderThreadSafe {
|
public class HolderThreadSafe {
|
||||||
|
@ -4,8 +4,8 @@ import java.util.function.Supplier;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* This lazy loader is thread safe and more efficient than {@link HolderThreadSafe}.
|
* This lazy loader is thread safe and more efficient than {@link HolderThreadSafe}. It utilizes
|
||||||
* It utilizes Java 8 functional interface {@link Supplier<T>} as {@link Heavy} factory.
|
* Java 8 functional interface {@link Supplier<T>} as {@link Heavy} factory.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Java8Holder {
|
public class Java8Holder {
|
||||||
@ -23,8 +23,11 @@ public class Java8Holder {
|
|||||||
private synchronized Heavy createAndCacheHeavy() {
|
private synchronized Heavy createAndCacheHeavy() {
|
||||||
class HeavyFactory implements Supplier<Heavy> {
|
class HeavyFactory implements Supplier<Heavy> {
|
||||||
private final Heavy heavyInstance = new Heavy();
|
private final Heavy heavyInstance = new Heavy();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Heavy get() { return heavyInstance; }
|
public Heavy get() {
|
||||||
|
return heavyInstance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!HeavyFactory.class.isInstance(heavy)) {
|
if (!HeavyFactory.class.isInstance(heavy)) {
|
||||||
heavy = new HeavyFactory();
|
heavy = new HeavyFactory();
|
||||||
|
@ -8,7 +8,8 @@ import static org.junit.Assert.assertNotNull;
|
|||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Using reflection this test shows that the heavy field is not instantiated until the method getHeavy is called
|
* Using reflection this test shows that the heavy field is not instantiated until the method
|
||||||
|
* getHeavy is called
|
||||||
*
|
*
|
||||||
* Created by jones on 11/10/2015.
|
* Created by jones on 11/10/2015.
|
||||||
*/
|
*/
|
||||||
@ -18,7 +19,8 @@ public class HolderThreadSafeTest {
|
|||||||
public void test() throws IllegalAccessException {
|
public void test() throws IllegalAccessException {
|
||||||
HolderThreadSafe hts = new HolderThreadSafe();
|
HolderThreadSafe hts = new HolderThreadSafe();
|
||||||
|
|
||||||
{//first call is null
|
{
|
||||||
|
// first call is null
|
||||||
Field[] ff = HolderThreadSafe.class.getDeclaredFields();
|
Field[] ff = HolderThreadSafe.class.getDeclaredFields();
|
||||||
for (Field f : ff) {
|
for (Field f : ff) {
|
||||||
f.setAccessible(true);
|
f.setAccessible(true);
|
||||||
@ -30,7 +32,8 @@ public class HolderThreadSafeTest {
|
|||||||
// now it is lazily loaded
|
// now it is lazily loaded
|
||||||
hts.getHeavy();
|
hts.getHeavy();
|
||||||
|
|
||||||
{//now it is not null - call via reflection so that the test is the same before and after
|
{
|
||||||
|
// now it is not null - call via reflection so that the test is the same before and after
|
||||||
Field[] ff = HolderThreadSafe.class.getDeclaredFields();
|
Field[] ff = HolderThreadSafe.class.getDeclaredFields();
|
||||||
for (Field f : ff) {
|
for (Field f : ff) {
|
||||||
f.setAccessible(true);
|
f.setAccessible(true);
|
||||||
|
@ -7,11 +7,9 @@ package com.iluwatar.mediator;
|
|||||||
*/
|
*/
|
||||||
public enum Action {
|
public enum Action {
|
||||||
|
|
||||||
HUNT("hunted a rabbit", "arrives for dinner"),
|
HUNT("hunted a rabbit", "arrives for dinner"), TALE("tells a tale", "comes to listen"), GOLD(
|
||||||
TALE("tells a tale", "comes to listen"),
|
"found gold", "takes his share of the gold"), ENEMY("spotted enemies", "runs for cover"), NONE(
|
||||||
GOLD("found gold", "takes his share of the gold"),
|
"", "");
|
||||||
ENEMY("spotted enemies", "runs for cover"),
|
|
||||||
NONE("", "");
|
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
private String description;
|
private String description;
|
||||||
|
@ -2,32 +2,31 @@ package com.iluwatar.mediator;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* The Mediator pattern defines an object that encapsulates how a set of objects
|
* The Mediator pattern defines an object that encapsulates how a set of objects interact. This
|
||||||
* interact. This pattern is considered to be a behavioral pattern due to the way
|
* pattern is considered to be a behavioral pattern due to the way it can alter the program's
|
||||||
* it can alter the program's running behavior.
|
* running behavior.
|
||||||
* <p>
|
* <p>
|
||||||
* Usually a program is made up of a large number of classes. So the logic and
|
* Usually a program is made up of a large number of classes. So the logic and computation is
|
||||||
* computation is distributed among these classes. However, as more classes are
|
* distributed among these classes. However, as more classes are developed in a program, especially
|
||||||
* developed in a program, especially during maintenance and/or refactoring,
|
* during maintenance and/or refactoring, the problem of communication between these classes may
|
||||||
* the problem of communication between these classes may become more complex.
|
* become more complex. This makes the program harder to read and maintain. Furthermore, it can
|
||||||
* This makes the program harder to read and maintain. Furthermore, it can become
|
* become difficult to change the program, since any change may affect code in several other
|
||||||
* difficult to change the program, since any change may affect code in several
|
* classes.
|
||||||
* other classes.
|
|
||||||
* <p>
|
* <p>
|
||||||
* With the Mediator pattern, communication between objects is encapsulated with
|
* With the Mediator pattern, communication between objects is encapsulated with a mediator object.
|
||||||
* a mediator object. Objects no longer communicate directly with each other, but
|
* Objects no longer communicate directly with each other, but instead communicate through the
|
||||||
* instead communicate through the mediator. This reduces the dependencies between
|
* mediator. This reduces the dependencies between communicating objects, thereby lowering the
|
||||||
* communicating objects, thereby lowering the coupling.
|
* coupling.
|
||||||
* <p>
|
* <p>
|
||||||
* In this example the mediator encapsulates how a set of objects ({@link PartyMember})
|
* In this example the mediator encapsulates how a set of objects ({@link PartyMember}) interact.
|
||||||
* interact. Instead of referring to each other directly they use the mediator
|
* Instead of referring to each other directly they use the mediator ({@link Party}) interface.
|
||||||
* ({@link Party}) interface.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -11,5 +11,4 @@ public class Hunter extends PartyMemberBase {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "Hunter";
|
return "Hunter";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,22 +4,21 @@ import java.util.Stack;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* The Memento pattern is a software design pattern that provides the ability to restore
|
* The Memento pattern is a software design pattern that provides the ability to restore an object
|
||||||
* an object to its previous state (undo via rollback).
|
* to its previous state (undo via rollback).
|
||||||
* <p>
|
* <p>
|
||||||
* The Memento pattern is implemented with three objects: the originator, a caretaker and
|
* The Memento pattern is implemented with three objects: the originator, a caretaker and a memento.
|
||||||
* a memento. The originator is some object that has an internal state. The caretaker is
|
* The originator is some object that has an internal state. The caretaker is going to do something
|
||||||
* going to do something to the originator, but wants to be able to undo the change. The
|
* to the originator, but wants to be able to undo the change. The caretaker first asks the
|
||||||
* caretaker first asks the originator for a memento object. Then it does whatever operation
|
* originator for a memento object. Then it does whatever operation (or sequence of operations) it
|
||||||
* (or sequence of operations) it was going to do. To roll back to the state before the
|
* was going to do. To roll back to the state before the operations, it returns the memento object
|
||||||
* operations, it returns the memento object to the originator. The memento object itself
|
* to the originator. The memento object itself is an opaque object (one which the caretaker cannot,
|
||||||
* is an opaque object (one which the caretaker cannot, or should not, change). When using
|
* or should not, change). When using this pattern, care should be taken if the originator may
|
||||||
* this pattern, care should be taken if the originator may change other objects or
|
* change other objects or resources - the memento pattern operates on a single object.
|
||||||
* resources - the memento pattern operates on a single object.
|
|
||||||
* <p>
|
* <p>
|
||||||
* In this example the object ({@link Star})
|
* In this example the object ({@link Star}) gives out a "memento" ({@link StarMemento}) that
|
||||||
* gives out a "memento" ({@link StarMemento}) that contains the state of the object.
|
* contains the state of the object. Later on the memento can be set back to the object restoring
|
||||||
* Later on the memento can be set back to the object restoring the state.
|
* the state.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
@ -63,8 +63,7 @@ public class Star {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("%s age: %d years mass: %d tons", type.toString(),
|
return String.format("%s age: %d years mass: %d tons", type.toString(), ageYears, massTons);
|
||||||
ageYears, massTons);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,7 +7,8 @@ package com.iluwatar.memento;
|
|||||||
*/
|
*/
|
||||||
public enum StarType {
|
public enum StarType {
|
||||||
|
|
||||||
SUN("sun"), RED_GIANT("red giant"), WHITE_DWARF("white dwarf"), SUPERNOVA("supernova"), DEAD("dead star"), UNDEFINED("");
|
SUN("sun"), RED_GIANT("red giant"), WHITE_DWARF("white dwarf"), SUPERNOVA("supernova"), DEAD(
|
||||||
|
"dead star"), UNDEFINED("");
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
|
@ -6,31 +6,31 @@ import org.apache.camel.impl.DefaultCamelContext;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* When two applications communicate with each other using a messaging system
|
* When two applications communicate with each other using a messaging system they first need to
|
||||||
* they first need to establish a communication channel that will carry the
|
* establish a communication channel that will carry the data. Message Channel decouples Message
|
||||||
* data. Message Channel decouples Message producers and consumers.
|
* producers and consumers.
|
||||||
* <p>
|
* <p>
|
||||||
* The sending application doesn't necessarily know what particular application
|
* The sending application doesn't necessarily know what particular application will end up
|
||||||
* will end up retrieving it, but it can be assured that the application that
|
* retrieving it, but it can be assured that the application that retrieves the information is
|
||||||
* retrieves the information is interested in that information. This is because
|
* interested in that information. This is because the messaging system has different Message
|
||||||
* the messaging system has different Message Channels for different types of
|
* Channels for different types of information the applications want to communicate. When an
|
||||||
* information the applications want to communicate. When an application sends
|
* application sends information, it doesn't randomly add the information to any channel available;
|
||||||
* information, it doesn't randomly add the information to any channel available;
|
* it adds it to a channel whose specific purpose is to communicate that sort of information.
|
||||||
* it adds it to a channel whose specific purpose is to communicate that sort of
|
* Likewise, an application that wants to receive particular information doesn't pull info off some
|
||||||
* information. Likewise, an application that wants to receive particular information
|
* random channel; it selects what channel to get information from based on what type of information
|
||||||
* doesn't pull info off some random channel; it selects what channel to get information
|
* it wants.
|
||||||
* from based on what type of information it wants.
|
|
||||||
* <p>
|
* <p>
|
||||||
* In this example we use Apache Camel to establish two different Message Channels. The first
|
* In this example we use Apache Camel to establish two different Message Channels. The first one
|
||||||
* one reads from standard input and delivers messages to Direct endpoint. The second Message
|
* reads from standard input and delivers messages to Direct endpoint. The second Message Channel is
|
||||||
* Channel is established from the Direct component to console output. No actual messages are sent,
|
* established from the Direct component to console output. No actual messages are sent, only the
|
||||||
* only the established routes are printed to standard output.
|
* established routes are printed to standard output.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
|
@ -5,20 +5,23 @@ package com.iluwatar.model.view.controller;
|
|||||||
* Model-View-Controller is a pattern for implementing user interfaces. It divides the application
|
* Model-View-Controller is a pattern for implementing user interfaces. It divides the application
|
||||||
* into three interconnected parts namely the model, the view and the controller.
|
* into three interconnected parts namely the model, the view and the controller.
|
||||||
* <p>
|
* <p>
|
||||||
* The central component of MVC, the model, captures the behavior of the application in terms of its problem
|
* The central component of MVC, the model, captures the behavior of the application in terms of its
|
||||||
* domain, independent of the user interface. The model directly manages the data, logic and rules of the
|
* problem domain, independent of the user interface. The model directly manages the data, logic and
|
||||||
* application. A view can be any output representation of information, such as a chart or a diagram
|
* rules of the application. A view can be any output representation of information, such as a chart
|
||||||
* The third part, the controller, accepts input and converts it to commands for the model or view.
|
* or a diagram The third part, the controller, accepts input and converts it to commands for the
|
||||||
|
* model or view.
|
||||||
* <p>
|
* <p>
|
||||||
* In this example we have a giant ({@link GiantModel}) with statuses for health, fatigue and nourishment. {@link GiantView}
|
* In this example we have a giant ({@link GiantModel}) with statuses for health, fatigue and
|
||||||
* can display the giant with its current status. {@link GiantController} receives input affecting the model and
|
* nourishment. {@link GiantView} can display the giant with its current status.
|
||||||
* delegates redrawing the giant to the view.
|
* {@link GiantController} receives input affecting the model and delegates redrawing the giant to
|
||||||
|
* the view.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -2,23 +2,24 @@ package com.iluwatar.model.view.presenter;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* The Model-View-Presenter(MVP) architectural pattern, helps us achieve what is
|
* The Model-View-Presenter(MVP) architectural pattern, helps us achieve what is called
|
||||||
* called "The separation of concerns" principle. This is accomplished
|
* "The separation of concerns" principle. This is accomplished by separating the application's
|
||||||
* by separating the application's logic (Model), GUIs (View), and finally
|
* logic (Model), GUIs (View), and finally the way that the user's actions update the application's
|
||||||
* the way that the user's actions update the application's logic (Presenter).
|
* logic (Presenter).
|
||||||
* <p>
|
* <p>
|
||||||
* In the following example, The {@link FileLoader} class represents the app's logic,
|
* In the following example, The {@link FileLoader} class represents the app's logic, the
|
||||||
* the {@link FileSelectorJFrame} is the GUI and the {@link FileSelectorPresenter} is
|
* {@link FileSelectorJFrame} is the GUI and the {@link FileSelectorPresenter} is responsible to
|
||||||
* responsible to respond to users' actions.
|
* respond to users' actions.
|
||||||
* <p>
|
* <p>
|
||||||
* Finally, please notice the wiring between the Presenter and the View
|
* Finally, please notice the wiring between the Presenter and the View and between the Presenter
|
||||||
* and between the Presenter and the Model.
|
* and the Model.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -5,8 +5,8 @@ import java.io.File;
|
|||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every instance of this class represents the Model component in the
|
* Every instance of this class represents the Model component in the Model-View-Presenter
|
||||||
* Model-View-Presenter architectural pattern.
|
* architectural pattern.
|
||||||
* <p>
|
* <p>
|
||||||
* It is responsible for reading and loading the contents of a given file.
|
* It is responsible for reading and loading the contents of a given file.
|
||||||
*/
|
*/
|
||||||
@ -27,8 +27,7 @@ public class FileLoader {
|
|||||||
*/
|
*/
|
||||||
public String loadData() {
|
public String loadData() {
|
||||||
try {
|
try {
|
||||||
BufferedReader br = new BufferedReader(new FileReader(new File(
|
BufferedReader br = new BufferedReader(new FileReader(new File(this.fileName)));
|
||||||
this.fileName)));
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
String line;
|
String line;
|
||||||
|
|
||||||
@ -51,6 +50,7 @@ public class FileLoader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the path of the file to be loaded, to the given value.
|
* Sets the path of the file to be loaded, to the given value.
|
||||||
|
*
|
||||||
* @param fileName The path of the file to be loaded.
|
* @param fileName The path of the file to be loaded.
|
||||||
*/
|
*/
|
||||||
public void setFileName(String fileName) {
|
public void setFileName(String fileName) {
|
||||||
|
@ -14,11 +14,9 @@ import javax.swing.JTextArea;
|
|||||||
import javax.swing.JTextField;
|
import javax.swing.JTextField;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is the GUI implementation of the View component in the
|
* This class is the GUI implementation of the View component in the Model-View-Presenter pattern.
|
||||||
* Model-View-Presenter pattern.
|
|
||||||
*/
|
*/
|
||||||
public class FileSelectorJFrame extends JFrame implements FileSelectorView,
|
public class FileSelectorJFrame extends JFrame implements FileSelectorView, ActionListener {
|
||||||
ActionListener {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default serial version ID.
|
* Default serial version ID.
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package com.iluwatar.model.view.presenter;
|
package com.iluwatar.model.view.presenter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every instance of this class represents the Presenter component in the
|
* Every instance of this class represents the Presenter component in the Model-View-Presenter
|
||||||
* Model-View-Presenter architectural pattern.
|
* architectural pattern.
|
||||||
* <p>
|
* <p>
|
||||||
* It is responsible for reacting to the user's actions and update the View
|
* It is responsible for reacting to the user's actions and update the View component.
|
||||||
* component.
|
|
||||||
*/
|
*/
|
||||||
public class FileSelectorPresenter {
|
public class FileSelectorPresenter {
|
||||||
|
|
||||||
@ -21,6 +20,7 @@ public class FileSelectorPresenter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
*
|
||||||
* @param view The view component that the presenter will interact with.
|
* @param view The view component that the presenter will interact with.
|
||||||
*/
|
*/
|
||||||
public FileSelectorPresenter(FileSelectorView view) {
|
public FileSelectorPresenter(FileSelectorView view) {
|
||||||
@ -29,6 +29,7 @@ public class FileSelectorPresenter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link FileLoader} object, to the value given as parameter.
|
* Sets the {@link FileLoader} object, to the value given as parameter.
|
||||||
|
*
|
||||||
* @param loader The new {@link FileLoader} object(the Model component).
|
* @param loader The new {@link FileLoader} object(the Model component).
|
||||||
*/
|
*/
|
||||||
public void setLoader(FileLoader loader) {
|
public void setLoader(FileLoader loader) {
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
package com.iluwatar.model.view.presenter;
|
package com.iluwatar.model.view.presenter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every instance of this class represents the Stub component in the
|
* Every instance of this class represents the Stub component in the Model-View-Presenter
|
||||||
* Model-View-Presenter architectural pattern.
|
* architectural pattern.
|
||||||
* <p>
|
* <p>
|
||||||
* The stub implements the View interface and it is useful when we want the test
|
* The stub implements the View interface and it is useful when we want the test the reaction to
|
||||||
* the reaction to user events, such as mouse clicks.
|
* user events, such as mouse clicks.
|
||||||
* <p>
|
* <p>
|
||||||
* Since we can not test the GUI directly, the MVP pattern provides this
|
* Since we can not test the GUI directly, the MVP pattern provides this functionality through the
|
||||||
* functionality through the View's dummy implementation, the Stub.
|
* View's dummy implementation, the Stub.
|
||||||
*/
|
*/
|
||||||
public class FileSelectorStub implements FileSelectorView {
|
public class FileSelectorStub implements FileSelectorView {
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package com.iluwatar.model.view.presenter;
|
package com.iluwatar.model.view.presenter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface represents the View component in the Model-View-Presenter
|
* This interface represents the View component in the Model-View-Presenter pattern. It can be
|
||||||
* pattern. It can be implemented by either the GUI components, or by the Stub.
|
* implemented by either the GUI components, or by the Stub.
|
||||||
*/
|
*/
|
||||||
public interface FileSelectorView {
|
public interface FileSelectorView {
|
||||||
|
|
||||||
@ -23,6 +23,7 @@ public interface FileSelectorView {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the presenter component, to the one given as parameter.
|
* Sets the presenter component, to the one given as parameter.
|
||||||
|
*
|
||||||
* @param presenter The new presenter component.
|
* @param presenter The new presenter component.
|
||||||
*/
|
*/
|
||||||
public void setPresenter(FileSelectorPresenter presenter);
|
public void setPresenter(FileSelectorPresenter presenter);
|
||||||
@ -34,6 +35,7 @@ public interface FileSelectorView {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the file's name, to the value given as parameter.
|
* Sets the file's name, to the value given as parameter.
|
||||||
|
*
|
||||||
* @param name The new name of the file.
|
* @param name The new name of the file.
|
||||||
*/
|
*/
|
||||||
public void setFileName(String name);
|
public void setFileName(String name);
|
||||||
@ -45,12 +47,14 @@ public interface FileSelectorView {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays a message to the users.
|
* Displays a message to the users.
|
||||||
|
*
|
||||||
* @param message The message to be displayed.
|
* @param message The message to be displayed.
|
||||||
*/
|
*/
|
||||||
public void showMessage(String message);
|
public void showMessage(String message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays the data to the view.
|
* Displays the data to the view.
|
||||||
|
*
|
||||||
* @param data The data to be written.
|
* @param data The data to be written.
|
||||||
*/
|
*/
|
||||||
public void displayData(String data);
|
public void displayData(String data);
|
||||||
|
@ -10,8 +10,8 @@ import com.iluwatar.model.view.presenter.FileSelectorPresenter;
|
|||||||
import com.iluwatar.model.view.presenter.FileSelectorStub;
|
import com.iluwatar.model.view.presenter.FileSelectorStub;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test case is responsible for testing our application by taking advantage
|
* This test case is responsible for testing our application by taking advantage of the
|
||||||
* of the Model-View-Controller architectural pattern.
|
* Model-View-Controller architectural pattern.
|
||||||
*/
|
*/
|
||||||
public class FileSelectorPresenterTest {
|
public class FileSelectorPresenterTest {
|
||||||
|
|
||||||
@ -67,8 +67,8 @@ public class FileSelectorPresenterTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if we receive a confirmation when we attempt to open a file that
|
* Tests if we receive a confirmation when we attempt to open a file that it's name is null or an
|
||||||
* it's name is null or an empty string.
|
* empty string.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void fileConfirmationWhenNameIsNull() {
|
public void fileConfirmationWhenNameIsNull() {
|
||||||
@ -83,8 +83,7 @@ public class FileSelectorPresenterTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if we receive a confirmation when we attempt to open a file that it
|
* Tests if we receive a confirmation when we attempt to open a file that it doesn't exist.
|
||||||
* doesn't exist.
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void fileConfirmationWhenFileDoesNotExist() {
|
public void fileConfirmationWhenFileDoesNotExist() {
|
||||||
|
@ -2,8 +2,8 @@ package com.iluwatar.monostate;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* The Server class. Each Server sits behind a LoadBalancer which delegates the call to the
|
* The Server class. Each Server sits behind a LoadBalancer which delegates the call to the servers
|
||||||
* servers in a simplistic Round Robin fashion.
|
* in a simplistic Round Robin fashion.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Server {
|
public class Server {
|
||||||
@ -26,6 +26,7 @@ public class Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final void serve(Request request) {
|
public final void serve(Request request) {
|
||||||
System.out.println("Server ID " + id + " associated to host : " + getHost() + " and Port " + getPort() +" Processed request with value " + request.value);
|
System.out.println("Server ID " + id + " associated to host : " + getHost() + " and Port "
|
||||||
|
+ getPort() + " Processed request with value " + request.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,20 +2,20 @@ package com.iluwatar.multiton;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Whereas Singleton design pattern introduces single globally
|
* Whereas Singleton design pattern introduces single globally accessible object the Multiton
|
||||||
* accessible object the Multiton pattern defines many globally
|
* pattern defines many globally accessible objects. The client asks for the correct instance from
|
||||||
* accessible objects. The client asks for the correct instance
|
* the Multiton by passing an enumeration as parameter.
|
||||||
* from the Multiton by passing an enumeration as parameter.
|
|
||||||
* <p>
|
* <p>
|
||||||
* In this example {@link Nazgul} is the Multiton and we can ask single
|
* In this example {@link Nazgul} is the Multiton and we can ask single {@link Nazgul} from it using
|
||||||
* {@link Nazgul} from it using {@link NazgulName}. The {@link Nazgul}s are statically
|
* {@link NazgulName}. The {@link Nazgul}s are statically initialized and stored in concurrent hash
|
||||||
* initialized and stored in concurrent hash map.
|
* map.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -5,8 +5,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Nazgul is a Multiton class. Nazgul instances can be queried
|
* Nazgul is a Multiton class. Nazgul instances can be queried using {@link #getInstance} method.
|
||||||
* using {@link #getInstance} method.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Nazgul {
|
public class Nazgul {
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* distributed with this work for additional information
|
* copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* to you under the Apache License, Version 2.0 (the
|
* copy of the License at
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing,
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* software distributed under the License is distributed on an
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* KIND, either express or implied. See the License for the
|
* the License.
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
*/
|
||||||
package domainapp.dom.app.homepage;
|
package domainapp.dom.app.homepage;
|
||||||
|
|
||||||
@ -25,16 +21,14 @@ import org.apache.isis.applib.annotation.HomePage;
|
|||||||
import org.apache.isis.applib.annotation.NatureOfService;
|
import org.apache.isis.applib.annotation.NatureOfService;
|
||||||
import org.apache.isis.applib.annotation.SemanticsOf;
|
import org.apache.isis.applib.annotation.SemanticsOf;
|
||||||
|
|
||||||
@DomainService(
|
@DomainService(nature = NatureOfService.VIEW_CONTRIBUTIONS_ONLY // trick to suppress the actions
|
||||||
nature = NatureOfService.VIEW_CONTRIBUTIONS_ONLY // trick to suppress the actions from the top-level menu
|
// from the top-level menu
|
||||||
)
|
)
|
||||||
public class HomePageService {
|
public class HomePageService {
|
||||||
|
|
||||||
// region > homePage (action)
|
// region > homePage (action)
|
||||||
|
|
||||||
@Action(
|
@Action(semantics = SemanticsOf.SAFE)
|
||||||
semantics = SemanticsOf.SAFE
|
|
||||||
)
|
|
||||||
@HomePage
|
@HomePage
|
||||||
public HomePageViewModel homePage() {
|
public HomePageViewModel homePage() {
|
||||||
return container.injectServicesInto(new HomePageViewModel());
|
return container.injectServicesInto(new HomePageViewModel());
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* distributed with this work for additional information
|
* copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* to you under the Apache License, Version 2.0 (the
|
* copy of the License at
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing,
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* software distributed under the License is distributed on an
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* KIND, either express or implied. See the License for the
|
* the License.
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
*/
|
||||||
package domainapp.dom.app.homepage;
|
package domainapp.dom.app.homepage;
|
||||||
|
|
||||||
@ -32,6 +28,7 @@ public class HomePageViewModel {
|
|||||||
public String title() {
|
public String title() {
|
||||||
return getObjects().size() + " objects";
|
return getObjects().size() + " objects";
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region > object (collection)
|
// region > object (collection)
|
||||||
@ -39,6 +36,7 @@ public class HomePageViewModel {
|
|||||||
public List<SimpleObject> getObjects() {
|
public List<SimpleObject> getObjects() {
|
||||||
return simpleObjects.listAll();
|
return simpleObjects.listAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region > injected services
|
// region > injected services
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* distributed with this work for additional information
|
* copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* to you under the Apache License, Version 2.0 (the
|
* copy of the License at
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing,
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* software distributed under the License is distributed on an
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* KIND, either express or implied. See the License for the
|
* the License.
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
*/
|
||||||
package domainapp.dom.modules.simple;
|
package domainapp.dom.modules.simple;
|
||||||
|
|
||||||
@ -37,34 +33,19 @@ import org.apache.isis.applib.services.eventbus.ActionDomainEvent;
|
|||||||
import org.apache.isis.applib.services.i18n.TranslatableString;
|
import org.apache.isis.applib.services.i18n.TranslatableString;
|
||||||
import org.apache.isis.applib.util.ObjectContracts;
|
import org.apache.isis.applib.util.ObjectContracts;
|
||||||
|
|
||||||
@javax.jdo.annotations.PersistenceCapable(
|
@javax.jdo.annotations.PersistenceCapable(identityType = IdentityType.DATASTORE, schema = "simple",
|
||||||
identityType=IdentityType.DATASTORE,
|
table = "SimpleObject")
|
||||||
schema = "simple",
|
|
||||||
table = "SimpleObject"
|
|
||||||
)
|
|
||||||
@javax.jdo.annotations.DatastoreIdentity(
|
@javax.jdo.annotations.DatastoreIdentity(
|
||||||
strategy=javax.jdo.annotations.IdGeneratorStrategy.IDENTITY,
|
strategy = javax.jdo.annotations.IdGeneratorStrategy.IDENTITY, column = "id")
|
||||||
column="id")
|
@javax.jdo.annotations.Version(strategy = VersionStrategy.VERSION_NUMBER, column = "version")
|
||||||
@javax.jdo.annotations.Version(
|
|
||||||
strategy=VersionStrategy.VERSION_NUMBER,
|
|
||||||
column="version")
|
|
||||||
@javax.jdo.annotations.Queries({
|
@javax.jdo.annotations.Queries({
|
||||||
@javax.jdo.annotations.Query(
|
@javax.jdo.annotations.Query(name = "find", language = "JDOQL", value = "SELECT "
|
||||||
name = "find", language = "JDOQL",
|
|
||||||
value = "SELECT "
|
|
||||||
+ "FROM domainapp.dom.modules.simple.SimpleObject "),
|
+ "FROM domainapp.dom.modules.simple.SimpleObject "),
|
||||||
@javax.jdo.annotations.Query(
|
@javax.jdo.annotations.Query(name = "findByName", language = "JDOQL", value = "SELECT "
|
||||||
name = "findByName", language = "JDOQL",
|
+ "FROM domainapp.dom.modules.simple.SimpleObject " + "WHERE name.indexOf(:name) >= 0 ")})
|
||||||
value = "SELECT "
|
|
||||||
+ "FROM domainapp.dom.modules.simple.SimpleObject "
|
|
||||||
+ "WHERE name.indexOf(:name) >= 0 ")
|
|
||||||
})
|
|
||||||
@javax.jdo.annotations.Unique(name = "SimpleObject_name_UNQ", members = {"name"})
|
@javax.jdo.annotations.Unique(name = "SimpleObject_name_UNQ", members = {"name"})
|
||||||
@DomainObject
|
@DomainObject
|
||||||
@DomainObjectLayout(
|
@DomainObjectLayout(bookmarking = BookmarkPolicy.AS_ROOT, cssClassFa = "fa-flag")
|
||||||
bookmarking = BookmarkPolicy.AS_ROOT,
|
|
||||||
cssClassFa = "fa-flag"
|
|
||||||
)
|
|
||||||
public class SimpleObject implements Comparable<SimpleObject> {
|
public class SimpleObject implements Comparable<SimpleObject> {
|
||||||
|
|
||||||
|
|
||||||
@ -72,6 +53,7 @@ public class SimpleObject implements Comparable<SimpleObject> {
|
|||||||
public TranslatableString title() {
|
public TranslatableString title() {
|
||||||
return TranslatableString.tr("Object: {name}", "name", getName());
|
return TranslatableString.tr("Object: {name}", "name", getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region > name (property)
|
// region > name (property)
|
||||||
@ -80,9 +62,7 @@ public class SimpleObject implements Comparable<SimpleObject> {
|
|||||||
|
|
||||||
@javax.jdo.annotations.Column(allowsNull = "false", length = 40)
|
@javax.jdo.annotations.Column(allowsNull = "false", length = 40)
|
||||||
@Title(sequence = "1")
|
@Title(sequence = "1")
|
||||||
@Property(
|
@Property(editing = Editing.DISABLED)
|
||||||
editing = Editing.DISABLED
|
|
||||||
)
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@ -96,18 +76,15 @@ public class SimpleObject implements Comparable<SimpleObject> {
|
|||||||
// region > updateName (action)
|
// region > updateName (action)
|
||||||
|
|
||||||
public static class UpdateNameDomainEvent extends ActionDomainEvent<SimpleObject> {
|
public static class UpdateNameDomainEvent extends ActionDomainEvent<SimpleObject> {
|
||||||
public UpdateNameDomainEvent(final SimpleObject source, final Identifier identifier, final Object... arguments) {
|
public UpdateNameDomainEvent(final SimpleObject source, final Identifier identifier,
|
||||||
|
final Object... arguments) {
|
||||||
super(source, identifier, arguments);
|
super(source, identifier, arguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Action(
|
@Action(domainEvent = UpdateNameDomainEvent.class)
|
||||||
domainEvent = UpdateNameDomainEvent.class
|
|
||||||
)
|
|
||||||
public SimpleObject updateName(
|
public SimpleObject updateName(
|
||||||
@Parameter(maxLength = 40)
|
@Parameter(maxLength = 40) @ParameterLayout(named = "New name") final String name) {
|
||||||
@ParameterLayout(named = "New name")
|
|
||||||
final String name) {
|
|
||||||
setName(name);
|
setName(name);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -126,6 +103,7 @@ public class SimpleObject implements Comparable<SimpleObject> {
|
|||||||
public Long getVersionSequence() {
|
public Long getVersionSequence() {
|
||||||
return (Long) JDOHelper.getVersion(this);
|
return (Long) JDOHelper.getVersion(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region > compareTo
|
// region > compareTo
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* distributed with this work for additional information
|
* copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* to you under the Apache License, Version 2.0 (the
|
* copy of the License at
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing,
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* software distributed under the License is distributed on an
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* KIND, either express or implied. See the License for the
|
* the License.
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
*/
|
||||||
package domainapp.dom.modules.simple;
|
package domainapp.dom.modules.simple;
|
||||||
|
|
||||||
@ -42,54 +38,40 @@ public class SimpleObjects {
|
|||||||
public TranslatableString title() {
|
public TranslatableString title() {
|
||||||
return TranslatableString.tr("Simple Objects");
|
return TranslatableString.tr("Simple Objects");
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region > listAll (action)
|
// region > listAll (action)
|
||||||
@Action(
|
@Action(semantics = SemanticsOf.SAFE)
|
||||||
semantics = SemanticsOf.SAFE
|
@ActionLayout(bookmarking = BookmarkPolicy.AS_ROOT)
|
||||||
)
|
|
||||||
@ActionLayout(
|
|
||||||
bookmarking = BookmarkPolicy.AS_ROOT
|
|
||||||
)
|
|
||||||
@MemberOrder(sequence = "1")
|
@MemberOrder(sequence = "1")
|
||||||
public List<SimpleObject> listAll() {
|
public List<SimpleObject> listAll() {
|
||||||
return container.allInstances(SimpleObject.class);
|
return container.allInstances(SimpleObject.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region > findByName (action)
|
// region > findByName (action)
|
||||||
@Action(
|
@Action(semantics = SemanticsOf.SAFE)
|
||||||
semantics = SemanticsOf.SAFE
|
@ActionLayout(bookmarking = BookmarkPolicy.AS_ROOT)
|
||||||
)
|
|
||||||
@ActionLayout(
|
|
||||||
bookmarking = BookmarkPolicy.AS_ROOT
|
|
||||||
)
|
|
||||||
@MemberOrder(sequence = "2")
|
@MemberOrder(sequence = "2")
|
||||||
public List<SimpleObject> findByName(
|
public List<SimpleObject> findByName(@ParameterLayout(named = "Name") final String name) {
|
||||||
@ParameterLayout(named="Name")
|
return container.allMatches(new QueryDefault<>(SimpleObject.class, "findByName", "name", name));
|
||||||
final String name
|
|
||||||
) {
|
|
||||||
return container.allMatches(
|
|
||||||
new QueryDefault<>(
|
|
||||||
SimpleObject.class,
|
|
||||||
"findByName",
|
|
||||||
"name", name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region > create (action)
|
// region > create (action)
|
||||||
public static class CreateDomainEvent extends ActionDomainEvent<SimpleObjects> {
|
public static class CreateDomainEvent extends ActionDomainEvent<SimpleObjects> {
|
||||||
public CreateDomainEvent(final SimpleObjects source, final Identifier identifier, final Object... arguments) {
|
public CreateDomainEvent(final SimpleObjects source, final Identifier identifier,
|
||||||
|
final Object... arguments) {
|
||||||
super(source, identifier, arguments);
|
super(source, identifier, arguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Action(
|
@Action(domainEvent = CreateDomainEvent.class)
|
||||||
domainEvent = CreateDomainEvent.class
|
|
||||||
)
|
|
||||||
@MemberOrder(sequence = "3")
|
@MemberOrder(sequence = "3")
|
||||||
public SimpleObject create(
|
public SimpleObject create(final @ParameterLayout(named = "Name") String name) {
|
||||||
final @ParameterLayout(named="Name") String name) {
|
|
||||||
final SimpleObject obj = container.newTransientInstance(SimpleObject.class);
|
final SimpleObject obj = container.newTransientInstance(SimpleObject.class);
|
||||||
obj.setName(name);
|
obj.setName(name);
|
||||||
container.persistIfNotAlready(obj);
|
container.persistIfNotAlready(obj);
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* this work for additional information regarding copyright ownership.
|
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* (the "License"); you may not use this file except in compliance with
|
* copy of the License at
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* See the License for the specific language governing permissions and
|
* the License.
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package domainapp.dom.modules.simple;
|
package domainapp.dom.modules.simple;
|
||||||
|
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* this work for additional information regarding copyright ownership.
|
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* (the "License"); you may not use this file except in compliance with
|
* copy of the License at
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* See the License for the specific language governing permissions and
|
* the License.
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package domainapp.dom.modules.simple;
|
package domainapp.dom.modules.simple;
|
||||||
|
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* distributed with this work for additional information
|
* copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* to you under the Apache License, Version 2.0 (the
|
* copy of the License at
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing,
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* software distributed under the License is distributed on an
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* KIND, either express or implied. See the License for the
|
* the License.
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
*/
|
||||||
package domainapp.fixture;
|
package domainapp.fixture;
|
||||||
|
|
||||||
@ -33,12 +29,10 @@ import domainapp.fixture.scenarios.RecreateSimpleObjects;
|
|||||||
public class DomainAppFixturesProvider implements FixtureScriptsSpecificationProvider {
|
public class DomainAppFixturesProvider implements FixtureScriptsSpecificationProvider {
|
||||||
@Override
|
@Override
|
||||||
public FixtureScriptsSpecification getSpecification() {
|
public FixtureScriptsSpecification getSpecification() {
|
||||||
return FixtureScriptsSpecification
|
return FixtureScriptsSpecification.builder(DomainAppFixturesProvider.class)
|
||||||
.builder(DomainAppFixturesProvider.class)
|
|
||||||
.with(FixtureScripts.MultipleExecutionStrategy.EXECUTE)
|
.with(FixtureScripts.MultipleExecutionStrategy.EXECUTE)
|
||||||
.withRunScriptDefault(RecreateSimpleObjects.class)
|
.withRunScriptDefault(RecreateSimpleObjects.class)
|
||||||
.withRunScriptDropDown(FixtureScriptsSpecification.DropDownPolicy.CHOICES)
|
.withRunScriptDropDown(FixtureScriptsSpecification.DropDownPolicy.CHOICES)
|
||||||
.withRecreate(RecreateSimpleObjects.class)
|
.withRecreate(RecreateSimpleObjects.class).build();
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* distributed with this work for additional information
|
* copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* to you under the Apache License, Version 2.0 (the
|
* copy of the License at
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing,
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* software distributed under the License is distributed on an
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* KIND, either express or implied. See the License for the
|
* the License.
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package domainapp.fixture.modules.simple;
|
package domainapp.fixture.modules.simple;
|
||||||
@ -28,6 +24,7 @@ public class SimpleObjectCreate extends FixtureScript {
|
|||||||
|
|
||||||
// region > name (input)
|
// region > name (input)
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of the object (required)
|
* Name of the object (required)
|
||||||
*/
|
*/
|
||||||
@ -39,6 +36,7 @@ public class SimpleObjectCreate extends FixtureScript {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
|
||||||
@ -47,11 +45,13 @@ public class SimpleObjectCreate extends FixtureScript {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The created simple object (output).
|
* The created simple object (output).
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public SimpleObject getSimpleObject() {
|
public SimpleObject getSimpleObject() {
|
||||||
return simpleObject;
|
return simpleObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* distributed with this work for additional information
|
* copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* to you under the Apache License, Version 2.0 (the
|
* copy of the License at
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing,
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* software distributed under the License is distributed on an
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* KIND, either express or implied. See the License for the
|
* the License.
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package domainapp.fixture.modules.simple;
|
package domainapp.fixture.modules.simple;
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* distributed with this work for additional information
|
* copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* to you under the Apache License, Version 2.0 (the
|
* copy of the License at
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing,
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* software distributed under the License is distributed on an
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* KIND, either express or implied. See the License for the
|
* the License.
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package domainapp.fixture.scenarios;
|
package domainapp.fixture.scenarios;
|
||||||
@ -33,8 +29,8 @@ import domainapp.fixture.modules.simple.SimpleObjectsTearDown;
|
|||||||
|
|
||||||
public class RecreateSimpleObjects extends FixtureScript {
|
public class RecreateSimpleObjects extends FixtureScript {
|
||||||
|
|
||||||
public final List<String> NAMES = Collections.unmodifiableList(Arrays.asList(
|
public final List<String> NAMES = Collections.unmodifiableList(Arrays.asList("Foo", "Bar", "Baz",
|
||||||
"Foo", "Bar", "Baz", "Frodo", "Froyo", "Fizz", "Bip", "Bop", "Bang", "Boo"));
|
"Frodo", "Froyo", "Fizz", "Bip", "Bop", "Bang", "Boo"));
|
||||||
|
|
||||||
public RecreateSimpleObjects() {
|
public RecreateSimpleObjects() {
|
||||||
withDiscoverability(Discoverability.DISCOVERABLE);
|
withDiscoverability(Discoverability.DISCOVERABLE);
|
||||||
@ -54,6 +50,7 @@ public class RecreateSimpleObjects extends FixtureScript {
|
|||||||
this.number = number;
|
this.number = number;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region > simpleObjects (output)
|
// region > simpleObjects (output)
|
||||||
@ -65,6 +62,7 @@ public class RecreateSimpleObjects extends FixtureScript {
|
|||||||
public List<SimpleObject> getSimpleObjects() {
|
public List<SimpleObject> getSimpleObjects() {
|
||||||
return simpleObjects;
|
return simpleObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -75,7 +73,8 @@ public class RecreateSimpleObjects extends FixtureScript {
|
|||||||
|
|
||||||
// validate
|
// validate
|
||||||
if (number < 0 || number > NAMES.size()) {
|
if (number < 0 || number > NAMES.size()) {
|
||||||
throw new IllegalArgumentException(String.format("number must be in range [0,%d)", NAMES.size()));
|
throw new IllegalArgumentException(String.format("number must be in range [0,%d)",
|
||||||
|
NAMES.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* distributed with this work for additional information
|
* copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* to you under the Apache License, Version 2.0 (the
|
* copy of the License at
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing,
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* software distributed under the License is distributed on an
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* KIND, either express or implied. See the License for the
|
* the License.
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
*/
|
||||||
package domainapp.integtests.bootstrap;
|
package domainapp.integtests.bootstrap;
|
||||||
|
|
||||||
@ -45,7 +41,8 @@ public class SimpleAppSystemInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static IsisConfiguration testConfiguration() {
|
private static IsisConfiguration testConfiguration() {
|
||||||
final IsisConfigurationForJdoIntegTests testConfiguration = new IsisConfigurationForJdoIntegTests();
|
final IsisConfigurationForJdoIntegTests testConfiguration =
|
||||||
|
new IsisConfigurationForJdoIntegTests();
|
||||||
|
|
||||||
testConfiguration.addRegisterEntitiesPackagePrefix("domainapp.dom.modules");
|
testConfiguration.addRegisterEntitiesPackagePrefix("domainapp.dom.modules");
|
||||||
return testConfiguration;
|
return testConfiguration;
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
/**
|
/**
|
||||||
O * Licensed to the Apache Software Foundation (ASF) under one or more
|
* O * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* this work for additional information regarding copyright ownership.
|
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* (the "License"); you may not use this file except in compliance with
|
* copy of the License at
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* See the License for the specific language governing permissions and
|
* the License.
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package domainapp.integtests.specglue;
|
package domainapp.integtests.specglue;
|
||||||
|
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* this work for additional information regarding copyright ownership.
|
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* (the "License"); you may not use this file except in compliance with
|
* copy of the License at
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* See the License for the specific language governing permissions and
|
* the License.
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package domainapp.integtests.specglue;
|
package domainapp.integtests.specglue;
|
||||||
|
|
||||||
@ -27,5 +25,4 @@ public class CatalogOfFixturesGlue extends CukeGlueAbstract {
|
|||||||
public void integrationFixtures() throws Throwable {
|
public void integrationFixtures() throws Throwable {
|
||||||
scenarioExecution().install(new RecreateSimpleObjects());
|
scenarioExecution().install(new RecreateSimpleObjects());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* this work for additional information regarding copyright ownership.
|
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* (the "License"); you may not use this file except in compliance with
|
* copy of the License at
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* See the License for the specific language governing permissions and
|
* the License.
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package domainapp.integtests.specglue.modules.simple;
|
package domainapp.integtests.specglue.modules.simple;
|
||||||
|
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* this work for additional information regarding copyright ownership.
|
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* (the "License"); you may not use this file except in compliance with
|
* copy of the License at
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* See the License for the specific language governing permissions and
|
* the License.
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package domainapp.integtests.specs;
|
package domainapp.integtests.specs;
|
||||||
|
|
||||||
@ -26,14 +24,9 @@ import cucumber.api.junit.Cucumber;
|
|||||||
* Runs scenarios in all <tt>.feature</tt> files (this package and any subpackages).
|
* Runs scenarios in all <tt>.feature</tt> files (this package and any subpackages).
|
||||||
*/
|
*/
|
||||||
@RunWith(Cucumber.class)
|
@RunWith(Cucumber.class)
|
||||||
@CucumberOptions(
|
@CucumberOptions(format = {"html:target/cucumber-html-report", "json:target/cucumber.json"},
|
||||||
format = {
|
glue = {"classpath:domainapp.integtests.specglue"}, strict = true, tags = {"~@backlog",
|
||||||
"html:target/cucumber-html-report"
|
"~@ignore"})
|
||||||
,"json:target/cucumber.json"
|
|
||||||
},
|
|
||||||
glue={"classpath:domainapp.integtests.specglue"},
|
|
||||||
strict = true,
|
|
||||||
tags = { "~@backlog", "~@ignore" })
|
|
||||||
public class RunSpecs {
|
public class RunSpecs {
|
||||||
// intentionally empty
|
// intentionally empty
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* agreements. See the NOTICE file distributed with this work for additional information regarding
|
||||||
* distributed with this work for additional information
|
* copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
* "License"); you may not use this file except in compliance with the License. You may obtain a
|
||||||
* to you under the Apache License, Version 2.0 (the
|
* copy of the License at
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing,
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||||
* software distributed under the License is distributed on an
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
* KIND, either express or implied. See the License for the
|
* the License.
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
*/
|
||||||
package domainapp.webapp;
|
package domainapp.webapp;
|
||||||
|
|
||||||
@ -53,6 +49,7 @@ import de.agilecoders.wicket.themes.markup.html.bootswatch.BootswatchThemeProvid
|
|||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* See:
|
* See:
|
||||||
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* <filter>
|
* <filter>
|
||||||
* <filter-name>wicket</filter-name>
|
* <filter-name>wicket</filter-name>
|
||||||
@ -95,10 +92,13 @@ public class SimpleApplication extends IsisWicketApplication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// else demo mode
|
// else demo mode
|
||||||
final AuthenticatedWebSessionForIsis s = (AuthenticatedWebSessionForIsis) super.newSession(request, response);
|
final AuthenticatedWebSessionForIsis s =
|
||||||
|
(AuthenticatedWebSessionForIsis) super.newSession(request, response);
|
||||||
IRequestParameters requestParameters = request.getRequestParameters();
|
IRequestParameters requestParameters = request.getRequestParameters();
|
||||||
final org.apache.wicket.util.string.StringValue user = requestParameters.getParameterValue("user");
|
final org.apache.wicket.util.string.StringValue user =
|
||||||
final org.apache.wicket.util.string.StringValue password = requestParameters.getParameterValue("pass");
|
requestParameters.getParameterValue("user");
|
||||||
|
final org.apache.wicket.util.string.StringValue password =
|
||||||
|
requestParameters.getParameterValue("pass");
|
||||||
s.signIn(user.toString(), password.toString());
|
s.signIn(user.toString(), password.toString());
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -129,11 +129,15 @@ public class SimpleApplication extends IsisWicketApplication {
|
|||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(String.class).annotatedWith(Names.named("applicationName")).toInstance("Simple App");
|
bind(String.class).annotatedWith(Names.named("applicationName")).toInstance("Simple App");
|
||||||
bind(String.class).annotatedWith(Names.named("applicationCss")).toInstance("css/application.css");
|
bind(String.class).annotatedWith(Names.named("applicationCss")).toInstance(
|
||||||
bind(String.class).annotatedWith(Names.named("applicationJs")).toInstance("scripts/application.js");
|
"css/application.css");
|
||||||
bind(String.class).annotatedWith(Names.named("welcomeMessage")).toInstance(readLines(getClass(), "welcome.html"));
|
bind(String.class).annotatedWith(Names.named("applicationJs")).toInstance(
|
||||||
|
"scripts/application.js");
|
||||||
|
bind(String.class).annotatedWith(Names.named("welcomeMessage")).toInstance(
|
||||||
|
readLines(getClass(), "welcome.html"));
|
||||||
bind(String.class).annotatedWith(Names.named("aboutMessage")).toInstance("Simple App");
|
bind(String.class).annotatedWith(Names.named("aboutMessage")).toInstance("Simple App");
|
||||||
bind(InputStream.class).annotatedWith(Names.named("metaInfManifest")).toProvider(Providers.of(getServletContext().getResourceAsStream("/META-INF/MANIFEST.MF")));
|
bind(InputStream.class).annotatedWith(Names.named("metaInfManifest")).toProvider(
|
||||||
|
Providers.of(getServletContext().getResourceAsStream("/META-INF/MANIFEST.MF")));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -142,7 +146,9 @@ public class SimpleApplication extends IsisWicketApplication {
|
|||||||
|
|
||||||
private static String readLines(final Class<?> contextClass, final String resourceName) {
|
private static String readLines(final Class<?> contextClass, final String resourceName) {
|
||||||
try {
|
try {
|
||||||
List<String> readLines = Resources.readLines(Resources.getResource(contextClass, resourceName), Charset.defaultCharset());
|
List<String> readLines =
|
||||||
|
Resources.readLines(Resources.getResource(contextClass, resourceName),
|
||||||
|
Charset.defaultCharset());
|
||||||
final String aboutText = Joiner.on("\n").join(readLines);
|
final String aboutText = Joiner.on("\n").join(readLines);
|
||||||
return aboutText;
|
return aboutText;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user