1
2
3
4
5
6
7
8
9
10
11
12
13
14 package chapters.mdc;
15
16 import java.rmi.RemoteException;
17 import java.rmi.registry.LocateRegistry;
18 import java.rmi.registry.Registry;
19 import java.rmi.server.UnicastRemoteObject;
20 import java.util.Vector;
21
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24 import org.slf4j.MDC;
25
26 import ch.qos.logback.classic.LoggerContext;
27 import ch.qos.logback.classic.joran.JoranConfigurator;
28 import ch.qos.logback.core.joran.spi.JoranException;
29
30
31
32
33
34
35
36 public class NumberCruncherServer extends UnicastRemoteObject implements NumberCruncher {
37
38 private static final long serialVersionUID = 1L;
39
40 static Logger logger = LoggerFactory.getLogger(NumberCruncherServer.class);
41
42 public NumberCruncherServer() throws RemoteException {
43 }
44
45 public int[] factor(int number) throws RemoteException {
46
47 try {
48 MDC.put("client", NumberCruncherServer.getClientHost());
49 } catch (java.rmi.server.ServerNotActiveException e) {
50 logger.warn("Caught unexpected ServerNotActiveException.", e);
51 }
52
53
54
55
56
57
58 MDC.put("number", String.valueOf(number));
59
60 logger.info("Beginning to factor.");
61
62 if (number <= 0) {
63 throw new IllegalArgumentException(number + " is not a positive integer.");
64 } else if (number == 1) {
65 return new int[] { 1 };
66 }
67
68 Vector<Integer> factors = new Vector<Integer>();
69 int n = number;
70
71 for (int i = 2; (i <= n) && ((i * i) <= number); i++) {
72
73
74
75 logger.debug("Trying " + i + " as a factor.");
76
77 if ((n % i) == 0) {
78 logger.info("Found factor " + i);
79 factors.addElement(i);
80
81 do {
82 n /= i;
83 } while ((n % i) == 0);
84 }
85
86
87
88 delay(100);
89 }
90
91 if (n != 1) {
92 logger.info("Found factor " + n);
93 factors.addElement(n);
94 }
95
96 int len = factors.size();
97
98 int[] result = new int[len];
99
100 for (int i = 0; i < len; i++) {
101 result[i] = ((Integer) factors.elementAt(i)).intValue();
102 }
103
104
105 MDC.remove("client");
106 MDC.remove("number");
107
108 return result;
109 }
110
111 static void usage(String msg) {
112 System.err.println(msg);
113 System.err.println("Usage: java chapters.mdc.NumberCruncherServer configFile\n" + " where configFile is a logback configuration file.");
114 System.exit(1);
115 }
116
117 public static void delay(int millis) {
118 try {
119 Thread.sleep(millis);
120 } catch (InterruptedException e) {
121 }
122 }
123
124 public static void main(String[] args) {
125 if (args.length != 1) {
126 usage("Wrong number of arguments.");
127 }
128
129 String configFile = args[0];
130
131 if (configFile.endsWith(".xml")) {
132 try {
133 LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
134 JoranConfigurator configurator = new JoranConfigurator();
135 configurator.setContext(lc);
136 lc.reset();
137 configurator.doConfigure(args[0]);
138 } catch (JoranException je) {
139 je.printStackTrace();
140 }
141 }
142
143 NumberCruncherServer ncs;
144
145 try {
146 ncs = new NumberCruncherServer();
147 logger.info("Creating registry.");
148
149 Registry registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
150 registry.rebind("Factor", ncs);
151 logger.info("NumberCruncherServer bound and ready.");
152 } catch (Exception e) {
153 logger.error("Could not bind NumberCruncherServer.", e);
154
155 return;
156 }
157 }
158 }