Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Complete exercise 14.47 on page 552 Submit the Responder.java file Responder.jav

ID: 3726871 • Letter: C

Question

Complete exercise 14.47 on page 552 Submit the Responder.java file

Responder.java file:

import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.util.*;

/**
* The responder class represents a response generator object.
* It is used to generate an automatic response, based on specified input.
* Input is presented to the responder as a set of words, and based on those
* words the responder will generate a String that represents the response.
*
* Internally, the reponder uses a HashMap to associate words with response
* strings and a list of default responses. If any of the input words is found
* in the HashMap, the corresponding response is returned. If none of the input
* words is recognized, one of the default responses is randomly chosen.
*
* @author David J. Barnes and Michael Kölling.
* @version 2016.02.29
*/
public class Responder
{
// Used to map key words to responses.
private HashMap responseMap;
// Default responses to use if we don't recognise a word.
private ArrayList defaultResponses;
// The name of the file containing the default responses.
private static final String FILE_OF_DEFAULT_RESPONSES = "default.txt";
private Random randomGenerator;

/**
* Construct a Responder
*/
public Responder()
{
responseMap = new HashMap<>();
defaultResponses = new ArrayList<>();
fillResponseMap();
fillDefaultResponses();
randomGenerator = new Random();
}

/**
* Generate a response from a given set of input words.
*
* @param words A set of words entered by the user
* @return A string that should be displayed as the response
*/
public String generateResponse(HashSet words)
{
Iterator it = words.iterator();
while(it.hasNext()) {
String word = it.next();
String response = responseMap.get(word);
if(response != null) {
return response;
}
}
// If we get here, none of the words from the input line was recognized.
// In this case we pick one of our default responses (what we say when
// we cannot think of anything else to say...)
return pickDefaultResponse();
}

/**
* Enter all the known keywords and their associated responses
* into our response map.
*/
private void fillResponseMap()
{
responseMap.put("crash",
"Well, it never crashes on our system. It must have something " +
"to do with your system. Tell me more about your configuration.");
responseMap.put("crashes",
"Well, it never crashes on our system. It must have something " +
"to do with your system. Tell me more about your configuration.");
responseMap.put("slow",
"I think this has to do with your hardware. Upgrading your processor " +
"should solve all performance problems. Have you got a problem with " +
"our software?");
responseMap.put("performance",
"Performance was quite adequate in all our tests. Are you running " +
"any other processes in the background?");
responseMap.put("bug",
"Well, you know, all software has some bugs. But our software engineers " +
"are working very hard to fix them. Can you describe the problem a bit " +
"further?");
responseMap.put("buggy",
"Well, you know, all software has some bugs. But our software engineers " +
"are working very hard to fix them. Can you describe the problem a bit " +
"further?");
responseMap.put("windows",
"This is a known bug to do with the Windows operating system. Please " +
"report it to Microsoft. There is nothing we can do about this.");
responseMap.put("macintosh",
"This is a known bug to do with the Mac operating system. Please " +
"report it to Apple. There is nothing we can do about this.");
responseMap.put("expensive",
"The cost of our product is quite competitive. Have you looked around " +
"and really compared our features?");
responseMap.put("installation",
"The installation is really quite straight forward. We have tons of " +
"wizards that do all the work for you. Have you read the installation " +
"instructions?");
responseMap.put("memory",
"If you read the system requirements carefully, you will see that the " +
"specified memory requirements are 1.5 giga byte. You really should " +
"upgrade your memory. Anything else you want to know?");
responseMap.put("linux",
"We take Linux support very seriously. But there are some problems. " +
"Most have to do with incompatible glibc versions. Can you be a bit " +
"more precise?");
responseMap.put("bluej",
"Ahhh, BlueJ, yes. We tried to buy out those guys long ago, but " +
"they simply won't sell... Stubborn people they are. Nothing we can " +
"do about it, I'm afraid.");
}

/**
* Build up a list of default responses from which we can pick
* if we don't know what else to say.
*/
private void fillDefaultResponses()
{
Charset charset = Charset.forName("US-ASCII");
Path path = Paths.get(FILE_OF_DEFAULT_RESPONSES);
try (BufferedReader reader = Files.newBufferedReader(path, charset)) {
String response = reader.readLine();
while(response != null) {
defaultResponses.add(response);
response = reader.readLine();
}
}
catch(FileNotFoundException e) {
System.err.println("Unable to open " + FILE_OF_DEFAULT_RESPONSES);
}
catch(IOException e) {
System.err.println("A problem was encountered reading " +
FILE_OF_DEFAULT_RESPONSES);
}
// Make sure we have at least one response.
if(defaultResponses.size() == 0) {
defaultResponses.add("Could you elaborate on that?");
}
}

/**
* Randomly select and return one of the default responses.
* @return A random default response
*/
private String pickDefaultResponse()
{
// Pick a random number for the index in the default response list.
// The number will be between 0 (inclusive) and the size of the list (exclusive).
int index = randomGenerator.nextInt(defaultResponses.size());
return defaultResponses.get(index);
}
}

52 Chapter 14 Handling Errors Responses method. Using any text editor, change it contains an empty line between anyt work correctly again in reading in the responses from this file. Exercise 14.45 The file default.txt in the project folder of the t support-io project contains the default responses read in by the fi11D code 14.2 oursoth Reading inte ger data wit the content of this file so that scann Exercise 14.46 Change your code so that several lines of text found in th file not separated by an empty line are read as one single response. Change the default.txt file so that it contains some responses spanning multiple lines. Test. Exercise 14.47 Modify the Responder class of the tech-support-io project so that it reads the associations between keywords and responses from a text file, rather than initializing responseMap with strings written into the source code in the fil1ResponseMap method. You can use the fil1DefaultResponses method as a pattern, but you will need to make some changes to its logic, because there are two strings to be read for each entry rather than one-the keyword and the response. Try storing keywords and responses on alternating lines; keep the text of each response on a single line. You may assume that there will always be an even number of lines (i.e., no missing responses).

Explanation / Answer

package org.apache.avro.ipc;

import java.io.IOException;
import java.nio.ByteBuffer;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.avro.AvroRuntimeException;
import org.apache.avro.UnresolvedUnionException;
import org.apache.avro.Protocol;
import org.apache.avro.Schema;
import org.apache.avro.Protocol.Message;
import org.apache.avro.util.ByteBufferInputStream;
import org.apache.avro.util.ByteBufferOutputStream;
import org.apache.avro.util.Utf8;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.generic.GenericDatumWriter;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.io.BinaryEncoder;
import org.apache.avro.io.Decoder;
import org.apache.avro.io.Encoder;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.specific.SpecificDatumWriter;

/** Base class for the server side of a protocol interaction. */
public abstract class Responder {
private static final Logger LOG = LoggerFactory.getLogger(Responder.class);

private static final Schema META =
    Schema.createMap(Schema.create(Schema.Type.BYTES));
private static final GenericDatumReader<Map<String,ByteBuffer>>
    META_READER = new GenericDatumReader<>(META);
private static final GenericDatumWriter<Map<String,ByteBuffer>>
    META_WRITER = new GenericDatumWriter<>(META);

private static final ThreadLocal<Protocol> REMOTE =
    new ThreadLocal<>();

private final Map<MD5,Protocol> protocols
    = new ConcurrentHashMap<>();

private final Protocol local;
private final MD5 localHash;
protected final List<RPCPlugin> rpcMetaPlugins;

protected Responder(Protocol local) {
    this.local = local;
    this.localHash = new MD5();
    localHash.bytes(local.getMD5());
    protocols.put(localHash, local);
    this.rpcMetaPlugins =
      new CopyOnWriteArrayList<>();
}

/** Return the remote protocol. Accesses a {@link ThreadLocal} that's set
   * around calls to {@link #respond(Protocol.Message, Object)}. */
public static Protocol getRemote() { return REMOTE.get(); }

/** Return the local protocol. */
public Protocol getLocal() { return local; }

/**
   * Adds a new plugin to manipulate per-call metadata. Plugins
   * are executed in the order that they are added.
   * @param plugin a plugin that will manipulate RPC metadata
   */
public void addRPCPlugin(RPCPlugin plugin) {
    rpcMetaPlugins.add(plugin);
}

/** Called by a server to deserialize a request, compute and serialize
   * a response or error. */
public List<ByteBuffer> respond(List<ByteBuffer> buffers) throws IOException {
    return respond(buffers, null);
}

/** Called by a server to deserialize a request, compute and serialize a
   * response or error. Transceiver is used by connection-based servers to
   * track handshake status of connection. */
public List<ByteBuffer> respond(List<ByteBuffer> buffers,
                                  Transceiver connection) throws IOException {
    Decoder in = DecoderFactory.get().binaryDecoder(
        new ByteBufferInputStream(buffers), null);
    ByteBufferOutputStream bbo = new ByteBufferOutputStream();
    BinaryEncoder out = EncoderFactory.get().binaryEncoder(bbo, null);
    Exception error = null;
    RPCContext context = new RPCContext();
    List<ByteBuffer> payload = null;
    List<ByteBuffer> handshake = null;
    boolean wasConnected = connection != null && connection.isConnected();
    try {
      Protocol remote = handshake(in, out, connection);
      out.flush();
      if (remote == null)                        // handshake failed
        return bbo.getBufferList();
      handshake = bbo.getBufferList();

      // read request using remote protocol specification
      context.setRequestCallMeta(META_READER.read(null, in));
      String messageName = in.readString(null).toString();
      if (messageName.equals(""))                 // a handshake ping
        return handshake;
      Message rm = remote.getMessages().get(messageName);
      if (rm == null)
        throw new AvroRuntimeException("No such remote message: "+messageName);
      Message m = getLocal().getMessages().get(messageName);
      if (m == null)
        throw new AvroRuntimeException("No message named "+messageName
                                       +" in "+getLocal());

      Object request = readRequest(rm.getRequest(), m.getRequest(), in);

      context.setMessage(rm);
      for (RPCPlugin plugin : rpcMetaPlugins) {
        plugin.serverReceiveRequest(context);
      }

      // create response using local protocol specification
      if ((m.isOneWay() != rm.isOneWay()) && wasConnected)
        throw new AvroRuntimeException("Not both one-way: "+messageName);

      Object response = null;

      try {
        REMOTE.set(remote);
        response = respond(m, request);
        context.setResponse(response);
      } catch (Exception e) {
        error = e;
        context.setError(error);
        LOG.warn("user error", e);
      } finally {
        REMOTE.set(null);
      }

      if (m.isOneWay() && wasConnected)           // no response data
        return null;

      out.writeBoolean(error != null);
      if (error == null)
        writeResponse(m.getResponse(), response, out);
      else
        try {
          writeError(m.getErrors(), error, out);
        } catch (UnresolvedUnionException e) {    // unexpected error
          throw error;
        }
    } catch (Exception e) {                       // system error
      LOG.warn("system error", e);
      context.setError(e);
      bbo = new ByteBufferOutputStream();
      out = EncoderFactory.get().binaryEncoder(bbo, null);
      out.writeBoolean(true);
      writeError(Protocol.SYSTEM_ERRORS, new Utf8(e.toString()), out);
      if (null == handshake) {
        handshake = new ByteBufferOutputStream().getBufferList();
      }
    }
    out.flush();
    payload = bbo.getBufferList();

    // Grab meta-data from plugins
    context.setResponsePayload(payload);
    for (RPCPlugin plugin : rpcMetaPlugins) {
      plugin.serverSendResponse(context);
    }
    META_WRITER.write(context.responseCallMeta(), out);
    out.flush();
    // Prepend handshake and append payload
    bbo.prepend(handshake);
    bbo.append(payload);

    return bbo.getBufferList();
}

private SpecificDatumWriter<HandshakeResponse> handshakeWriter =
    new SpecificDatumWriter<>(HandshakeResponse.class);
private SpecificDatumReader<HandshakeRequest> handshakeReader =
    new SpecificDatumReader<>(HandshakeRequest.class);

private Protocol handshake(Decoder in, Encoder out, Transceiver connection)
    throws IOException {
    if (connection != null && connection.isConnected())
      return connection.getRemote();
    HandshakeRequest request = (HandshakeRequest)handshakeReader.read(null, in);
    Protocol remote = protocols.get(request.clientHash);
    if (remote == null && request.clientProtocol != null) {
      remote = Protocol.parse(request.clientProtocol.toString());
      protocols.put(request.clientHash, remote);
    }
    HandshakeResponse response = new HandshakeResponse();
    if (localHash.equals(request.serverHash)) {
      response.match =
        remote == null ? HandshakeMatch.NONE : HandshakeMatch.BOTH;
    } else {
      response.match =
        remote == null ? HandshakeMatch.NONE : HandshakeMatch.CLIENT;
    }
    if (response.match != HandshakeMatch.BOTH) {
      response.serverProtocol = local.toString();
      response.serverHash = localHash;
    }

    RPCContext context = new RPCContext();
    context.setHandshakeRequest(request);
    context.setHandshakeResponse(response);
    for (RPCPlugin plugin : rpcMetaPlugins) {
      plugin.serverConnecting(context);
    }
    handshakeWriter.write(response, out);

    if (connection != null && response.match != HandshakeMatch.NONE)
      connection.setRemote(remote);

    return remote;
}

/** Computes the response for a message. */
public abstract Object respond(Message message, Object request)
    throws Exception;

/** Reads a request message. */
public abstract Object readRequest(Schema actual, Schema expected, Decoder in)
    throws IOException;

/** Writes a response message. */
public abstract void writeResponse(Schema schema, Object response,
                                     Encoder out) throws IOException;

/** Writes an error message. */
public abstract void writeError(Schema schema, Object error,
                                  Encoder out) throws IOException;

}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote