/*
* IntrospectionClient.java
*
* Created on May 13, 2007, 3:24 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package org.atomojo.app.client;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Logger;
import org.infoset.xml.Characters;
import org.infoset.xml.Element;
import org.infoset.xml.Item;
import org.infoset.xml.ItemDestination;
import org.infoset.xml.Name;
import org.infoset.xml.Named;
import org.infoset.xml.XMLException;
import org.restlet.Client;
import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.ChallengeResponse;
import org.restlet.data.ChallengeScheme;
import org.restlet.data.MediaType;
import org.restlet.data.Method;
import org.restlet.data.Protocol;
import org.restlet.data.Reference;
import org.restlet.representation.Representation;
/**
*
* @author alex
*/
public class IntrospectionClient extends AppClient
{
static final MediaType ATOM_SERVICE_XML = MediaType.valueOf("application/atomsvc+xml");
public interface ServiceListener {
void onStartWorkspace(String title);
void onCollection(EntryCollection collection);
void onEndWorkspace();
}
Logger log;
Reference location;
URI ulocation;
class ServiceDestination implements ItemDestination {
ServiceListener listener;
int state;
boolean startedWorkspace;
String title;
URI collectionLocation;
ItemDestination delegate;
StringBuilder buffer;
ServiceDestination(ServiceListener listener)
{
this.listener = listener;
this.state = 0;
this.buffer = null;
}
public void send(Item item)
throws XMLException
{
switch (state) {
case 0:
if (item.getType()==Item.ItemType.ElementItem) {
Name name = ((Named)item).getName();
if (name.equals(WORKSPACE) || name.equals(OLD_WORKSPACE)) {
state = 1;
startedWorkspace = false;
}
}
break;
case 1:
switch (item.getType()) {
case ElementItem:
{
Element e = (Element)item;
Name name = ((Named)item).getName();
if (name.equals(COLLECTION) || name.equals(OLD_COLLECTION)) {
if (!startedWorkspace) {
listener.onStartWorkspace("");
startedWorkspace = true;
}
String href = e.getAttributeValue("href");
if (href==null) {
return;
}
title = null;
URI base = e.getBaseURI();
if (base==null) {
base = ulocation;
}
collectionLocation = base.resolve(href);
//Logger.getAnonymousLogger().info("Resolved '"+href+"' against '"+base+"' to get '"+collectionLocation+"'");
state = 2;
} else if (name.equals(TITLE_NAME)) {
buffer = new StringBuilder();
title = "";
}
}
break;
case ElementEndItem:
{
Name name = ((Named)item).getName();
if (name.equals(WORKSPACE) || name.equals(OLD_WORKSPACE)) {
listener.onEndWorkspace();
state = 0;
} else if (name.equals(TITLE_NAME)) {
listener.onStartWorkspace(buffer.toString());
startedWorkspace = true;
buffer = null;
}
}
break;
case CharactersItem:
if (buffer!=null) {
buffer.append(((Characters)item).getText());
}
}
break;
case 2:
switch (item.getType()) {
case ElementItem:
{
Name name = ((Named)item).getName();
if (name.equals(TITLE_NAME)) {
buffer = new StringBuilder();
}
}
break;
case ElementEndItem:
{
Name name = ((Named)item).getName();
if (name.equals(COLLECTION) || name.equals(OLD_COLLECTION)) {
listener.onCollection(new EntryCollection(title,collectionLocation));
state = 1;
}
}
break;
case CharactersItem:
if (buffer!=null) {
buffer.append(((Characters)item).getText());
}
}
}
}
}
/** Creates a new instance of IntrospectionClient */
public IntrospectionClient(Logger log,URI location)
{
this.log = log;
this.ulocation = location;
this.location = new Reference(location.toString());
}
/** Creates a new instance of IntrospectionClient */
public IntrospectionClient(Logger log,Reference location)
throws URISyntaxException
{
this.log = log;
this.location = location;
this.ulocation = new URI(location.toString());
}
public void introspect(ServiceListener listener)
throws IOException,XMLException
{
Client client = new Client(new Context(Logger.getLogger(IntrospectionClient.class.getName())),Protocol.valueOf(location.getScheme()));
client.getContext().getAttributes().put("hostnameVerifier", org.apache.commons.ssl.HostnameVerifier.DEFAULT);
Request request = new Request(Method.GET,location.toString());
if (identity!=null) {
request.setChallengeResponse(new ChallengeResponse(ChallengeScheme.HTTP_BASIC,identity.getName(),identity.getPassword()));
}
if (cookie!=null) {
request.getCookies().add(cookie);
}
Response response = client.handle(request);
if (response.getStatus().isSuccess()) {
Representation rep = response.getEntity();
String mediaTypeName = rep.getMediaType().getName();
if (!mediaTypeName.equals(ATOM_SERVICE_XML.getName())) {
if (mediaTypeName.equals(MediaType.APPLICATION_XML.getName()) || mediaTypeName.equals(MediaType.TEXT_XML.getName()) || mediaTypeName.equals("application/atomserv+xml")) {
log.info("Incorrect media type "+mediaTypeName+" received, recovering.");
} else {
throw new IOException("Invalid media type received: "+rep.getMediaType());
}
}
XMLRepresentationParser parser = new XMLRepresentationParser();
parser.parse(response,new ServiceDestination(listener));
} else {
throw new IOException("Introspection failed to get a service document, status="+response.getStatus().getCode());
}
}
}