Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Applied Java™ Patterns - Stephen Stelting, Olav Maassen.pdf
Скачиваний:
198
Добавлен:
24.05.2014
Размер:
2.84 Mб
Скачать

Example A.253 RunPattern.java

1.import java.io.IOException;

2.public class RunPattern{

3.public static void main(String [] arguments){

4.System.out.println("Example for the Router pattern");

5.System.out.println("This code same will create a series of GUIs, and use");

6.System.out.println(" the Router pattern to map message notifications between");

7.System.out.println(" them. In this code example, the Router will send messages");

8.System.out.println(" between the GUI clients based on the following mapping:");

9.System.out.println();

10.System.out.println("\tGUI # 1:\tGUI #2\tGUI #3");

11.System.out.println("\tGUI # 2:\tGUI #1\tGUI #4");

12.System.out.println("\tGUI # 3:\tGUI #1\tGUI #4");

13.System.out.println("\tGUI # 4:\tGUI #1\tGUI #2\tGUI #3\tGUI #4");

14.System.out.println();

15.

16.System.out.println("Running the RMI compiler (rmic)");

17.try{

18.

Process

p1

=

Runtime.getRuntime().exec("rmic Router");

19.

Process

p2

=

Runtime.getRuntime().exec("rmic RouterClient");

20.

p1.waitFor();

21.

p2.waitFor();

22.}

23.catch (IOException exc){

24. System.err.println("Unable to run rmic utility. Exiting application.");

25. System.exit(1);

26.}

27.catch (InterruptedException exc){

28. System.err.println("Threading problems encountered while using the rmic utility.");

29. }

30.

31.

32.System.out.println("Starting the rmiregistry");

33.System.out.println();

34.Process rmiProcess = null;

35.try{

36. rmiProcess = Runtime.getRuntime().exec("rmiregistry");

37. Thread.sleep(15000);

38.}

39.catch (IOException exc){

40. System.err.println("Unable to start the rmiregistry. Exiting application.");

41. System.exit(1);

42.}

43.catch (InterruptedException exc){

44.System.err.println("Threading problems encountered when starting the

rmiregistry.");

45.

}

46.

 

47.System.out.println("Creating the Router object");

48.System.out.println();

49.Router mainRouter = new Router();

50.

51.InputKey keyOne = new InputKey();

52.InputKey keyTwo = new InputKey();

53.InputKey keyThree = new InputKey();

54.InputKey keyFour = new InputKey();

56.System.out.println("Creating the four RouterGui objects");

57.System.out.println();

58.RouterGui first = new RouterGui(keyOne);

59.RouterGui second = new RouterGui(keyTwo);

60.RouterGui third = new RouterGui(keyThree);

61.RouterGui fourth = new RouterGui(keyFour);

62.

63.System.out.println("Creating GUI OutputChannel lists for the Router");

64.System.out.println();

65.OutputChannel [] subscriptionListOne =

{second.getOutputChannel(),third.getOutputChannel() };

66.OutputChannel [] subscriptionListTwo =

{first.getOutputChannel(),fourth.getOutputChannel() };

67.OutputChannel [] subscriptionListThree = { first.getOutputChannel(),

second.getOutputChannel(),

68. third.getOutputChannel(),fourth.getOutputChannel() };

69.

70.mainRouter.addRoute(keyOne, subscriptionListOne);

71.mainRouter.addRoute(keyTwo, subscriptionListTwo);

358

72.mainRouter.addRoute(keyThree, subscriptionListTwo);

73.mainRouter.addRoute(keyFour, subscriptionListThree);

75.first.createGui();

76.second.createGui();

77.third.createGui();

78.fourth.createGui();

79.}

80.}

359

Transaction

The Personal Information Manager stores appointments based on their date. Naturally, since users lead active lives, appointments change all the time. A user's appointment book is constantly being updated with new or changing appointments.

If a number of users need to agree on a date for an appointment, it would be helpful if their appointment books could coordinate, arriving at a date that would work for everybody. That's what this example demonstrates—how the Transaction pattern can be used to allow address books to reschedule a date for an appointment.

The basic interface that supports transactions is AppointmentTransactionParticipant. It defines three methods to manage transactions (join, commit, and cancel) and the business method changeDate. This class is a Remote class, since it is used to communicate between transaction participants that might reside on different Java Virtual Machines.

Example A.254 AppointmentTransactionParticipant.java

1.import java.util.Date;

2.import java.rmi.Remote;

3.import java.rmi.RemoteException;

4.public interface AppointmentTransactionParticipant extends Remote{

5.public boolean join(long transactionID) throws RemoteException;

6.public void commit(long transactionID) throws TransactionException, RemoteException;

7.public void cancel(long transactionID) throws RemoteException;

8.public boolean changeDate(long transactionID, Appointment appointment,

9.Date newStartDate) throws TransactionException, RemoteException;

10.}

The class AppointmentBook represents a user's calendar, and implements the

AppointmentTransactionParticipant interface. In addition to providing support to change an Appointment date, the AppointmentBook can initiate a change of an Appointment. Its method changeAppointment accepts a transaction ID, an Appointment object, an array of other AppointmentBooks that should be transaction participants, and an array of possible alternate dates for the appointment. The changeAppointment method allows one of the AppointmentBook objects to communicate with the others using RMI, calling the changeDate method on every one of the participants until all agree on an alternate date for the Appointment.

Example A.255 AppointmentBook.java

1.import java.util.ArrayList;

2.import java.util.HashMap;

3.import java.util.Date;

4.import java.rmi.Naming;

5.import java.rmi.server.UnicastRemoteObject;

6.import java.rmi.RemoteException;

7.public class AppointmentBook implements AppointmentTransactionParticipant{

8.private static final String TRANSACTION_SERVICE_PREFIX = "transactionParticipant";

9.private static final String TRANSACTION_HOSTNAME = "localhost";

10.private static int index = 1;

11.private String serviceName = TRANSACTION_SERVICE_PREFIX + index++;

12.private HashMap appointments = new HashMap();

13.private long currentTransaction;

14.private Appointment currentAppointment;

15.private Date updateStartDate;

16.

17.public AppointmentBook(){

18.try {

19.

UnicastRemoteObject.exportObject(this);

20.

Naming.rebind(serviceName, this);

21.}

22.catch (Exception exc){

23.System.err.println("Error using RMI to register the AppointmentBook " + exc);

24.}

25.}

26.

27.public String getUrl(){

28.return "//" + TRANSACTION_HOSTNAME + "/" + serviceName;

29.}

30.

31.public void addAppointment(Appointment appointment){

32.if (!appointments.containsValue(appointment)){

33. if (!appointments.containsKey(appointment.getStartDate())){

34. appointments.put(appointment.getStartDate(), appointment);

360

35. }

36.}

37.}

38.public void removeAppointment(Appointment appointment){

39.if (appointments.containsValue(appointment)){

40. appointments.remove(appointment.getStartDate());

41.}

42.}

44.public boolean join(long transactionID){

45.if (currentTransaction != 0){

46.

return false;

47.} else {

48.

currentTransaction = transactionID;

49.

return true;

50.}

51.}

52.public void commit(long transactionID) throws TransactionException{

53.if (currentTransaction != transactionID){

54. throw new TransactionException("Invalid TransactionID");

55.} else {

56.

removeAppointment(currentAppointment);

57.

currentAppointment.setStartDate(updateStartDate);

58.

appointments.put(updateStartDate, currentAppointment);

59.}

60.}

61.public void cancel(long transactionID){

62.if (currentTransaction == transactionID){

63. currentTransaction = 0;

64. appointments.remove(updateStartDate);

65.}

66.}

67.public boolean changeDate(long transactionID, Appointment appointment,

68.Date newStartDate) throws TransactionException{

69.if ((appointments.containsValue(appointment)) && (!appointments.

70.

 

containsKey(newStartDate))){

 

appointments.put(newStartDate, null);

 

71.

updateStartDate = newStartDate;

 

 

72.

currentAppointment = appointment;

 

Y

73.

return true;

 

 

74.

}

 

 

L

75.

return false;

F

76.

}

 

M

 

 

77.

 

E

 

 

 

78.

public boolean changeAppointment(Appointment appointment, Date[] possibleDates,

79.

 

T

 

 

 

AppointmentTransactionParticipant[] participants, long transactionID){

80.

try {

 

 

 

 

81.

for (int i = 0; i < participants.length; i++){

82.

 

if (!participants[i].join(transactionID)){

83.

 

return false;

 

 

 

84.

}

}

 

 

 

85.

 

 

 

 

86.

for (int i = 0; i < possibleDates.length; i++){

87.

 

if (isDateAvailable(transactionID, appointment, possibleDates[i],

88.

 

participants)){

 

 

 

 

try {

 

 

 

89.

 

commitAll(transactionID, participants);

90.

 

return true;

 

 

 

91.

 

}

 

 

 

92.

 

catch(TransactionException exc){ }

93.

}

}

 

 

 

94.

 

 

 

 

95.}

96.catch (RemoteException exc){ }

97.try{

98. cancelAll(transactionID, participants);

99.}

100.catch (RemoteException exc){}

101.return false;

102.}

103.

104.private boolean isDateAvailable(long transactionID, Appointment appointment,

105.Date date, AppointmentTransactionParticipant[] participants){

106.try{

107.

for (int i = 0; i <

i++){

108.

try{

TEAM FLY PRESENTS

109.

if (!participants[i].changeDate(transactionID, appointment, date)){

110.

return false;

361