diff --git a/cs656/lab4/ChatServer.java b/cs656/lab4/ChatServer.java index 2e573ee..f94512a 100644 --- a/cs656/lab4/ChatServer.java +++ b/cs656/lab4/ChatServer.java @@ -10,10 +10,26 @@ import org.restlet.Router; import org.restlet.data.Protocol; import org.restlet.util.Variable; +import com.db4o.Db4o; +import com.db4o.ObjectContainer; +import com.db4o.config.Configuration; + public class ChatServer extends Application { - public ChatServer() + /** + * This is our persistant object database container. + */ + private ObjectContainer myContainer; + + public ChatServer() { + /** Open and keep the db4o object container. */ + Configuration config = Db4o.configure(); + config.updateDepth(2); + String fileName = System.getProperty("user.home") + + File.separator + "cs656-lab4-users.dbo"; + System.out.println("Database file is: " + fileName); + myContainer = Db4o.openFile(fileName); } /* Create application root node. @@ -25,7 +41,7 @@ public class ChatServer extends Application Router router = new Router(getContext()); // Add a route for user resources - router.attach("/users", UserResource.class); + router.attach("/users", UsersResource.class); // Add a route for a user resource router.attach("/users/{id}", UserResource.class); @@ -33,12 +49,10 @@ public class ChatServer extends Application return router; } - /* public ObjectContainer getContainer() { - return this.container; + return myContainer; } - */ /** * @param args Passed in from the command line. diff --git a/cs656/lab4/PresenceServiceImpl.java b/cs656/lab4/PresenceServiceImpl.java index 7d345bd..ab3d22a 100644 --- a/cs656/lab4/PresenceServiceImpl.java +++ b/cs656/lab4/PresenceServiceImpl.java @@ -1,5 +1,6 @@ import java.io.IOException; +import java.util.*; import org.restlet.Client; import org.restlet.data.Form; @@ -15,11 +16,13 @@ public class PresenceServiceImpl implements PresenceService { private int myPort; private String myHost; + private String myAppURI; public PresenceServiceImpl(String host, int port) { myHost = host; myPort = port; + myAppURI = "http://" + host + ":" + port + "/v1"; } /** @@ -28,6 +31,22 @@ public class PresenceServiceImpl implements PresenceService */ public void register(RegistrationInfo reg) throws Exception { + Form form = new Form(); + form.add("user[name]", reg.getUserName()); + form.add("user[host]", reg.getHost()); + form.add("user[port]", reg.getPort()); + form.add("user[status]", reg.getStatus() ? "available" : "away"); + + // construct request to create a new user resource + String usersResouceUri = myAppURI + "/users"; + Request request = new Request(Method.POST, usersResouceUri); + + request.setEntity(form.getWebRepresentation()); + + // Invoke the client HTTP connector + Response resp = new Client(Protocol.HTTP).handle(request); + if ( ! resp.getStatus().isSuccess() ) + System.out.println(resp.getStatus()); } /** @@ -37,6 +56,13 @@ public class PresenceServiceImpl implements PresenceService */ public void unregister(String userName) throws Exception { + String userResourceUri = myAppURI + "/users/" + userName; + Request request = new Request(Method.DELETE, userResourceUri); + + // Invoke the client HTTP connector + Response resp = new Client(Protocol.HTTP).handle(request); + if ( ! resp.getStatus().isSuccess() ) + System.err.println(resp.getStatus()); } /** @@ -47,6 +73,23 @@ public class PresenceServiceImpl implements PresenceService */ public RegistrationInfo lookup(String name) throws Exception { + try + { + String userResourceUri = myAppURI + "/users/" + name; + request = new Request(Method.GET, userResourceUri); + resp = new Client(Protocol.HTTP).handle(request); + if ( ! resp.getStatus().isSuccess() ) + System.out.println(resp.getStatus()); + DomRepresentation d = resp.getEntityAsDom(); + Node n = d.getFirstChild(); + if (n == null) + return null; + return nodeToRegInfo(n); + } + catch (Exception ioex) + { + ioex.printStackTrace(); + } return null; } @@ -57,6 +100,24 @@ public class PresenceServiceImpl implements PresenceService */ public void setStatus(String userName, boolean status) throws Exception { + Form form = new Form(); + form.add("user[status]", status ? "available" : "away"); + + String userResourceUri = myAppURI + "/users/" + userName; + Request request = new Request(Method.PUT, userResourceUri); + request.setEntity(form.getWebRepresentation()); + + try + { + // Invoke the client HTTP connector + Response resp = new Client(Protocol.HTTP).handle(request); + if ( ! resp.getStatus().isSuccess() ) + System.err.println(resp.getStatus()); + } + catch (IOException e) + { + e.printStackTrace(); + } } /** @@ -66,6 +127,57 @@ public class PresenceServiceImpl implements PresenceService */ public RegistrationInfo[] listRegisteredUsers() throws Exception { - return null; + Vector users = new Vector(); + + try + { + String usersResourceUri = myAppURI + "/users"; + Request request = new Request(Method.GET, usersResourceUri); + + // Invoke the client HTTP connector + Response resp = new Client(Protocol.HTTP).handle(request); + if ( ! resp.getStatus().isSuccess() ) + System.err.println(resp.getStatus()); + DomRepresentation dom = resp.getEntityAsDom(); + System.out.println("DEBUG: DOM received:\n" + dom.getText()); + Document d = dom.getDocument(); + Node root = d.getFirstChild(); + NodeList nl = root.getChildren(); + for (int i = 0; i < nl.getLength(); i++) + { + Node n = nl.item(i); + if (n.getNodeName().equals("user")) + { + RegistrationInfo ri = nodeToRegInfo(n); + users.add(ri); + } + } + } + catch (Exception ioex) + { + ioex.printStackTrace(); + } + + return users.toArray(); + } + + private RegistrationInfo nodeToRegInfo(Node n) + { + Registration ri = new RegistrationInfo(); + NodeList nl = n.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) + { + Node n = nl.item(i); + String name = n.getNodeName(); + if (name.equals("name")) + ri.setUserName(name.getTextContent()); + else if (name.equals("host")) + ri.setHost(name.getTextContent()); + else if (name.equals("port")) + ri.setPort(Integer.parseInt(name.getTextContent())); + else if (name.equals("status")) + ri.setStatus(name.getTextContent().equals("available")); + } + return ri; } } diff --git a/cs656/lab4/UserResource.java b/cs656/lab4/UserResource.java index 9272a7c..1c0fd33 100644 --- a/cs656/lab4/UserResource.java +++ b/cs656/lab4/UserResource.java @@ -1,94 +1,177 @@ -//---------------------------------------------------------------------- -// -// Filename: UserResource.java -// Description: -// -// $Id:$ -// -//---------------------------------------------------------------------- - -import java.io.IOException; - -import org.restlet.Context; -import org.restlet.data.Form; -import org.restlet.data.MediaType; -import org.restlet.data.Request; -import org.restlet.data.Response; -import org.restlet.resource.Resource; -import org.restlet.data.Status; -import org.restlet.resource.DomRepresentation; -import org.restlet.resource.Representation; -import org.restlet.resource.Variant; - - -public class UserResource extends Resource -{ - - public UserResource(Context context, Request request, Response response) - { - super(context, request, response); - String id = (String) request.getAttributes().get("id"); - getVariants().add(new Variant(MediaType.TEXT_XML)); - } - - /** - * handle HTTP GET requests. - */ - @Override - public Representation getRepresentation(Variant variant) - { - DomRepresentation rep = null; - if (variant.getMediaType().equals(MediaType.TEXT_XML)) - { - try - { - rep = new DomRepresentation(MediaType.TEXT_XML); - getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND); - rep.getDocument().normalizeDocument(); - } - catch (IOException e) - { - e.printStackTrace(); - } - } - return rep; - } - - @Override - public boolean allowDelete() - { - return true; - } - - @Override - public void delete() - { - /* - if (this.book != null) - { - getContainer().delete(this.book); - getContainer().commit(); - getResponse().setStatus(Status.SUCCESS_OK); - } else { - getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND); - } - */ - } - - /** - * PUT is implemented. - */ - @Override - public boolean allowPut() - { - return true; - } - - /** - * Update a resource in response to an HTTP PUT call. - */ - @Override - public void put(Representation entity) - { - } -} +//---------------------------------------------------------------------- +// +// Filename: BookResource.java +// Description: +// +// $Id:$ +// +//---------------------------------------------------------------------- +package edu.gvsu.cis.rest.example; + +import java.io.IOException; + +import org.restlet.Context; +import org.restlet.data.Form; +import org.restlet.data.MediaType; +import org.restlet.data.Request; +import org.restlet.data.Response; +import org.restlet.data.Status; +import org.restlet.resource.DomRepresentation; +import org.restlet.resource.Representation; +import org.restlet.resource.Variant; + + + +/** + * + * Book Resource. This handles HTTP requests against a specific Book resource. + * e.g. URIs of the form /v1/books/{id} + * + * @author Jonathan Engelsma + * + */ +public class BookResource extends BaseResource { + + private Book book; + + /** + * Load up the book resource data that is being called on. + * @param context Context of the HTTP request. + * @param request The HTTP request. + * @param response The HTTP response that will be returned to the caller. + */ + public BookResource(Context context, Request request, Response response) + { + super(context, request, response); + System.out.println("In BookResource"); + String id = (String) request.getAttributes().get("id"); + this.book = findBook(id); + if(this.book != null) { + getVariants().add(new Variant(MediaType.TEXT_XML)); + } + } + + /** + * handle HTTP GET requests. Return an XML representation of the book resource. + */ + @Override + public Representation getRepresentation(Variant variant) + { + DomRepresentation rep=null; + if (variant.getMediaType().equals(MediaType.TEXT_XML)){ + try { + if (book!=null){ + rep = book.getDomRepresentation(); + } + else{ + rep = new DomRepresentation(MediaType.TEXT_XML); + getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND); + //TODO: we need to return a 404 here. + //Error.embedErrorInResponse(rep.getDocument(),MediaType.TEXT_XML,Error.ErrorCode.RESOURCE_UNDEFINED); + } + rep.getDocument().normalizeDocument(); + + } catch (IOException e){ + e.printStackTrace(); + } + } + return rep; + } + + + @Override + public boolean allowDelete() { + return true; + } + + /** + * Handle an HTTP DELETE request. Delete the book resource. + */ + @Override + public void delete() + { + if (this.book != null) { + getContainer().delete(this.book); + // TODO: need to delete the book reviews here as well. + getContainer().commit(); + getResponse().setStatus(Status.SUCCESS_OK); + } else { + getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND); + } + } + + /** + * PUT is implemented. + */ + @Override + public boolean allowPut() { + // TODO Auto-generated method stub + return true; + } + + /** + * Update a resource in response to an HTTP PUT call. + */ + @Override + public void put(Representation entity) + { + try { + if (entity.getMediaType().equals(MediaType.APPLICATION_WWW_FORM, true) && (this.book != null)) { + + // Parse the entity as a web form + Form form = new Form(entity); + + // update the loaded Book object + String value = form.getFirstValue("book[authors]"); + if (value != null) { + book.setAuthors(value); + } + + value = form.getFirstValue("book[isbn]"); + if(value != null) { + book.setIsbn(value); + } + + value = form.getFirstValue("book[title]"); + if(value != null) { + book.setTitle(value); + } + + value = form.getFirstValue("book[publisher]"); + if(value != null) { + book.setPublisher(value); + } + + value = form.getFirstValue("book[year]"); + if (value != null ) { + book.setYear(value); + } + + // commit the changes. + getContainer().set(book); + getContainer().commit(); + + getResponse().setStatus(Status.SUCCESS_OK); + getResponse().setEntity(this.book.getDomRepresentation()); + + + } else { + // Intentionnally hide the bookmark existence + getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND); + } + } catch (IOException e) { + getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST); + e.printStackTrace(); + } + } + + /** + * Returns the book instance. + * @return a reference to a Book instance. + */ + public Book getBook() { + return this.book; + } + + +}