File sharing with my chat RMI program - chat

I have been doing a RMI chat system on school and wanted some sort of file sharing with it. Have not done something like this before and have not been through this at school, but I wanted to try. Have done some searching on google and this
http://java.sun.com/developer/technicalArticles/RMI/rmi_corba/
was the best i found. Is this "technology" new so i can use it? Did not get it to work, but that can be my lack of Java knowledge.
Some tips why i don't get it to work?

There isn't a tremendous difference between sending messages back and forth and sending files. The answer depends largely on what your current code looks like. Do you have some code to share?
What does your current RMI interface look like? What does your architecture look like?
Do you have a server that clients connect to?
Do you have a method sendChat(String message)?
With respect to having sendChat(), you could probably add a sendFile( ... ). Then the question is just what you want to do for the parameters.
Do you want to send a java.io.File object? A byte[] (along with a String name, maybe a boolean flag to distinguish binary files)?
Seeing that this is your first time doing this, you might want to code the mundane parts yourself. However, tasks like obtaining bytes from a file are rather common annoyances. The Apache commons and Google guava libraries both provide methods to simplify the process. I suppose it depends on the learning goals you have on this project.

Yes. The clients connects to the server, and are able to chat in chatrooms.
Here is some of the code we have until now, except the file for connecting and communication with the database, and the GUI. Thanks for answering.
Interfaces:
Chatfront interface:
public interface ChatFront extends Remote {
boolean registerClient(Client client, String password) throws RemoteException;
void logMeOut(Client client) throws RemoteException;
void newChannelMessage(String toChannel, String fromUser, String message) throws RemoteException;
void newPrivateMessage(String fromUser, String toUser, String message) throws RemoteException;
String connectChannel(String username, String channel) throws RemoteException;
String disconnectChannel(String username, String channel) throws RemoteException;
boolean isUserRegistered(String username) throws RemoteException;
void errorMessage(String toUser, String message) throws RemoteException;
}
Clientinterface:
public interface Client extends Remote {
String findName() throws RemoteException;
void newPrivateMessage(String fromUser, String toUser, String message) throws RemoteException;
void newMessageChannel(String toChannel, String fromUser, String message) throws RemoteException;
void newSystemMessageChannel(String toChannel, String fromUser, String message) throws RemoteException;
void errorMessage(String toUser, String message) throws RemoteException;
}
Serverside:
class ChatServer {
public static void main(String[] args) throws Exception {
String objectname = "chatter";
LocateRegistry.createRegistry(1099);
ChatFront cf = new ChatFrontImpl();
Naming.rebind(objectname, cf);
javax.swing.JOptionPane.showMessageDialog(null, "Tjener kjører. Trykk OK for å avslutte tjeneren.");
Naming.unbind(objectname);
System.exit(0);
}
}
ChatFrontImpl.java
package server;
import Interfaces.ChatFront;
import Interfaces.Client;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
/**
*
* #author sindre
*/
class ChatFrontImpl extends UnicastRemoteObject implements ChatFront {
private UserDAC u = new UserDAC();
private Hashtable<String, ArrayList<String>> channels = new Hashtable<String, ArrayList<String>>();
private ArrayList<Client> clients = new ArrayList<Client>();
public ChatFrontImpl() throws RemoteException {
}
/* Registrerer en ny client */
#Override
public synchronized boolean registerClient(Client client, String password) throws RemoteException {
if(!u.logIn(client.findName(), password)){
System.out.println("feil username eller password");
return false;
}
if (!clients.contains(client)) {
try {
clients.add(client);
System.out.println("Na er " + client.findName() + " registrert.");
} catch (Exception e){
System.out.println("Feil oppstatt i registrerMeg(): " + e);
}
return true;
} else
return false;
}
/* Kobler en client til en kanal */
#Override
public String connectChannel(String username, String kanal) throws RemoteException{
if(isUserRegistered(username)){
if (!channels.containsKey(kanal)) {
String message = "Bruker " + username + " har ankommet kanalen";
channels.put(kanal, new ArrayList<String>());
channels.get(kanal).add(username);
notifyChannelSystem(kanal, "SYSTEM", message);
notifySelf(username, "Skriv /? for mulige kommandoer");
return("Kanal opprettet, og bruker satt i kanalen.");
}
else{
if(channels.get(kanal).contains(username)){
return ("Brukeren er allerede i kanalen.");
} else {
channels.get(kanal).add(username);
String message = "Bruker " + username + " har ankommet kanalen";
notifyChannelSystem(kanal, "SYSTEM", message);
return ("Kanal fantes allerede. Bruker satt i kanalen.");
}
}
}
return "";
}
/*Sjekker om brukeren ikke er blank.*/
#Override
public boolean isUserRegistered(String username){
if(username.equals("")){
return false;
}
return true;
}
/* Kobler en bruker fra en kanal */
#Override
public String disconnectChannel(String username, String channel) throws RemoteException{
if(isUserInChannelX(username, channel)){
channels.get(channel).remove(username);
String message = "Bruker " + username + " har forlatt kanalen.";
notifySelf(username, " Du har nå forlatt kanalen " + channel);
notifyChannelSystem(channel, "SYSTEM", message);
if(channels.get(channel).isEmpty()){
channels.remove(channel);
}
}
return ("Bruker har forlatt kanalen.");
}
/* Kobler en client fra clientlisten */
#Override
public synchronized void logMeOut(Client client) throws RemoteException {
boolean isfound = false;
int clientIndeks = 0;
while (clientIndeks < clients.size() && !isfound) {
Client denne = clients.get(clientIndeks);
if (denne.equals(client)) { // bruker equals() for a sammenlikne stubbobjektene
isfound = true;
clients.remove(clientIndeks);
System.out.println("Na er clienten " + client.findName() + " fjernet.");
} else clientIndeks++;
}
}
/* Sjekker om brukeren finnes i en gitt kanal */
public boolean isUserInChannelX(String bruker, String kanal){
if(channels.containsKey(kanal) && channels.get(kanal).contains(bruker)){
return true;
} else {
return false;
}
}
/* Kaller metoden varsleKanal()*/
#Override
public void newChannelMessage(String tilKanal, String fraBruker, String message) throws RemoteException{
if(isUserInChannelX(fraBruker, tilKanal)){
notifyChannel(tilKanal, fraBruker, message);
}
else{
}
}
/* Kaller metoden varsleEn() */
#Override
public void newPrivateMessage(String fra, String toUser, String message) throws RemoteException{
notifyUser(fra,toUser,message);
}
#Override
public void errorMessage(String toUser, String message) throws RemoteException{
notifySelf(toUser, message);
}
private void notifySelf(String toUser, String message) throws RemoteException{
for(Client k: clients){
if(k.findName().equals(toUser)){
k.errorMessage(toUser, message);
}
}
}
/* Bruker metoden nymessagePrivat() + ser om brukeren er tilkoblet*/
private void notifyUser(String fromUser, String toUser, String message) throws RemoteException{
boolean funnet = false;
for(Client k : clients){
if(k.findName().equals(toUser)){
k.newPrivateMessage(fromUser, toUser, message);
funnet = true;
}
}
if (!funnet) errorMessage(fromUser, "Ingen brukere ved dette navnet!");
}
/* Kjører metoden nymessageKanal() */
private void notifyChannel(String toChannel, String fromUser, String message) throws RemoteException{
if(channels.containsKey(toChannel) && isUserRegistered(fromUser)){
for(String k : channels.get(toChannel)){
for(Client cli : clients){
if(cli.findName().equals(k)){
cli.newMessageChannel(toChannel, fromUser, message);
}
}
}
}
else{
System.out.println("Brukeren er ikke registrert.");
}
}
private void notifyChannelSystem(String toChannel, String fromUser, String message) throws RemoteException{
if(channels.containsKey(toChannel) && isUserRegistered(fromUser)){
for(String k : channels.get(toChannel)){
for(Client kli : clients){
if(kli.findName().equals(k)){
kli.newMessageChannel(toChannel, fromUser, message);
}
}
}
}
else{
System.out.println("Brukeren er ikke registrert.");
}
}
}
Clientside:
GUILogic.java
package gui;
import Interfaces.ChatFront;
import Interfaces.Client;
import java.rmi.Naming;
import java.rmi.RemoteException;
import klient.ClientImpl;
/**
*
* #author sindre
*/
public class GUILogic {
GUI gui;
ChatFront cf;
public String username;
public String channel;
public String password;
public String message;
public GUILogic(GUI gui){
this.gui = gui;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
/* Kobler GUI klienten opp mot serveren */
public void createCFConnection(String username, String password) throws Exception{
String objectname = "chatter";
String hostname = "localhost";
String url = "rmi://" + hostname + "/" + objectname;
cf = (ChatFront) Naming.lookup(url);
Client k = new ClientImpl(username, gui);
cf.registerClient(k, password);
}
public void connectChannel(String username, String channel) throws RemoteException{
cf.connectChannel(username, channel);
}
public void disconnectChannel(String username, String channel) throws RemoteException{
cf.disconnectChannel(username, channel);
}
public void newChannelMessage(String toChannel, String fromUser, String message) throws RemoteException{
cf.newChannelMessage(fromUser ,toChannel, message);
}
public void newPrivateMessage(String fromUser, String toUser, String message) throws RemoteException{
cf.newPrivateMessage(fromUser, toUser, message);
}
public void errorMessage(String toUser, String message) throws RemoteException{
cf.errorMessage(toUser, message);
}
/* Logger klienten av GUIen */
public boolean logOut(String username) throws RemoteException{
Client k = new ClientImpl(username, gui);
if(k.findName().equals("")){
return false;
} else {
cf.logMeOut(k);
System.out.println("user " + username + " logget ut.");
return true;
}
}
/* Analysermessage har funnet / i starten av messageen, og da blir denne metoden kjørt. */
public String commandWritten(String username, String channel, String message) throws RemoteException{
String[] result = message.split(" ", 3);
String channel1;
if((result[0].equalsIgnoreCase("/join") || (result[0].equalsIgnoreCase("/j")))){
channel1 = result[1];
setChannel(channel1);
connectChannel(username, channel1);
}
else if(result[0].equalsIgnoreCase("/leave") || (result[0].equalsIgnoreCase(("/l")))){
channel = result[1];
disconnectChannel(username, channel);
}
else if(result[0].equalsIgnoreCase("/whisper") || (result[0].equalsIgnoreCase(("/w")))){
for (int x=2; x<result.length; x++)
newPrivateMessage(username, result[1], result[x]);
}
else if(result[0].equalsIgnoreCase("/exit") || (result[0].equalsIgnoreCase(("/e")))){
System.exit(0);
}
else if(result[0].equalsIgnoreCase("/?")){
errorMessage(username, "Mulige kommandoer er:" + "\n" +
"/leave 'channel' eller /l" + "\n" +
"/whisper 'username' eller /w" + "\n" +
"/join 'channel' eller /j" + "\n" +
"/exit eller /e" + "\n");
}
else{
errorMessage(username, "Feil kommando! Skriv /? for mulige kommandoer");
}
return message;
}
/* Analyserer messageen som skrives inn i messagefeltet. Kommandoer starter med / */
public void analyzeMessage(String username, String channel, String message) throws RemoteException{
String text = getMessage().toLowerCase();
char command = '/';
for(int i = 0; i<1; i++){
char c = text.charAt(0);
if(c == command){
commandWritten(username, channel, text);
}
else {
newChannelMessage(username, channel, text);
}
}
}
}

Related

Postman not returning a table

I am working on a web dev project right now using netbeans 8.2 + glassfish 4.1
My code seems to be good since it is not showing any type of errors. However, when I try to run it and I paste the code in google postman my response look like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<clubss></clubss>
Just to make sure, my project is on football teams. I currently have a table with 3 team only, just to keep it short. A weird thing that I noticed is the last line - "clubss". I searched through my code and could not find the word "clubss" anywhere - I do have loats of "club" + "clubs" but nowhere a "clubss".
However, most important thing to me at the moment is to get the whole thing running and to display the 3 teams in postman.
If you require any code just let me know. I did not paste them in in the first place because
a) it might turned out it is not needed
b) they are fairly long and it would make the post look bad.
However if you do need it I will update it immediately.
Thanks in advance, any help appreciated. UPDATE
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlRootElement(name="clubs")
// define the field order
#XmlType(propOrder={"id", "name", "year", "country", "league",
"picture", "description"})
public class Clubs {
private int id;
private String name, year, country, league, picture, description;
// JAXB requires a default ctor
public Clubs(){
}
public Clubs(int id, String name, String year, String country, String league, String picture, String description) {
this.id = id;
this.name = name;
this.country = country;
this.year = year;
this.league = league;
this.picture = picture;
this.description = description;
}
#XmlElement
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#XmlElement
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElement
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
#XmlElement
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
#XmlElement
public String getLeague() {
return league;
}
public void setLeague(String league) {
this.league = league;
}
#XmlElement
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
#XmlElement
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Override
public String toString() {
return "Clubs{" + "id=" + id + ", name=" + name + ", country=" + country + ", league=" + league + ", year=" + year + ", picture=" + picture + ", description=" + description + '}';
}
}
package dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ClubsDAO {
private Connection con = null;
public static void main(String[] args) {
ClubsDAO dao = new ClubsDAO();
int nextId = dao.getNextClubId();
System.out.println(nextId);
}
public ClubsDAO() {
try {
Class.forName("org.apache.derby.jdbc.ClientDriver");
con = DriverManager.getConnection(
"jdbc:derby://localhost:1527/CD_WD3_DB",
"sean", "sean");
System.out.println("OK");
} catch (ClassNotFoundException ex) {
//Logger.getLogger(ClubsDAO.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("ClassNotFoundException");
ex.printStackTrace();
} catch (SQLException ex) {
//Logger.getLogger(ClubsDAO.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("SQLException");
ex.printStackTrace();
}
}
public int updateClubs(Clubs clubs){
int rowsUpdated=0;
try{
PreparedStatement ps = con.prepareStatement(
"UPDATE APP.CLUB SET NAME=?, YR=?, COUNTRY=?,"
+ "LEAGUE=?, DESCRIPTION=?, PICTURE=? WHERE "
+ "ID = ?");
ps.setString(1, clubs.getName());
ps.setString(2, clubs.getYear());
ps.setString(4, clubs.getCountry());
ps.setString(5, clubs.getLeague());
ps.setString(6, clubs.getDescription());
ps.setString(7, clubs.getPicture());
ps.setInt(8, clubs.getId());
rowsUpdated = ps.executeUpdate();
}catch (Exception e){
System.err.println("Exception in executeUpdate()");
e.printStackTrace();
return -1;
}
return rowsUpdated;// 1
}
public int addClubs(Clubs clubs){
int numRowsInserted=0;
try{
PreparedStatement ps = con.prepareStatement(
"INSERT INTO APP.CLUB " // CLUBS??
+ "(ID, NAME, YR, COUNTRY, "
+ "LEAGUE, DESCRIPTION, PICTURE) "
+ "VALUES (?,?,?,?,?,?,?)");
ps.setString(1, clubs.getName());
ps.setString(2, clubs.getYear());
ps.setString(4, clubs.getCountry());
ps.setString(5, clubs.getLeague());
ps.setString(6, clubs.getDescription());
ps.setString(7, clubs.getPicture());
ps.setInt(8, clubs.getId());
numRowsInserted = ps.executeUpdate();
}catch (Exception e){
e.printStackTrace();
return -1;
}
return numRowsInserted;
}
public int getNextClubId(){
int nextClubId = -1;
try{
PreparedStatement ps =
con.prepareStatement(
"SELECT MAX(ID) AS MAX_ID FROM APP.CLUB");
ResultSet rs = ps.executeQuery();
if(!rs.next()){ // set the db cursor
return -1;
}
nextClubId = rs.getInt("MAX_ID") + 1;
}catch(Exception e){
e.printStackTrace();
return -1;
}
return nextClubId;
}
public List<Clubs> findAll() {
List<Clubs> list
= new ArrayList<>();
try {
PreparedStatement pstmt
= con.prepareStatement("SELECT * FROM APP.CLUB ORDER BY ID");
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
list.add(processRow(rs));
}
} catch (SQLException ex) {
//Logger.getLogger(ClubsDAO.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("SQLException");
ex.printStackTrace();
}
return list;
}
public Clubs processRow(ResultSet rs) throws SQLException {
Clubs clubs = new Clubs();
clubs.setId(rs.getInt("id"));
clubs.setName(rs.getString("name"));
clubs.setCountry(rs.getString("country"));
clubs.setLeague(rs.getString("league"));
clubs.setYear(rs.getString("yr"));
clubs.setPicture(rs.getString("picture"));
clubs.setDescription(rs.getString("description"));
return clubs;
}
public Clubs findById(int clubId) {
Clubs club = null;
try {
PreparedStatement pstmt
= con.prepareStatement("SELECT * FROM APP.CLUB WHERE ID=?");
pstmt.setInt(1, clubId);
ResultSet rs = pstmt.executeQuery();
if (!rs.next()) { // !F => T
return null;
}
// we have a record
club = processRow(rs);
} catch (SQLException ex) {
//Logger.getLogger(ClubDAO.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("SQLException");
ex.printStackTrace();
}
return club;
}
public List<Clubs> findByName(String name) {
List<Clubs> list
= new ArrayList<Clubs>();
try {
PreparedStatement pstmt
= con.prepareStatement(
"SELECT * FROM APP.CLUB "
+ "WHERE UPPER(NAME) "
+ "LIKE ? ORDER BY NAME");
pstmt.setString(1, "%" + name.toUpperCase() + "%");
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
list.add(processRow(rs));
}
} catch (SQLException ex) {
ex.printStackTrace();
}
return list;
}
public int deleteById(int clubId){
int numRowsDeleted=0;
try{
PreparedStatement pstmt =
con.prepareStatement("DELETE FROM APP.CLUB WHERE ID=?");
pstmt.setInt(1, clubId);
numRowsDeleted = pstmt.executeUpdate();
}catch (Exception e){
e.printStackTrace();
}
return numRowsDeleted; // 0 == failure; 1 == success
}
public int deleteAllClubs(){
int result=0;
try{
PreparedStatement pstmt =
con.prepareStatement("DELETE FROM APP.CLUB");
result = pstmt.executeUpdate(); // 0 == failure; >=1 == success
}catch (Exception e){
e.printStackTrace();
}
return result; // 0 == failure; >=1 == success
}
}
package rest.clubs;
// link into JAX-RS
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
#ApplicationPath("/rest")
public class RestConfig extends Application{
#Override
public Set<Class<?>> getClasses(){
final Set<Class<?>> classes =
new HashSet<Class<?>>();
classes.add(ClubsResource.class);
return classes;
}
}
package rest.clubs;
import dao.Clubs;
import dao.ClubsDAO;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.OPTIONS;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
#Path("/clubs")
public class ClubsResource {
// this class responds to ".../rest/clubs"
private static ClubsDAO dao = new ClubsDAO();
#Context
private UriInfo context;
public ClubsResource() {
}
#GET
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getAllClubs() {
System.out.println("get all");
List<Clubs> clubList
= dao.findAll();
GenericEntity<List<Clubs>> entity;
entity = new GenericEntity<List<Clubs>>(clubList) {
};
return Response
.status(Response.Status.OK)
.header("Access-Control-Allow-Origin", "*")
.entity(entity)
.build();
}
#POST
#Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response addClubs(Clubs newClubs) {
System.out.println("POST - " + newClubs);
// the 'id' field in the request entity body is ignored!
int nextClubId = dao.getNextClubId();
newClubs.setId(nextClubId);
System.out.println("POST: nextClubId == " + nextClubId);
// now, our Clubobject is set up; insert into db
dao.addClubs(newClubs);
// now set up the HTTP response as per the HTTP spec
return Response
.status(Response.Status.CREATED)
.header("Location",
String.format("%s%s",
context.getAbsolutePath().toString(),
newClubs.getId()))
.header("Access-Control-Allow-Origin", "*")
.entity(newClubs)
.build();
}
#OPTIONS
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response optionsForAllClubs() {
System.out.println("OPTIONS for all");
// what is the verb set for this URI?
// what is the API supported?
Set<String> api = new TreeSet<>();
api.add("GET");// get all
api.add("POST");// add
api.add("DELETE");// delete all
api.add("HEAD");// get with no entity body
return Response
.noContent()
.allow(api)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers", "Content-Type")
.build();
}
#OPTIONS
#Path("{clubId}")
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response optionsForOneClub() {
System.out.println("OPTIONS for one");
// what is the verb set for this URI?
// what is the API supported?
Set<String> api = new TreeSet<>();
api.add("GET");// get one
api.add("PUT");// update (or add)
api.add("DELETE");// delete one
api.add("HEAD");// get with no entity body
return Response
.noContent()
.allow(api)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "DELETE, PUT, GET")
.header("Access-Control-Allow-Headers", "Content-Type")
.build();
}
#PUT
#Path("{clubId}")
#Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response updateOneClub(Clubs updateClub, #PathParam("clubId") int clubId) {
System.out.println("PUT - " + updateClub);
if (clubId == updateClub.getId()) {
// entity body id == id in URI
if (dao.findById(clubId) == null) {
// id not in db, create
dao.addClubs(updateClub);
// now set up the HTTP response as per the HTTP spec
return Response
.status(Response.Status.CREATED)
.header("Location",context.getAbsolutePath().toString())
.header("Access-Control-Allow-Origin", "*")
.entity(updateClub)
.build();
} else {
// id in db, update
dao.updateClubs(updateClub);
return Response
.status(Response.Status.OK)
.entity(updateClub)
.build();
}
} else {
// id in xml <> id in URI
return Response
.status(Response.Status.CONFLICT)
.entity("<conflict idInURI='"+clubId+"' idInEntityBody='"+updateClub.getId()+"' />")
.build();
}
}
#HEAD
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response headerForAllClubs() {
System.out.println("HEAD");
return Response
.noContent()
.build();
}
#HEAD
#Path("{clubId}")
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response headerForOneClub(#PathParam("clubId") String clubId) {
return Response
.noContent()
.build();
}
#DELETE
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response deleteAllClubs() {
System.out.println("delete all");
int rowsDeleted = dao.deleteAllClubs();
if (rowsDeleted > 0) { // success
// now set up the HTTP response message
return Response
.noContent()
.status(Response.Status.NO_CONTENT)
.header("Access-Control-Allow-Origin", "*")
.build();
} else {
// error
return Response
.status(Response.Status.NOT_FOUND)
.entity("<error rowsDeleted='" + rowsDeleted + "' />")
.header("Access-Control-Allow-Origin", "*")
.build();
}
}
#GET
#Path("{clubId}")
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getOneClub(#PathParam("clubId") String clubId) {
System.out.println("getOneClub::" + clubId);
Clubs club
= dao.findById(Integer.parseInt(clubId));
return Response
.status(Response.Status.OK)
.header("Access-Control-Allow-Origin", "*")
.entity(club)
.build();
}
#GET
#Path("search/{name}") // /clubs/search/Real
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getByName(#PathParam("name") String name) {
System.out.println("getByName: " + name);
List<Clubs> clubList
= dao.findByName(name);
GenericEntity<List<Clubs>> entity;
entity = new GenericEntity<List<Clubs>>(clubList) {
};
return Response
.status(Response.Status.OK)
.header("Access-Control-Allow-Origin", "*")
.entity(entity)
.build();
}
#DELETE
#Path("{clubId}") // Path Param i.e. /clubs/1
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response deleteOneClub(#PathParam("clubId") String clubId) {
System.out.println("deleteOneClub(): " + clubId);
// delete the row from the db where the id={clubId}
int numRowsDeleted = dao.deleteById(Integer.parseInt(clubId));
if (numRowsDeleted == 1) { // success
return Response
.noContent()
.status(Response.Status.NO_CONTENT)
.header("Access-Control-Allow-Origin", "*")
.build();
} else {// error
return Response
.status(Response.Status.NOT_FOUND)
.entity("<idNotInDB id='" + clubId + "' />")
.header("Access-Control-Allow-Origin", "*")
.build();
}
}
}

codename one FB authentication

I have been using the following code
String clientId = "1171134366245722";
String redirectURI = "http://www.codenameone.com/";
String clientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXX";
Login fb = FacebookConnect.getInstance();
fb.setClientId(clientId);
fb.setRedirectURI(redirectURI);
fb.setClientSecret(clientSecret);
//Sets a LoginCallback listener
fb.setCallback(...);
//trigger the login if not already logged in
if(!fb.isUserLoggedIn()){
fb.doLogin();
} else {
//get the token and now you can query the facebook
String token = fb.getAccessToken().getToken();
...
}
After login into facebook account, it directly takes me to the sendRedirectURI(XXX) as specified in code and the callback function is not working. I need to run setcallback(), how do I achieve that?
You have a couple of things to do for Facebook login to work.
You need to define what kind of data you will like to fetch. The best way is to create a UserData interface and implement it in your class:
public interface UserData {
public String getId();
public String getEmail();
public String getFirstName();
public String getLastName();
public String getImage();
public void fetchData(String token, Runnable callback);
}
Then implement it like this:
class FacebookData implements UserData {
String id;
String email;
String first_name;
String last_name;
String image;
#Override
public String getId() {
return id;
}
#Override
public String getEmail() {
return email;
}
#Override
public String getFirstName() {
return first_name;
}
#Override
public String getLastName() {
return last_name;
}
#Override
public String getImage() {
return image;
}
#Override
public void fetchData(String token, Runnable callback) {
ConnectionRequest req = new ConnectionRequest() {
#Override
protected void readResponse(InputStream input) throws IOException {
try {
JSONParser parser = new JSONParser();
Map<String, Object> parsed = parser.parseJSON(new InputStreamReader(input, "UTF-8"));
id = (String) parsed.get("id");
email = (String) parsed.get("email");
first_name = (String) parsed.get("first_name");
last_name = (String) parsed.get("last_name");
image = (String) ((Map) ((Map) parsed.get("picture")).get("data")).get("url").toString();
} catch (Exception ex) {
}
}
#Override
protected void postResponse() {
callback.run();
}
#Override
protected void handleErrorResponseCode(int code, String message) {
if (code >= 400 && code <= 410) {
doLogin(FacebookConnect.getInstance(), FacebookData.this, true);
return;
}
super.handleErrorResponseCode(code, message);
}
};
req.setPost(false);
req.setUrl("https://graph.facebook.com/v2.10/me");
req.addArgumentNoEncoding("access_token", token);
req.addArgumentNoEncoding("fields", "id,email,first_name,last_name,picture.width(512).height(512)");
NetworkManager.getInstance().addToQueue(req);
}
}
Let's create a doLogin() method that includes the setCallback()
void doLogin(Login lg, UserData data, boolean forceLogin) {
if (!forceLogin) {
if (lg.isUserLoggedIn()) {
//process Facebook login with "data" here
return;
}
String token = Preferences.get("token", (String) null);
if (getToolbar() != null && token != null) {
long tokenExpires = Preferences.get("tokenExpires", (long) -1);
if (tokenExpires < 0 || tokenExpires > System.currentTimeMillis()) {
data.fetchData(token, () -> {
//process Facebook login with "data" here
});
return;
}
}
}
lg.setCallback(new LoginCallback() {
#Override
public void loginFailed(String errorMessage) {
Dialog.show("Error Logging In", "There was an error logging in with Facebook: " + errorMessage, "Ok", null);
}
#Override
public void loginSuccessful() {
data.fetchData(lg.getAccessToken().getToken(), () -> {
Preferences.set("token", lg.getAccessToken().getToken());
Preferences.set("tokenExpires", tokenExpirationInMillis(lg.getAccessToken()));
//process Facebook login with "data" here
});
}
});
lg.doLogin();
}
long tokenExpirationInMillis(AccessToken token) {
String expires = token.getExpires();
if (expires != null && expires.length() > 0) {
try {
long l = (long) (Float.parseFloat(expires) * 1000);
return System.currentTimeMillis() + l;
} catch (NumberFormatException ex) {
}
}
return -1;
}
Finally, call doLogin() after fb.setClientSecret()
String clientId = "1171134366245722";
String redirectURI = "http://www.codenameone.com/";
String clientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXX";
Login fb = FacebookConnect.getInstance();
fb.setClientId(clientId);
fb.setRedirectURI(redirectURI);
fb.setClientSecret(clientSecret);
doLogin(fb, new FacebookData(), false);

how to watch the cilent when it lose Leadership through zookeeper curator?

as we know,when the client get the leadership,will invode the takeLeadership,but the document do not tell me when the client lost the leadership!!!so,how to watch the cilent when it lose Leadership through zookeeper curator?
question two : why my client was lose,i am can not debug the stateChanged(...) thought idea?
here my code, expect your great answer,thx
public class ExampleClient extends LeaderSelectorListenerAdapter implements Closeable{
private final String name;
private final LeaderSelector leaderSelector;
private final AtomicInteger leaderCount = new AtomicInteger();//用于记录领导次数
public ExampleClient(CuratorFramework client,String path,String name) {
this.name = name;
leaderSelector = new LeaderSelector(client, path, this);
leaderSelector.autoRequeue();//保留重新获取领导权资格
}
public void start() throws IOException {
leaderSelector.start();
}
#Override
public void close() throws IOException {
leaderSelector.close();
}
#Override
public void stateChanged(CuratorFramework client, ConnectionState newState)
{
if ((newState == ConnectionState.SUSPENDED) || (newState == ConnectionState.LOST) ) {
log.info("stateChanged !!!");
throw new CancelLeadershipException();
}
}
/**
* will be invoded when get leadeship
* #param client
* #throws Exception
*/
#Override
public void takeLeadership(CuratorFramework client) throws Exception {
final int waitSeconds =(int)(Math.random()*5)+1;
log.info(name + " is the leader now,wait " + waitSeconds + " seconds!");
log.info(name + " had been leader for " + leaderCount.getAndIncrement() + " time(s) before");
try {
/**/
Thread.sleep(TimeUnit.SECONDS.toMillis(waitSeconds));
//do something!!!
/*while(true){
//guarantee this client be the leader all the time!
}*/
}catch (InterruptedException e){
log.info(name+" was interrupted!");
Thread.currentThread().interrupt();
}finally{
log.info(name+" relinquishing leadership.\n");
}
}
}
LeaderLatchListener has two call backs about isLeader and notLeader. Some examples,
http://www.programcreek.com/java-api-examples/index.php?api=org.apache.curator.framework.recipes.leader.LeaderLatchListener

netty SimpleChannelInboundHandler<String> channelRead0 only occasionally invoked

I know that there are several similar questions that have either been answered or still outstanding, however, for the life of me...
Later Edit 2016-08-25 10:05 CST - Actually, I asked the wrong question.
The question is the following: given that I have both a netty server (taken from DiscardServer example) and a netty client - (see above) what must I do to force the DiscardServer to immediately send the client a request?
I have added an OutboundHandler to the server and to the client.
After looking at both the DiscardServer and PingPongServer examples, there is an external event occurring to kick off all the action. In the case of Discard server, it is originally waiting for a telnet connection, then will transmit whatever was in the telnet msg to the client.
In the case of PingPongServer, the SERVER is waiting on the client to initiate action.
What I want is for the Server to immediately start transmitting after connection with the client. None of the examples from netty seem to do this.
If I have missed something, and someone can point it out, much good karma.
My client:
public final class P4Listener {
static final Logger LOG;
static final String HOST;
static final int PORT;
static final Boolean SSL = Boolean.FALSE;
public static Dto DTO;
static {
LOG = LoggerFactory.getLogger(P4Listener.class);
HOST = P4ListenerProperties.getP4ServerAddress();
PORT = Integer.valueOf(P4ListenerProperties.getListenerPort());
DTO = new Dto();
}
public static String getId() { return DTO.getId(); }
public static void main(String[] args) throws Exception {
final SslContext sslCtx;
if (SSL) {
LOG.info("{} creating SslContext", getId());
sslCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
} else {
sslCtx = null;
}
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.handler(new P4ListenerInitializer(sslCtx));
// Start the connection attempt.
LOG.debug(" {} starting connection attempt...", getId());
Channel ch = b.connect(HOST, PORT).sync().channel();
// ChannelFuture localWriteFuture = ch.writeAndFlush("ready\n");
// localWriteFuture.sync();
} finally {
group.shutdownGracefully();
}
}
}
public class P4ListenerHandler extends SimpleChannelInboundHandler<String> {
static final Logger LOG = LoggerFactory.getLogger(P4ListenerHandler.class);
static final DateTimeFormatter DTFormatter = DateTimeFormatter.ofPattern("yyyyMMdd-HHMMss.SSS");
static final String EndSOT;
static final String StartSOT;
static final String EOL = "\n";
static final ClassPathXmlApplicationContext AppContext;
static {
EndSOT = P4ListenerProperties.getEndSOT();
StartSOT = P4ListenerProperties.getStartSOT();
AppContext = new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" });
}
private final RequestValidator rv = new RequestValidator();
private JAXBContext jaxbContext = null;
private Unmarshaller jaxbUnmarshaller = null;
private boolean initialized = false;
private Dto dto;
public P4ListenerHandler() {
dto = new Dto();
}
public Dto getDto() { return dto; }
public String getId() { return getDto().getId(); }
Message convertXmlToMessage(String xml) {
if (xml == null)
throw new IllegalArgumentException("xml message is null!");
try {
jaxbContext = JAXBContext.newInstance(p4.model.xml.request.Message.class, p4.model.xml.request.Header.class,
p4.model.xml.request.Claims.class, p4.model.xml.request.Insurance.class,
p4.model.xml.request.Body.class, p4.model.xml.request.Prescriber.class,
p4.model.xml.request.PriorAuthorization.class,
p4.model.xml.request.PriorAuthorizationSupportingDocumentation.class);
jaxbUnmarshaller = jaxbContext.createUnmarshaller();
StringReader strReader = new StringReader(xml);
Message m = (Message) jaxbUnmarshaller.unmarshal(strReader);
return m;
} catch (JAXBException jaxbe) {
String error = StacktraceUtil.getCustomStackTrace(jaxbe);
LOG.error(error);
throw new P4XMLUnmarshalException("Problems when attempting to unmarshal transmission string: \n" + xml,
jaxbe);
}
}
#Override
public void channelActive(ChannelHandlerContext ctx) {
LOG.debug("{} let server know we are ready", getId());
ctx.writeAndFlush("Ready...\n");
}
/**
* Important - this method will be renamed to
* <code><b>messageReceived(ChannelHandlerContext, I)</b></code> in netty 5.0
*
* #param ctx
* #param msg
*/
#Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
ChannelFuture lastWriteFuture = null;
LOG.debug("{} -- received message: {}", getId(), msg);
Channel channel = ctx.channel();
Message m = null;
try {
if (msg instanceof String && msg.length() > 0) {
m = convertXmlToMessage(msg);
m.setMessageStr(msg);
dto.setRequestMsg(m);
LOG.info("{}: received TIMESTAMP: {}", dto.getId(), LocalDateTime.now().format(DTFormatter));
LOG.debug("{}: received from server: {}", dto.getId(), msg);
/*
* theoretically we have a complete P4(XML) request
*/
final List<RequestFieldError> errorList = rv.validateMessage(m);
if (!errorList.isEmpty()) {
for (RequestFieldError fe : errorList) {
lastWriteFuture = channel.writeAndFlush(fe.toString().concat(EOL));
}
}
/*
* Create DBHandler with message, messageStr, clientIp to get
* dbResponse
*/
InetSocketAddress socketAddress = (InetSocketAddress) channel.remoteAddress();
InetAddress inetaddress = socketAddress.getAddress();
String clientIp = inetaddress.getHostAddress();
/*
* I know - bad form to ask the ApplicationContext for the
* bean... BUT ...lack of time turns angels into demons
*/
final P4DbRequestHandler dbHandler = (P4DbRequestHandler) AppContext.getBean("dbRequestHandler");
// must set the requestDTO for the dbHandler!
dbHandler.setClientIp(clientIp);
dbHandler.setRequestDTO(dto);
//
// build database request and receive response (string)
String dbResponse = dbHandler.submitDbRequest();
/*
* create ResponseHandler and get back response string
*/
P4ResponseHandler responseHandler = new P4ResponseHandler(dto, dbHandler);
String responseStr = responseHandler.decodeDbServiceResponse(dbResponse);
/*
* write response string to output and repeat exercise
*/
LOG.debug("{} -- response to be written back to server:\n {}", dto.getId(), responseStr);
lastWriteFuture = channel.writeAndFlush(responseStr.concat(EOL));
//
LOG.info("{}: response sent TIMESTAMP: {}", dto.getId(), LocalDateTime.now().format(DTFormatter));
} else {
throw new P4EventException(dto.getId() + " -- Message received is not a String");
}
processWriteFutures(lastWriteFuture);
} catch (Throwable t) {
String tError = StacktraceUtil.getCustomStackTrace(t);
LOG.error(tError);
} finally {
if (lastWriteFuture != null) {
lastWriteFuture.sync();
}
}
}
private void processWriteFutures(ChannelFuture writeFuture) throws InterruptedException {
// Wait until all messages are flushed before closing the channel.
if (writeFuture != null) {
writeFuture.sync();
}
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
/**
* Creates a newly configured {#link ChannelPipeline} for a new channel.
*/
public class P4ListenerInitializer extends ChannelInitializer<SocketChannel> {
private static final StringDecoder DECODER = new StringDecoder();
private static final StringEncoder ENCODER = new StringEncoder();
private final SslContext sslCtx;
public P4ListenerInitializer(SslContext sslCtx) {
this.sslCtx = sslCtx;
}
#Override
public void initChannel(SocketChannel ch) {
P4ListenerHandler lh = null;
ChannelPipeline pipeline = ch.pipeline();
if (sslCtx != null) {
P4Listener.LOG.info("{} -- constructing SslContext new handler ", P4Listener.getId());
pipeline.addLast(sslCtx.newHandler(ch.alloc(), P4Listener.HOST, P4Listener.PORT));
} else {
P4Listener.LOG.info("{} -- SslContext null; bypassing adding sslCtx.newHandler(ch.alloc(), P4Listener.HOST, P4Listener.PORT) ", P4Listener.getId());
}
// Add the text line codec combination first,
pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast(DECODER);
P4Listener.LOG.debug("{} -- added Decoder ", P4Listener.getId());
pipeline.addLast(ENCODER);
P4Listener.LOG.debug("{} -- added Encoder ", P4Listener.getId());
// and then business logic.
pipeline.addLast(lh = new P4ListenerHandler());
P4Listener.LOG.debug("{} -- added P4ListenerHandler: {} ", P4Listener.getId(), lh.getClass().getSimpleName());
}
}
#Sharable
public class P4ListenerOutboundHandler extends ChannelOutboundHandlerAdapter {
static final Logger LOG = LoggerFactory.getLogger(P4ListenerOutboundHandler.class);
private Dto outBoundDTO = new Dto();
public String getId() {return this.outBoundDTO.getId(); }
#Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
try {
ChannelFuture lastWrite = ctx.write(Unpooled.copiedBuffer((String) msg, CharsetUtil.UTF_8));
try {
if (lastWrite != null) {
lastWrite.sync();
promise.setSuccess();
}
} catch (InterruptedException e) {
promise.setFailure(e);
e.printStackTrace();
}
} finally {
ReferenceCountUtil.release(msg);
}
}
}
output from client
Just override channelActive(...) on the handler of the server and trigger a write there.

SASL Authentication failed while integrating facebook chat using Smack

I am trying to integrate facebook chat using smack API.But i get an error telling authentication failed using digest md5...
Here s the code for authentication:
SASLAuthentication.registerSASLMechanism("DIGEST-MD5", SASLDigestMD5Mechanism.class);
SASLAuthentication.supportSASLMechanism("DIGEST-MD5", 0);
ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com",5222);
connection = new XMPPConnection(config);
config.setSASLAuthenticationEnabled(true);
connection.connect();
connection.login(userName, password);
below is the error i get wen i run it:
Exception in thread "main" SASL authentication failed using mechanism DIGEST-MD5:
at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:325)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:395)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:349)
at JabberSmackAPIFacebook.login(JabberSmackAPIFacebook.java:31)
at JabberSmackAPIFacebook.main(JabberSmackAPIFacebook.java:77)
I can successfully connect to gtalk but am having no success vit fb...
can sumone tel me wat s the problem
For me the solution was to not include the host part in the username when calling login() without DNS SRV and not agains the Google Talk services. This is also described in the ignite forums.
E.g.
connection.login("user#jabber.org", "password", "resource");
becomes
connection.login("user", "password", "resource");
There is a huge thread at Ignite that deals with this issue. You may want to take a look at it as there are several solutions for Java and Android given that seem to work.
I have succesfully connected using DIGEST-MD5 to facebook, the code you have posted looks good.
But still we need to check the contents of your SASLDigestMD5Mechanism class
I have used the class provided in here with success
http://community.igniterealtime.org/message/200878#200878
Also you have to notice that in the DIGEST-MD5 mechanism you have to login with your facebook username and not with the email address. By default the facebook accounts don't have a username, you have to create one fisrt, you can check that in here:
http://www.facebook.com/username/
MainActivity.java
public class MainActivity extends Activity {
XMPPConnection xmpp;
ArrayList<HashMap<String, String>> friends_list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Session.openActiveSession(this, true, new StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if ( session.isOpened()){
new testLoginTask().execute();
}
}
});
}
private class testLoginTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
testLogin();
return null;
}
}
private void testLogin(){
ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222);
config.setSASLAuthenticationEnabled(true);
config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);
config.setDebuggerEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
config.setTruststoreType("AndroidCAStore");
config.setTruststorePassword(null);
config.setTruststorePath(null);
} else {
config.setTruststoreType("BKS");
String path = System.getProperty("javax.net.ssl.trustStore");
if (path == null)
path = System.getProperty("java.home") + File.separator + "etc"
+ File.separator + "security" + File.separator
+ "cacerts.bks";
config.setTruststorePath(path);
}
xmpp = new XMPPConnection(config);
SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM",SASLXFacebookPlatformMechanism.class);
SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
try {
xmpp.connect();
Log.i("XMPPClient","Connected to " + xmpp.getHost());
} catch (XMPPException e1) {
Log.i("XMPPClient","Unable to " + xmpp.getHost());
e1.printStackTrace();
}
try {
String apiKey = Session.getActiveSession().getApplicationId();
String sessionKey = Session.getActiveSession().getAccessToken();
String sessionSecret = "replace with your app secret key";
xmpp.login(apiKey + "|" + sessionKey, sessionSecret , "Application");
Log.i("XMPPClient"," its logined ");
Log.i("Connected",""+xmpp.isConnected());
if ( xmpp.isConnected()){
Presence presence = new Presence(Presence.Type.available);
xmpp.sendPacket(presence);
}
} catch (XMPPException e) {
e.printStackTrace();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
SASLXFacebookPlatformMechanism.java
public class SASLXFacebookPlatformMechanism extends SASLMechanism{
private static final String NAME = "X-FACEBOOK-PLATFORM";
private String apiKey = "";
private String accessToken = "";
/**
* Constructor.
*/
public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication) {
super(saslAuthentication);
}
#Override
protected void authenticate() throws IOException, XMPPException {
getSASLAuthentication().send(new AuthMechanism(NAME, ""));
}
#Override
public void authenticate(String apiKey, String host, String accessToken) throws IOException, XMPPException {
if (apiKey == null || accessToken == null) {
throw new IllegalArgumentException("Invalid parameters");
}
this.apiKey = apiKey;
this.accessToken = accessToken;
this.hostname = host;
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, this);
authenticate();
}
#Override
public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException {
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, cbh);
authenticate();
}
#Override
protected String getName() {
return NAME;
}
#Override
public void challengeReceived(String challenge) throws IOException {
byte[] response = null;
if (challenge != null) {
String decodedChallenge = new String(Base64.decode(challenge));
Map<String, String> parameters = getQueryMap(decodedChallenge);
String version = "1.0";
String nonce = parameters.get("nonce");
String method = parameters.get("method");
long callId = new GregorianCalendar().getTimeInMillis();
String composedResponse = "api_key="
+ URLEncoder.encode(apiKey, "utf-8") + "&call_id=" + callId
+ "&method=" + URLEncoder.encode(method, "utf-8")
+ "&nonce=" + URLEncoder.encode(nonce, "utf-8")
+ "&access_token="
+ URLEncoder.encode(accessToken, "utf-8") + "&v="
+ URLEncoder.encode(version, "utf-8");
response = composedResponse.getBytes("utf-8");
}
String authenticationText = "";
if (response != null) {
authenticationText = Base64.encodeBytes(response,
Base64.DONT_BREAK_LINES);
}
// Send the authentication to the server
getSASLAuthentication().send(new Response(authenticationText));
}
private Map<String, String> getQueryMap(String query) {
Map<String, String> map = new HashMap<String, String>();
String[] params = query.split("\\&");
for (String param : params) {
String[] fields = param.split("=", 2);
map.put(fields[0], (fields.length > 1 ? fields[1] : null));
}
return map;
}
}