Disclaimer - this is for an assignment, I'm trying to figure out why my code is giving me an error.
Background:
So the assignment is basically to make edits to SimpleChat, a client-server framework for which the teacher has given us the code. I am trying to implement a chat console from the server side, and implement actions that begin with hashtags. So I have a "handleMessageFromServer" method in my server file (called "EchoServer"), and am trying to call it from the server console (aptly named "Server Console"). I'll put the relevant code below, and explain it:
I'll edit what I've put, I'll put the whole files with comments.
Below is the "EchoServer" file. The more important bits relevant to my question are the "handleMessageFromServer" method, which I am trying to call from the other file and pass in information, as well as the EchoServer constructor, which I am using in the other file to create an instance.
import java.io.*;
import ocsf.server.*;
import common.*;
/**
* This class overrides some of the methods in the abstract
* superclass in order to give more functionality to the server.
*
* #author Dr Timothy C. Lethbridge
* #author Dr Robert Laganière
* #author François Bélanger
* #author Paul Holden
* #version July 2000
*/
public class EchoServer extends AbstractServer
{
//Class variables *************************************************
/**
* The default port to listen on.
*/
final public static int DEFAULT_PORT = 5555;
//Constructors ****************************************************
/*
* An interface type variable, will allow the implementation of the
* Display method in the client.
*
*/
public ChatIF server;
/**
* Constructs an instance of the echo server.
*
* #param port The port number to connect on.
*/
public EchoServer(int port, ChatIF server)
{
super(port);
this.server = server;
}
//Instance methods ************************************************
/**
* This method handles any messages received from the client.
*
* #param msg The message received from the client.
* #param client The connection from which the message originated.
*/
public void handleMessageFromClient
(Object msg, ConnectionToClient client)
{
System.out.println("Message received: " + msg + " from " + client);
this.sendToAllClients(msg);
}
/**
* This method handles any messages received from the server console.
*
* #param msg The message received from the server.
* #param server The connection from which the message originated.
*/
public void handleMessageFromServer(String message)
{
if (message.charAt(0) == '#')
{
serverCommand(message);
}
else
{
server.display(message);
this.sendToAllClients("SERVER MSG> " + message);
}
}
/*This method allows us to run commands from the server console
*
*/
public void serverCommand(String command)
{
if (command.equalsIgnoreCase("quit")) System.exit(0); /////Shuts the system down
else if (command.equalsIgnoreCase("#stop")) stopListening(); ///Stops listening for connections
else if (command.equalsIgnoreCase("#close")) ///////closes all connections
{
try close();
catch(IOException ex) {
server.display("Could not close connection");
}
}
else if (command.toLowerCase().startsWith("#setport")) /////Sets port when not listening
{
if (!isListening() && getNumberOfClients() == 0)
{
//////If there are no connected clients, and
//////we're not listening for new ones, we can
////assume that the server is closed (close() has been
////called.
String portNum = command.substring(s.indexOf("<") + 1)
portNum = portnum.substring(0, s.indexOf(">"));
int num = Integer.parseInt(portNum);
setPort(num);
server.display("The server port has been changed to port" + getPort());
}
else
{
server.display("Port cannot be changed");
}
else if (command.equalsIgnoreCase("#start")) ///////starts listening for clients if not already
{
if (!isListening())
{
try listen();
catch (Exception ex)
{
server.display("Could not listen for clients!");
}
}
else
{
server.display("Already listening for clients");
}
}
else if (message.equalsIgnoreCase("#getport")) //////gets the port number
{
server.display("Current port: " + Integer.toString(getPort()));
}
}
}
/**
* This method overrides the one in the superclass. Called
* when the server starts listening for connections.
*/
protected void serverStarted()
{
System.out.println
("Server listening for connections on port " + getPort());
}
/**
* This method overrides the one in the superclass. Called
* when the server stops listening for connections.
*/
protected void serverStopped()
{
System.out.println
("Server has stopped listening for connections.");
}
//Class methods ***************************************************
/**
* This method is responsible for the creation of
* the server instance (there is no UI in this phase).
*
* #param args[0] The port number to listen on. Defaults to 5555
* if no argument is entered.
*/
public static void main(String[] args)
{
int port = 0; //Port to listen on
try
{
port = Integer.parseInt(args[0]); //Get port from command line
}
catch(Throwable t)
{
port = DEFAULT_PORT; //Set port to 5555
}
EchoServer sv = new EchoServer(port);
try
{
sv.listen(); //Start listening for connections
}
catch (Exception ex)
{
System.out.println("ERROR - Could not listen for clients!");
}
}
}
//End of EchoServer class
Below is the ServerConsole file, where I am creating an instance of the EchoServer class so that I may pass in information. The purpose of this file is to create an environment where the server side can send text for the SimpleChat application. The text then gets passed back to the EchoServer class, where it can be used for commands (all the commands begin with hashtags). I am currently getting an error in the "accept" method, when trying to call echoServer.handleMessageFromServer(message). The error is "The method handleMessageFromServer(String) is undefined for the type EchoServer".
import java.io.*;
import client.*;
import common.*;
/**
* This class constructs the UI for a chat client. It implements the
* chat interface in order to activate the display() method.
* Warning: Some of the code here is cloned in ServerConsole
*
* #author François Bélanger
* #author Dr Timothy C. Lethbridge
* #author Dr Robert Laganière
* #version July 2000
*/
public class ServerConsole implements ChatIF
{
//Class variables *************************************************
/**
* The default port to connect on.
*/
final public static int DEFAULT_PORT = 5555;
//Instance variables **********************************************
/**
* The instance of the server that created this ConsoleChat.
*/
//Constructors ****************************************************
EchoServer echoServer;
/**
* Constructs an instance of the ClientConsole UI.
*
* #param host The host to connect to.
* #param port The port to connect on.
*/
public ServerConsole(int port)
{
this.echoServer = new EchoServer(port);
}
//Instance methods ************************************************
/**
* This method waits for input from the console. Once it is
* received, it sends it to the client's message handler.
*/
public void accept()
{
try
{
BufferedReader fromConsole =
new BufferedReader(new InputStreamReader(System.in));
String message;
while (true)
{
message = fromConsole.readLine();
///////////////ADDED FOR E50B MA/ND
echoServer.handleMessageFromServer(message);
///////////////ADDED FOR E50B MA/ND
}
}
catch (Exception ex)
{
System.out.println
("Unexpected error while reading from console!");
}
}
/**
* This method overrides the method in the ChatIF interface. It
* displays a message onto the screen.
*
* #param message The string to be displayed.
*/
public void display(String message)
{
System.out.println(message);
}
//Class methods ***************************************************
/**
* This method is responsible for the creation of the Client UI.
*
* #param args[0] The host to connect to.
*/
public static void main(String[] args)
{
int port = 0; //The port number
try
{
String host = args[0];
}
catch(ArrayIndexOutOfBoundsException e)
{
String host = "localhost";
}
ServerConsole chat= new ServerConsole(DEFAULT_PORT);
chat.accept(); //Wait for console data
}
}
//End of ConsoleChat class
I think I might not be constructing the instance right, but any help is greatly appreciated guys!
Your echoserver class has the following contructor:
public EchoServer(int port, ChatIF server)
{
super(port);
this.server = server;
}
note it takes in two parameters.
your call to the EchoServer is however only injecting a port
this.echoServer = new EchoServer(port);
Without seeing all your code my guess would be that Echoserver extends some other Server class that does not have the method you want.
Related
We have a spring application which is having a dynamic queue listener connecting to queue in rabbitmq. Let's say I have a total of 5 listener consumer connected to 5 queues from my spring application to rabbitmq.
Now if Network fluctuation/failure happens then each time, first one of my 5 connected queues is stopped retrying to rabbitmq.
I have debugged code through spring-amqp class and found out that on creating a connection with rabbitmq (when network failure happens), it fails to connect to it and throw org.springframework.amqp.AmqpIOException particular exception which is not handled in retry function so that that queue is removed from retried queue list.
My Main class:
#Slf4j
#SpringBootApplication(exclude = {ClientAutoConfiguration.class})
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = "com.x.x.repositories")
#EntityScan(basePackages = "com.x.x.entities")
public class Main
{
#PostConstruct
void configuration()
{
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
/**
* The main method.
*
* #param args the arguments
*/
public static void main(String[] args)
{
ConfigurableApplicationContext context = SpringApplication.run(Main.class, args);
RabbitMQListenerUtil queueRegisterUtil = context.getBean(RabbitMQListenerUtil.class);
try
{
queueRegisterUtil.registerSpecifiedListenerForAllInstance();
}
catch (Exception e)
{
log.error(e.getMessage(), e);
}
}
}
Class which is used to create 5 consumer/listener
/**
* The Class RabbitMQListenerUtil.
*/
#Component
#Slf4j
public class RabbitMQListenerUtil
{
#Autowired
private ApplicationContext applicationContext;
public void registerSpecifiedListenerForAllInstance()
{
try
{
log.debug("New Listener has been register for instane name : ");
Thread.sleep(5000);
registerNewListener("temp1");
registerNewListener("temp2");
registerNewListener("temp3");
registerNewListener("temp4");
registerNewListener("temp5");
}
catch (Exception e)
{
}
}
/**
* This method will add new listener bean for given queue name at runtime
*
* #param queueName - Queue name
* #return Configurable application context
*/
public void registerNewListener(String queueName)
{
AnnotationConfigApplicationContext childAnnotaionConfigContext = new AnnotationConfigApplicationContext();
childAnnotaionConfigContext.setParent(applicationContext);
ConfigurableEnvironment environmentConfig = childAnnotaionConfigContext.getEnvironment();
Properties listenerProperties = new Properties();
listenerProperties.setProperty("queue.name", queueName + "_queue");
PropertiesPropertySource pps = new PropertiesPropertySource("props", listenerProperties);
environmentConfig.getPropertySources().addLast(pps);
childAnnotaionConfigContext.register(RabbitMQListenerConfig.class);
childAnnotaionConfigContext.refresh();
}
}
Class which create dynamic listener for queue consumer
/**
* The Class RabbitMQListenerConfig.
*/
#Configuration
#Slf4j
#EnableRabbit
public class RabbitMQListenerConfig
{
/** The Constant ALLOW_MESSAGE_REQUEUE. */
private static final boolean ALLOW_MESSAGE_REQUEUE = true;
/** The Constant MULTIPLE_MESSAGE_FALSE. */
private static final boolean MULTIPLE_MESSAGE_FALSE = false;
/**
* Listen.
*
* #param msg the msg
* #param channel the channel
* #param queue the queue
* #param deliveryTag the delivery tag
* #throws IOException Signals that an I/O exception has occurred.
*/
#RabbitListener(queues = "${queue.name}")
public void listen(Message msg, Channel channel, #Header(AmqpHeaders.CONSUMER_QUEUE) String queue, #Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws IOException
{
int msgExecutionStatus = 0;
try
{
String message = new String(msg.getBody(), StandardCharsets.UTF_8);
log.info(message);
}
catch (Exception e)
{
log.error(e.toString());
log.error(e.getMessage(), e);
}
finally
{
ackMessage(channel, deliveryTag, msgExecutionStatus);
}
}
/**
* Ack message.
*
* #param channel the channel
* #param deliveryTag the delivery tag
* #param msgExecutionStatus the msg execution status
* #throws IOException Signals that an I/O exception has occurred.
*/
protected void ackMessage(Channel channel, long deliveryTag, int msgExecutionStatus) throws IOException
{
if (msgExecutionStatus == Constants.MESSAGE_DELETE_FOUND_EXCEPTION)
{
channel.basicNack(deliveryTag, MULTIPLE_MESSAGE_FALSE, ALLOW_MESSAGE_REQUEUE);
}
else
{
channel.basicAck(deliveryTag, MULTIPLE_MESSAGE_FALSE);
}
}
/**
* Bean will create from this with given name.
*
* #param name - Queue name-
* #return the queue
*/
#Bean
public Queue queue(#Value("${queue.name}") String name)
{
return new Queue(name);
}
/**
* RabbitAdmin Instance will be created which is required to create new Queue.
*
* #param cf - Connection factory
* #return the rabbit admin
*/
#Bean
public RabbitAdmin admin(ConnectionFactory cf)
{
return new RabbitAdmin(cf);
}
}
Application log :
https://pastebin.com/NQWdmdTH
I have tested this multiple times and each time my first connected queue is being stopped from connecting .
========================= UPDATE 1=============================
Code to reconnect stopped consumer :
https://pastebin.com/VnUrhdLP
Caused by: java.net.UnknownHostException: rabbitmqaind1.hqdev.india
There is something wrong with your network.
I am willing to use CoAP protocol for implementing a java push-based messaging system. Particularly in such a system, a client opens just once a connection with a server (resource) and the server pushes messages (‘non-confirmable’) with a specific rate (e.g., 10 messages per second). However I did not find any existing solution to build the above system.
What I found is the pull-based messaging system. For such case, a client opens a connection with the server and after some time the client sends a GET request. Then, the server handles the request and pushes (as response) a single message to the client.
Hence, for each GET, I have a single message as response -- i.e., a two-way asynchronous interaction.
Does anybody have any idea on how to implement the push-based messaging system using CoAP? Does CoAP supports such a system?
The pull-based messaging system is implemented as follows
Server Part
public class CoapServerPartAsync extends CoapServer {
private static final int COAP_PORT = 8891;
private static int incrementor = 1;
/*
* Application entry point.
*/
public static void main(String[] args) {
try {
// create server
CoapServerPartAsync server = new CoapServerPartAsync();
// add endpoints on all IP addresses
server.addEndpoints();
server.start();
} catch (SocketException e) {
System.err.println("Failed to initialize server: " + e.getMessage());
}
}
/**
* Add endpoints listening on default CoAP port on all IP addresses of all network interfaces.
*
* #throws SocketException if network interfaces cannot be determined
*/
private void addEndpoints() throws SocketException {
InetSocketAddress bindToAddress = new InetSocketAddress("127.0.0.1", COAP_PORT);
addEndpoint(new CoapEndpoint(bindToAddress));
}
/*
* Constructor for a new Hello-World server. Here, the resources
* of the server are initialized.
*/
public CoapServerPartAsync() throws SocketException {
// provide an instance of a Hello-World resource
add(new HelloWorldResource());
}
/*
* Definition of the Hello-World Resource
*/
class HelloWorldResource extends CoapResource {
public HelloWorldResource() {
// set resource identifier
super("helloWorld");
// set display name
getAttributes().setTitle("Hello-World Resource");
}
#Override
public void handleGET(CoapExchange exchange){
// respond to the request
System.out.println("Push [Hello World!"+(incrementor)+"]");
exchange.respond("Hello World!"+(incrementor));
incrementor++;
}
}
}
Client Part
public class CoapClientPartAsync {
// static boolean getResponse = false;
public static void main(String args[]) {
CoapClient client = new CoapClient("coap://127.0.0.1:8891/helloWorld").useNONs();
while(true){
CoapObserveRelation relation = client.observe(
new CoapHandler() {
#Override public void onLoad(CoapResponse response){
String content = response.getResponseText();
System.out.println("NOTIFICATION: " + content);
}
#Override public void onError() {
System.err.println("OBSERVING FAILED (press enter to exit)");
}
});
try {
Thread.sleep(1000);
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I am trying to make chatbot plugin for openfire.But when i run plugin on openfire then i am getting below error:-
2016.10.28 18: 04: 21 org.jivesoftware.openfire.container.PluginManager - Error loading plugin: C: \Program Files(x86)\ Openfire\ plugins\ hospitalbot
java.lang.NoSuchMethodError: org.jivesoftware.openfire.XMPPServerInfo.getName() Ljava / lang / String;
at org.jivesoftware.openfire.botz.BotzConnection.login(BotzConnection.java: 319)
at org.jivesoftware.openfire.botz.BotzConnection.login(BotzConnection.java: 272)
at org.jivesoftware.openfire.plugin.ChatBot.initializePlugin(ChatBot.java: 75)
at org.jivesoftware.openfire.container.PluginManager.loadPlugin(PluginManager.java: 447)
at org.jivesoftware.openfire.container.PluginManager.access$300(PluginManager.java: 68)
at org.jivesoftware.openfire.container.PluginManager$PluginMonitor.run(PluginManager.java: 1037)
at org.jivesoftware.openfire.container.PluginManager.installPlugin(PluginManager.java: 176)
at org.jivesoftware.openfire.admin.plugin_002dadmin_jsp._jspService(plugin_002dadmin_jsp.java: 180)
I have copied this plugin from below link :-
https://community.igniterealtime.org/docs/DOC-1130
I am getting error in below file :-
package org.jivesoftware.openfire.botz;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.jivesoftware.openfire.Connection;
import org.jivesoftware.openfire.SessionManager;
import org.jivesoftware.openfire.SessionPacketRouter;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.roster.Roster;
import org.jivesoftware.openfire.auth.AuthToken;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.net.VirtualConnection;
import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.session.LocalClientSession;
import org.jivesoftware.openfire.spi.ConnectionConfiguration;
import org.jivesoftware.openfire.user.UserAlreadyExistsException;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils;
import org.xmpp.packet.JID;
import org.xmpp.packet.Packet;
import org.xmpp.packet.StreamError;
/**
* The objective of BotzConnection class is to create a robot/bot application as
* an internal user of the main XMPP server. The class's login methods performs
* the necessary (virtual) connection to the server. The bot can login as an
* anonymous or a real user.
*
* <p>
* The class's object uses a BotzPacketReceiver object passed to it via one of
* it's constructors or via calls to
* {#link #setPacketReceiver(BotzPacketReceiver)} method to receive packets from
* other XMPP entities to the bot. The bot can reply to these packets with
* {#link #sendPacket(Packet)} method. Thus, a class that wants to handle bot
* packets must implement {#link BotzPacketReceiver} class.
*
* <p>
* Below is a sample parrot bot code snippet illustrating how to use
* BotzConnection and BotzPacketReceiver:
*
* <blockquote>
*
* <pre>
* *
* * BotzPacketReceiver packetReceiver = new BotzPacketReceiver() {
* * BotzConnection bot;
* * public void initialize(BotzConnection bot) { this.bot = bot; }
* * public void processIncoming(Packet packet) {
* * if (packet instanceof Message) {
* * packet.setTo(packet.getFrom());
* * bot.sendPacket(packet);
* * }
* * }
* * public void processIncomingRaw(String rawText) {};
* * public void terminate() {};
* * };
* *
* * BotzConnection bot = new BotzConnection(packetReceiver);
* * try {
* * bot.login("MyUsername");
* * Presence presence = new Presence();
* * presence.setStatus("Online");
* * bot.sendPacket(presence);
* * } catch (Exception e) {
* * }
* *
* </pre>
*
* </blockquote>
*
* #author Aznidin Zainuddin
* #see BotzPacketReceiver
*/
public class BotzConnection extends VirtualConnection {
/**
* The packet receiver object that will handle receiving of packets.
*/
private BotzPacketReceiver packetReceiver;
/**
* Holds the initialization state of the packet receiver.
*/
private boolean initPacketReceiver;
/**
* Holds the session for the bot.
*/
private LocalClientSession localClientSession;
private Roster roster;
private JID jid;
/**
* Creates a new instance of BotzConnection.
*/
public BotzConnection() {}
/**
* Creates a new instance of BotzConnection with the specified packet
* receiver.
*
* <p>
* When login is attempted with an instance created with this constructor,
* the packetReceiver traps incoming packets and texts as soon as the bot
* logs on.
*
* #param packetReceiver
* BotzConnection packetReceiver
*/
public BotzConnection(BotzPacketReceiver packetReceiver) {
this.packetReceiver = packetReceiver;
}
public LocalClientSession getLocalClientSession() {
return localClientSession;
}
public Roster getRoster() {
return roster;
}
/**
* The method will be implicitly called by the server when the bot's
* connection is (virtually) closed. The method terminates the packet
* receiver.
*/
#
Override
public void closeVirtualConnection() {
if (packetReceiver != null && initPacketReceiver) {
packetReceiver.terminate();
initPacketReceiver = false;
}
}
/**
* Calls to this method is made by the server to deliver packets to the bot.
* This method will in turn call
* {#link BotzPacketReceiver#processIncoming(Packet)} of the packet receiver
* associated with the bot.
*
* #param packet
* XMPP packet
* #throws UnauthorizedException
* When packets could not be delivered due to authorization
* problem.
*/
public void deliver(Packet packet) throws UnauthorizedException {
if (packetReceiver == null)
return;
packetReceiver.processIncoming(packet);
}
/**
* Calls to this method is made by the server to deliver raw text to the
* bot. This method will in turn call
* {#link BotzPacketReceiver#processIncomingRaw(String)} of the packet
* receiver associated with the bot.
*
* #param text
* The text string delivered to the bot.
*/
public void deliverRawText(String text) {
if (packetReceiver == null)
return;
packetReceiver.processIncomingRaw(text);
}
/*
* (non-Javadoc)
*
* #see org.jivesoftware.openfire.Connection#getAddress()
*/
//#Override
public byte[] getAddress() throws UnknownHostException {
return InetAddress.getLocalHost().getAddress();
}
/*
* (non-Javadoc)
*
* #see org.jivesoftware.openfire.Connection#getHostAddress()
*/
//#Override
public String getHostAddress() throws UnknownHostException {
return InetAddress.getLocalHost().getHostAddress();
}
/*
* (non-Javadoc)
*
* #see org.jivesoftware.openfire.Connection#getHostName()
*/
//#Override
public String getHostName() throws UnknownHostException {
return InetAddress.getLocalHost().getHostName();
}
/**
* Get the bot's packet receiver
*
* #return BotzPacketReceiver packetReceiver
*/
public BotzPacketReceiver getPacketReceiver() {
return packetReceiver;
}
/**
* Get the resource portion of the bot's JID.
*
* #return Resource portion of the bot's JID.
*/
public String getResource() {
if (localClientSession == null)
return null;
return localClientSession.getAddress().getResource();
}
/**
* Get the node's portion of the bot's JID.
*
* #return Node portion of the bot's JID.
*/
public String getUsername() {
if (localClientSession == null)
return null;
return localClientSession.getAddress().getNode();
}
/**
* Get the node's portion of the bot's JID.
*
* #return Node portion of the bot's JID.
*/
public JID getIdentity() {
if (localClientSession == null)
return null;
return localClientSession.getAddress();
}
/**
* Check whether the bot session is still active.
*
* #return <tt>true</tt> if the bot is still active, <tt>false</tt>
* otherwise.
*/
public boolean isLoggedOn() {
return !isClosed();
}
/**
* Login to the XMPP server as an anonymous user. This method creates a
* virtual connection to the XMPP server and establish a user session. If
* the packet receiver is already defined, initialize it.
*
* #throws BotzSessionAlreadyExistsException
* If the users session already exists.
*/
public void login() throws BotzSessionAlreadyExistsException {
if (isClosed())
throw new BotzSessionAlreadyExistsException();
localClientSession = (LocalClientSession) SessionManager.getInstance().getSession(jid);
localClientSession.setAnonymousAuth();
if (packetReceiver != null) {
packetReceiver.initialize(this);
initPacketReceiver = true;
}
return;
}
/**
* A convenient way to login. It uses the default "Botz" as the JID resource
* and auto create the user if it doesn't exist.
*
* #param username
* The username to login with.
* #throws BotzSessionAlreadyExistsException
* If the bot's session already exists.
* #throws UserNotFoundException
* If it fails to create the user.
*
* #see #login(String, String, boolean)
*/
public void login(String username)
throws BotzSessionAlreadyExistsException, UserNotFoundException {
login(username, "Botz", true);
}
/**
* A convenient way to login. It auto create the user if it doesn't exist.
*
* #param username
* The username to login with.
* #param resource
* The resource the user will bind to.
* #throws BotzSessionAlreadyExistsException
* If the bot's session already exists.
* #throws UserNotFoundException
* If it fails to create the user.
*
* #see #login(String, String, boolean)
*/
public void login(String username, String resource)
throws BotzSessionAlreadyExistsException, UserNotFoundException {
login(username, resource, true);
}
/**
* Login to the XMPP server and establish a non-anonymous user session using
* the given username and resource. When <tt>createIfNotExist</tt> is
* <tt>true</tt>, a new user with the username will be created and stored
* in the database if it does not exist. When <tt>false</tt>, and the
* user does not exist, the method will not attempt the login. Whenever
* there's an error, the bot will not login.
*
* #param username
* Username to login with.
* #param resource
* The resource the user will bind to.
* #param createIfNotExist
* When specified as <tt>true</tt>, a new user will be created
* and stored in the database if it does not exist.
* #throws BotzSessionAlreadyExistsException
* If the bot's session already exists.
* #throws UserNotFoundException
* If it fails to create the user.
*/
public void login(String username, String resource, boolean createIfNotExist)
throws BotzSessionAlreadyExistsException, UserNotFoundException {
if (isClosed())
throw new BotzSessionAlreadyExistsException();
jid = new JID(username.toLowerCase(), XMPPServer.getInstance().getServerInfo().getXMPPDomain(), resource);
ClientSession oldSession = XMPPServer.getInstance().getRoutingTable()
.getClientRoute(jid);
// Check for session conflict
if (oldSession != null) {
try {
oldSession.incrementConflictCount();
int conflictLimit = SessionManager.getInstance()
.getConflictKickLimit();
if (conflictLimit != SessionManager.NEVER_KICK) {
// Kick out the old connection that is conflicting with the
// new one
StreamError error = new StreamError(
StreamError.Condition.conflict);
oldSession.deliverRawText(error.toXML());
oldSession.close();
} else
throw new BotzSessionAlreadyExistsException();
} catch (Exception e) {
Log.error("Error during login", e);
}
}
if (!XMPPServer.getInstance().getUserManager().isRegisteredUser(
jid.getNode())) {
if (createIfNotExist) {
try {
// Bot doesn't care of whatever password it is.
XMPPServer.getInstance().getUserManager().createUser(
jid.getNode(), StringUtils.randomString(15), null,
null);
} catch (UserAlreadyExistsException e) {
// Ignore
}
} else {
throw new UserNotFoundException();
}
}
localClientSession = (LocalClientSession) SessionManager.getInstance().getSession(jid);
localClientSession.setAuthToken(new AuthToken(jid.getNode()), jid
.getResource());
if (packetReceiver != null) {
packetReceiver.initialize(this);
initPacketReceiver = true;
}
this.roster = XMPPServer.getInstance().getRosterManager().getRoster(username);
}
/**
* Logout the bot and destroy the active session. This method need not be
* called explicitly unless, for example, when callers need to refresh the
* assign a different username or resource (re-login).
*/
public void logout() {
close();
}
/**
* Send a packet out to an XMPP entity. The packet must be one of
* <message/>, <iq/> or <presence/>. Callers need not specify the
* <tt>from</tt> attribute inside the packet because it will be
* automatically inserted with/replaced by the bot's real JID.
*
* #param packet
* The packet to send.
*/
public void sendPacket(Packet packet) {
if (isClosed())
throw new IllegalStateException("No valid session");
SessionPacketRouter router = new SessionPacketRouter(localClientSession);
router.route(packet);
}
/**
* Assign a packet receiver ({#link BotzPacketReceiver}) object that will
* receive packets to the bot. The method can be called repeatedly if
* necessary to dynamically change different packet receivers during a
* login. If the previous packet receiver is in an initialized state during
* this call, it will be terminated; and the new packet receiver will be
* initialized.
*
* <p>
* If the previous packetReceiver is the same with the new one, this method
* will ignore the assignment.
*
* #param packetReceiver
* The packetReceiver object
*/
public void setPacketReceiver(BotzPacketReceiver packetReceiver) {
if (this.packetReceiver == packetReceiver)
return;
if (this.packetReceiver != null && initPacketReceiver) {
this.packetReceiver.terminate();
initPacketReceiver = false;
}
this.packetReceiver = packetReceiver;
if (!isClosed()) {
this.packetReceiver.initialize(this);
initPacketReceiver = true;
}
}
/**
* Calls to this method is made by the server to notify about server
* shutdown to the bot.
*/
public void systemShutdown() {
close();
}
#
Override
public ConnectionConfiguration getConfiguration() {
// TODO Auto-generated method stub
return null;
}
}
Can any one please help me out as i am newb in openfire.
I think bot has not been customized for newer versions as you can see in trailing last posts in that discussions that it doesn't work for anyone.But you can always use smack api to create your own bot.
Create a bot id.
Create a Java App and connect to Openfire using Smack
Use a business logic once you receive the chats and reply to the same.
I have a pause mechanism for my events(Runnable) but I am not sure how to use/call it when I need it to be called.
In my class, I have a run method that submits an arraylist full of events to an executor. (see run() on GreenhouseControls). When the Events are submitted, Thread.sleep(eventTime); is called and afterwards the action() inside the event is called.
My program requirement needs a mechanism that pauses all the threads with a method(which will be called by a method when clicked) which can be resumed later on with another button.
Does anyone know how to implement this mechanism?
Here are the files:
GreenhouseControls.java
package control;
/**
* In this exercise we take a different design approach to GreenhouseControls
*
* Compiled/Tested using Eclipse Version: Luna Release (4.4.0)
* TME4 Folder is located in C:\COMP 308\
*/
import java.io.*;
import java.util.regex.*;
import java.util.logging.*;
import java.util.*;
import java.util.concurrent.*;
import java.lang.reflect.*;
import tme4.*;
/**
* GreenhouseControls consists of the Greenhouse's status and methods that
* control what actions will be performed inside the Greenhouse.
* #author Ray Masiclat
*
*/
public class GreenhouseControls extends Controller implements Serializable{
/**
* status is a Set of StatusPair objects which contains information about the
* GreenhouseControls' status. The Default States are initialized in the default constructor.
*/
private Set<StatusPair> status = new HashSet<StatusPair>();
private static String file = "src/error.log";
/**
* Default Constructor - initializes each state of the Greenhouse
*
*/
public GreenhouseControls(){
status.add(new StatusPair<String, Boolean>("light", false));
status.add(new StatusPair<String, Boolean>("water", false));
status.add(new StatusPair<String, Boolean>("fans", false));
status.add(new StatusPair<String, Boolean>("windowok", true));
status.add(new StatusPair<String, Boolean>("poweron", true));
status.add(new StatusPair<String, String>("thermostat", "Day"));
status.add(new StatusPair<String, Integer>("errorcode", 0));
status = Collections.synchronizedSet(status);
}
/**
* Prints out in the console how to use the program.
*/
public static void printUsage() {
System.out.println("Correct format: ");
System.out.println(" java GreenhouseControls -f <filename>, or");
System.out.println(" java GreenhouseControls -d dump.out");
}
/**
* Takes in an errorcode and returns the appropriate Fix that will fix the
* error that occured in the past.
* #param errorcode
* #return fix
*/
public Fixable getFixable(int errorcode){
Fixable fix = null;
switch(errorcode){
case 1:
fix = new FixWindow(this);
break;
case 2:
fix = new PowerOn(this);
break;
default:
System.out.println("No Error");
break;
}
return fix;
}
/**
* shutdown - method creates a Logger that creates an error log which consists of information about the
* reason of why the program was shut down. After logging the error information, it serializes
* the current state of the program in order for it to be fixed/restored in the future.
* #throws IOException
*/
public void shutdown() throws IOException{
System.err.println("System Shutting Down");
Logger logger = Logger.getLogger("ControllerException");
FileHandler fh;
try {
fh = new FileHandler("src/error.log");
logger.addHandler(fh);
SimpleFormatter formatter = new SimpleFormatter();
fh.setFormatter(formatter);
} catch (SecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Check for errorcode using getError method.
int checkError = this.getError();
if(checkError == 1){
logger.info("Window Malfunction");
} else if (checkError == 2){
logger.info("Power Outage");
} else {
logger.info("No Error");
}
/**
* Serialize the current state and output it onto the src/ directory as dump.out
*/
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("src/dump.out"));
out.writeObject(this);
out.writeObject(getEventList());
out.close();
System.exit(0);
}
/**
* getStatus - returns the status Set which consists of information about the current state of the program.
* #return status
*/
public Set<StatusPair> getStatus(){
return status;
}
/**
* getError - Assigns an integer which will be used when logging the error.
* The errorNum is retrieved using the status Set
* #return errorNum
*/
public int getError(){
int errorNum = 0;
//Iterate through the status Set
for(StatusPair sp : status){
//Check for the name "errorcode" and initializes errorNum from its status
if(sp.getName().equals("errorcode")){
errorNum = (int) sp.getStatus();
}
}
return errorNum;
}
/**
* getEventList - returns a List of Events in the program.
* #return eventList
*/
public List<Event> getEventList(){
return eventList;
}
/**
* Create a method in GreenhouseControls called setVariable to
* handle updating to this collection. Use the synchronization feature
* in java to ensure that two Event classes are not trying to add to
* the structure at the same time.
* s - represents the name of the status
* o - represents the status it is going to be replaced with
* #param s
* #param o
*/
public void setVariable(String s, Object o){
for(StatusPair sp : getStatus()){
if(sp.getName().equals(s))
{
sp.setStatus(o);
}
}
}
/**
* addStatus - Adds a new status in the status Set and it is used
* if the program cannot find a name in the status Set.
* #param name
* #param status
*/
public void addStatus(String name, Object status){
getStatus().add(new StatusPair<String, Object>(name,status));
}
/**
* run - creates a thread array which will be used to run Events from
* the text file. Then a for loop is created to fill up the thread
* array with Events on each index. Then the thread is started once
* an index is initialized. After an event is added in to the thread
* array it is removed from the events list.
*/
public void run(){
ExecutorService exec = Executors.newCachedThreadPool();
if(eventList.size() == 1){
exec.submit(eventList.get(0));
eventList.remove(eventList.get(0));
} else {
for(Event e : eventList){
exec.submit(e);
}
}
exec.shutdown();
/*while(eventList.size() > 0){
for(int i = 0; i < eventList.size(); i++){
exec.submit(eventList.get(i));
}
}*/
/*Thread[] threads = new Thread[eventList.size()];
while(eventList.size() > 0)
for(int i = 0; i < eventList.size(); i++){
threads[i] = new Thread(eventList.get(i));
threads[i].start();
eventList.remove(i);
}*/
}
} ///:~
Event.java
/**
* Make Event implements Runnable so that each type of event provides
* its own timing. Each event file should be a class of its own. Change
* the rest of the design to simplify this model.
*
* Assignment: TME4
* #author Ray Masiclat
* #studentid 3231308
* #date July 27, 2015
*
*
* Compiled/Tested using Eclipse Version: Luna Release (4.4.0)
* TME4 Folder is located in C:\COMP 308\
*/
package tme4;
import java.io.*;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import gui.*;
import control.*;
/**
* Event class that implements Runnable and Serializable
* #author Ray Masiclat
*
*/
public abstract class Event implements Runnable, Serializable{
/**
* eventTime - represents time it takes for the program to wait and then
* call its action method.
*/
protected long eventTime;
protected GreenhouseControls gcontrol;
protected boolean suspended = false;
/**
* Event class constructor which is used to initialize the Event's eventTime and
* GreenhouseControls object which is used for the Event to have access to its status
* variables.
* #param gc
* #param eventTime
*/
public Event(GreenhouseControls gc,long eventTime){
this.eventTime = eventTime;
this.gcontrol = gc;
}
/**
* getTime - returns the event's eventTime initialized from the constructor.
* #return eventTime
*/
public long getTime(){
return eventTime;
}
/**
* setTime - sets the eventTime
*/
public void setTime(long eventTime){
this.eventTime = eventTime;
}
/**
* run - Event class' run method is called when the Event is added in to the Thread
* and then "started". This method puts the Thread to sleep for however long the
* eventTime is. Afterwards, once it is done, it tries to run the Event's action
* method. If the action method throws an error, it is caught by the try-catch
* block which calls the GreenhouseControls object's shutdown which outputs an error.log
* file and serializes the current state of the GreenhouseControls object to a dump.out file.
*/
public void run(){
try {
synchronized(this){
while(suspended){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Thread.sleep(eventTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
this.action();
} catch (ControllerException e) {
//Use shutdown to create error log
try {
gcontrol.shutdown();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
}
public void suspend(){
suspended = true;
}
public synchronized void resume(){
suspended = false;
notify();
}
/**
* abstract method used to call an Event's action method in the run method.
* #throws ControllerException
*/
public abstract void action() throws ControllerException;
} ///:~
(Pastebin: GreenhouseControls.java
and Event.java)
Something like this:
boolean stop = false;
You can use a suspending/stopping object, like so
public class Stopping {
public synchronized void checkStop() {
if (stopped) {
wait(); // wait until stop has been cleared
}
}
public synchronized void setStop(boolean val) {
stop = val;
if (val) {
notifyAll();
}
}
}
Create one of these and share it with all your threads, making sure to call checkStop() frequently. Alternatively, you could make the methods in this class static, and then your threads wouldn't need an object reference - they could just call Stopping.checkStop();
In my program, I am trying to get the last modified date for some items in my box folders, but I am unable to access that information.
According to the documentation for the box API and the javadoc for the java library, any of the following methods of BoxTypedObject should return the information I want:
getModifiedAt() should return a String in ISO 8601 format for the date.
getModifiedDate() should return a Date object for the date.
getValue("modified_at") should also return a String in ISO 8601 format for the date.
getExtraData("modified_at") is also a possible way, although I am not as sure of this one.
However, none of those methods has worked for me; they all just returh null.
The (vastly simplified) code that I am using to retrieve the dates is as follows, with one of the above methods substituted for the comment block:
private static void printAll(BoxFolder boxFolder){
for(BoxTypedObject file : boxFolder.getItemCollection().getEntries())
System.out.printf("[\"%1$s\" %2$s]%n",
file.getValue("name"), file./*[???]*/);
}
The other fields all return the correct values, only when I try to get the date does it fail on me.
How do I retrieve the modified date for the BoxTypedObjects?
EDIT: I have figured out one way to get it, but it is somewhat slow.
client.getFilesManager().getFile(file.getId(), null).getModifiedAt()
retrieves the date. I am still interested if there is a better way to do it, though.
Additional information (may or may not be relevant to the problem):
The authentication of the box client is handled by the following class:
import java.awt.Desktop;
import java.io.*;
import java.net.*;
import com.box.boxjavalibv2.BoxClient;
import com.box.boxjavalibv2.dao.BoxOAuthToken;
import com.box.boxjavalibv2.exceptions.*;
import com.box.boxjavalibv2.requests.requestobjects.BoxOAuthRequestObject;
import com.box.restclientv2.exceptions.BoxRestException;
/**
* This class handles the storage and use of authentication keys, to
* simplify the process of obtaining n authenticated client. This class
* will store refresh keys in a file, so that it can authenticate a client
* without needing for user intervention.
* <p>
* Copyright 2013 Mallick Mechanical, Inc.
*
* #author Anson Mansfield
*/
public class Authenticator {
/**
* Constructs an {#code Authenticator} for use obtaining
* authenticated {#Code BoxClient}s
*
* #param key The OAuth client id and application key.
* #param secret The OAuth client secret.
* #param authFile The file to be used for storing authentications
* for later use.
*/
public Authenticator(String key, String secret, File authFile){
this.key = key;
this.secret = secret;
this.authFile = authFile;
}
/**
* Constructs a new {#Code BoxClient} object, authenticates it,
* and returns it.
*/
public BoxClient getAuthenticatedClient(){
BoxClient client = new BoxClient(key,secret);
client.authenticate(getToken(client));
return client;
}
public final String host = "http://localhost";
public final int port = 4000;
public final String key, secret;
public final File authFile;
public final String url = "https://www.box.com/api/oauth2/authorize?response_type=code&client_id=";
/**
* Obtains a token that can be used to authenticate the box client,
* and stores its refresh value in a file, so it can be used later.
* #param client The client to obtain a token for.
* #return A token that can be used to authenticate the client, or
* {#code null} if one could not be obtained.
*/
private BoxOAuthToken getToken(BoxClient client){
BoxOAuthToken token = null;
try{
if((token = getOldToken(client)) != null) return token;
if((token = getNewToken(client)) != null) return token;
return token;
}finally{
writeNewToken(token);
}
}
/**
* Attempts to write a token's refresh token to a file.
* #param token The token whose refresh value is to be written.
*/
private void writeNewToken(BoxOAuthToken token) {
if(token != null)
try(BufferedWriter out = new BufferedWriter(new FileWriter(authFile))){
out.write(token.getRefreshToken());
}catch(IOException ex){
System.out.println("couldn't update new token");
}
}
/**
* Reads the last session's refresh token from a file and attempts
* to get a new authentication token with it.
* #param client The client for which the authentication token is for.
* #return The token obtained from the refresh, or {#code null} if one
* could not be obtained.
*/
private BoxOAuthToken getOldToken(BoxClient client) {
System.out.println("attempting to use old token");
BoxOAuthToken token = null;
try(BufferedReader in = new BufferedReader(new FileReader(authFile))){
token = client.getOAuthManager().refreshOAuth(
BoxOAuthRequestObject.refreshOAuthRequestObject(
in.readLine(), key, secret
));
System.out.println("refreshed old token");
}catch(IOException ex){
System.out.println("couldn't read old token");
} catch(BoxRestException | BoxServerException | AuthFatalFailureException ex){
System.out.println("couldn't refresh old token");
}
return token;
}
/**
* Connects to the OAuth server and gets a new authentication token.
* #param client The client to get a token for.
* #return The new token obtained from the server, or {#code null} if one could not be obtained.
*/
private BoxOAuthToken getNewToken(BoxClient client) {
System.out.println("attempting to get new token");
BoxOAuthToken token = null;
try {
Desktop.getDesktop().browse(java.net.URI.create(url + key));
token = client.getOAuthManager().createOAuth(
BoxOAuthRequestObject.createOAuthRequestObject(getCode(), key, secret, host + port)
);
} catch (BoxRestException | BoxServerException | AuthFatalFailureException | IOException ex) {
ex.printStackTrace();
return null;
}
return token;
}
/**
* This listens on the configured port for the code included in the callback.
* It also deploys a script on the receiving socket to close the browser tab navigating to it.
* #return The authentication code to generate a token with.
*/
private String getCode(){
try (ServerSocket serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());){
out.println("<script type=\"text/javascript\">");
out.println( "window.open('', '_self', '');");
out.println( "window.close();");
out.println("</script>"); //Close the tab
while (true){
String code = "";
code = in.readLine ();
System.out.println(code);
String match = "code";
int loc = code.indexOf(match);
if( loc >0 ) {
int httpstr = code.indexOf("HTTP")-1;
code = code.substring(code.indexOf(match), httpstr);
String parts[] = code.split("=");
code=parts[1];
return code;
} else {
// It doesn't have a code
}
}
} catch (IOException | NullPointerException e) {
return "";
}
}
}
The actual class that will be getting the modified field (not yet finished, though):
import java.io.File;
import java.util.Scanner;
import com.box.boxjavalibv2.BoxClient;
import com.box.boxjavalibv2.dao.BoxFolder;
import com.box.boxjavalibv2.dao.BoxTypedObject;
/**
* Copyright 2013 Mallick Mechanical, Inc.
*
* #author Anson Mansfield
*/
public class BoxStuff {
static BoxClient client;
public void main(String ... args) throws Exception {
client = new Authenticator(args[0], args[1], new File(args[2]))
.getAuthenticatedClient();
userSelectFolder("Select the project folder");
}
private static BoxFolder userSelectFolder(String prompt) throws Exception{
Scanner kbd;
if(System.console()!=null)
kbd = new Scanner(System.console().reader());
else
kbd = new Scanner(System.in);
String line = "";
System.out.println();
System.out.println(prompt);
System.out.println("(leave prompt blank to select folder)");
BoxFolder current = client.getFoldersManager().getFolder("0", null);
printAll(current);
System.out.print("select>");
while(!(line = kbd.nextLine()).isEmpty()){
BoxFolder next = select(current, Integer.parseInt(line));
if(next != null) current = next;
printAll(current);
System.out.print("select>");
}
return current;
}
private static void printAll(BoxFolder boxFolder){
int idx=0;
System.out.println(" 0:[parent folder]");
for(BoxTypedObject file : boxFolder
.getItemCollection()
.getEntries()){
if(file.getType().equals("folder")){
System.out.printf("%1$3d:[%2$-32s %3$-6s %4$-9s]%n",
++idx, format((String) file.getValue("name"),30), file.getType(), file.getId());
} else {
System.out.printf(" [%1$-32s %2$-6s %3$-9s Edit:%4$s]%n",
format((String) file.getValue("name"),32), file.getType(), file.getId(), file.getExtraData("modified_at"));
}
}
}
private static String format(CharSequence source, int length){
StringBuilder b = new StringBuilder(length);
b.append('"');
if(source.length() > 30)
b.append(source.subSequence(0, 29)).append('~');
else
b.append(String.format("%1$-30s",source));
b.append('"');
return b.toString();
}
private static BoxFolder select(BoxFolder boxFolder, int i) throws Exception{
int idx=0;
for(BoxTypedObject file : boxFolder.getItemCollection().getEntries()){
if(file.getType().equals("folder") && ++idx == i){
return client.getFoldersManager().getFolder(file.getId(), null);
}
}
if(idx==0){
if(boxFolder.getParent() == null)
return client.getFoldersManager().getFolder("0", null);
else
return client.getFoldersManager().getFolder(boxFolder.getParent().getId(), null);
}else{
System.out.println("Selection is out of range!");
return boxFolder;
}
}
}
If anyone else wants to use these classes for something, just ask me. It is probably OK (they are a mechanical contractor, not a software company), I just need to clear it with my boss (This code does still belong to the company).
This is actually a little tricky. The api call to get folder items by default only return children items with some default fields, they don't include fields like modified_at. However if you supply extra fields parameters you should be able to get them.
Here is what you can do when using the getFolderItems method(this is also in the readme in github):
BoxFolderRequestObject requestObj =
BoxFolderRequestObject.getFolderItemsRequestObject(30, 20)
.addField(BoxFolder.FIELD_NAME)
.addField(BoxFolder.FIELD_MODIFIED_AT);
BoxCollection collection =
boxClient.getFoldersManager().getFolderItems(folderId, requestObj);
There is another tricky thing here though, after you supply these fields, the result children items will only contain the supplied fields(plus some basic fields), so make sure you add all the fields you want.
Here is one way I figured out to get it (that actually works):
client.getFilesManager().getFile(file.getId(), null).getModifiedAt()
This, however, is somewhat slow, so I would greatly appreciate it if someone else knows a faster solution.