001: package org.andromda.core.server;
002:
003: import java.io.DataInputStream;
004: import java.io.IOException;
005: import java.io.ObjectInputStream;
006: import java.io.ObjectOutputStream;
007:
008: import java.net.ServerSocket;
009: import java.net.Socket;
010: import java.net.SocketTimeoutException;
011:
012: import org.andromda.core.common.AndroMDALogger;
013: import org.andromda.core.configuration.Configuration;
014: import org.andromda.core.engine.Engine;
015:
016: /**
017: * The default AndroMDA {@link Server instance}.
018: *
019: * @author Chad Brandon
020: */
021: public class DefaultServer implements Server {
022: /**
023: * The message sent to the client when AndroMDA processing has completed.
024: */
025: private static final String COMPLETE = "complete";
026:
027: /**
028: * The command sent to the server that indicates it
029: * should stop.
030: */
031: static final String STOP = "stop";
032:
033: /**
034: * The server listener.
035: */
036: private ServerSocket listener = null;
037:
038: /**
039: * The AndroMDA Engine instance.
040: */
041: private Engine engine = Engine.newInstance();
042:
043: /**
044: * @see org.andromda.core.server.Server#start(org.andromda.core.configuration.Configuration)
045: */
046: public void start(final Configuration configuration) {
047: engine.initialize(configuration);
048: if (configuration != null) {
049: final org.andromda.core.configuration.Server serverConfiguration = configuration
050: .getServer();
051: if (serverConfiguration != null) {
052: try {
053: try {
054: this .listener = new ServerSocket(
055: serverConfiguration.getPort());
056: final int modelLoadInterval = serverConfiguration
057: .getLoadInterval();
058: if (modelLoadInterval > 0) {
059: this .listener
060: .setSoTimeout(serverConfiguration
061: .getLoadInterval());
062: }
063: } catch (final IOException exception) {
064: throw new ServerException(
065: "Could not listen on port '"
066: + serverConfiguration.getPort()
067: + "', change the port in your configuration");
068: }
069: while (true) {
070: try {
071: final Socket client = this .listener
072: .accept();
073: if (client != null) {
074: final ObjectOutputStream serverOutput = new ObjectOutputStream(
075: client.getOutputStream());
076: final ObjectInputStream objectInput = new ObjectInputStream(
077: new DataInputStream(client
078: .getInputStream()));
079: try {
080: final Object object = objectInput
081: .readObject();
082: if (object instanceof Configuration) {
083: this .engine
084: .run((Configuration) object);
085: } else if (object instanceof String) {
086: final String string = (String) object;
087: if (string.equals(STOP)) {
088: break;
089: }
090: }
091: } catch (final Throwable throwable) {
092: AndroMDALogger.error(throwable);
093:
094: // - pass the exception to the client
095: serverOutput.writeObject(throwable);
096: }
097:
098: // - signal to the client, it can stop waiting
099: serverOutput.writeObject(COMPLETE);
100: serverOutput.flush();
101: serverOutput.close();
102: objectInput.close();
103: client.close();
104: }
105: } catch (final SocketTimeoutException exception) {
106: try {
107: this .engine
108: .loadModelsIfNecessary(configuration);
109: this .resetFailedLoadAttempts();
110: } catch (final Throwable throwable) {
111: this .incrementFailedLoadAttempts();
112:
113: // - only fail if the failed load attempts is greater than the maximum
114: if (this .failedLoadAttempts > serverConfiguration
115: .getMaximumFailedLoadAttempts()) {
116: throw throwable;
117: }
118: }
119: }
120: }
121: this .shutdown();
122: } catch (final Throwable throwable) {
123: throw new ServerException(throwable);
124: }
125: }
126: }
127: }
128:
129: /**
130: * Stores the failed load attempts.
131: */
132: private int failedLoadAttempts;
133:
134: /**
135: * Resets the failed load attempt counter.
136: */
137: private void resetFailedLoadAttempts() {
138: this .failedLoadAttempts = 0;
139: }
140:
141: /**
142: * Increments the failed load attempt counter.
143: */
144: private void incrementFailedLoadAttempts() {
145: this .failedLoadAttempts++;
146: }
147:
148: /**
149: * Shuts the server down.
150: */
151: public void shutdown() {
152: try {
153: this .listener.close();
154: this .listener = null;
155: this .engine.shutdown();
156: } catch (final IOException exception) {
157: // ignore exception
158: }
159: }
160: }
|