/*
* SyncTarget.java
*
* Created on April 11, 2007, 8:42 AM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package org.atomojo.app.db;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URI;
import java.util.logging.Level;
import org.atomojo.app.InfosetRepresentation;
import org.atomojo.app.admin.AdminXML;
import org.atomojo.app.auth.AuthCredentials;
import org.infoset.xml.Element;
import org.infoset.xml.InfosetFactory;
import org.infoset.xml.XMLException;
import org.infoset.xml.util.XMLWriter;
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.Status;
import org.restlet.representation.FileRepresentation;
import org.restlet.representation.Representation;
/**
*
* @author alex
*/
public class RemoteApp extends XMLObject implements StoredXML
{
DB db;
String name;
URI introspect;
URI root;
AuthCredentials auth;
/** Creates a new instance of SyncTarget */
public RemoteApp(DB db,Representation rep)
{
super(rep);
this.db = db;
}
public RemoteApp(DB db,Element xml)
{
super(xml);
this.name = xml.getAttributeValue("name");
this.db = db;
}
public RemoteApp(DB db,String name)
{
super((Element)null);
this.name = name;
this.db = db;
}
public RemoteApp(DB db,String name,URI introspect,URI root,AuthCredentials auth)
{
super((Element)null);
this.name = name;
this.introspect = introspect;
this.root = root;
this.auth = auth;
this.db = db;
}
public Representation getRepresentation() {
if (rep==null && name!=null) {
rep = new FileRepresentation(getFile(),MediaType.APPLICATION_XML);
}
return super.getRepresentation();
}
protected File getFile() {
return new File(db.getRemoteAppDir(),name+".xml");
}
public void unmarshall()
throws XMLException
{
if (xml==null) {
try {
parse();
} catch (IOException ex) {
throw new XMLException("Cannot load XML due to I/O exception.",ex);
}
}
try {
Element top = getElement();
name = top.getAttributeValue("name");
String intro = top.getAttributeValue("introspect");
introspect = intro==null ? null : URI.create(intro);
root = URI.create(top.getAttributeValue("root"));
Element authE = top.getFirstElementNamed(AdminXML.NM_AUTH);
auth = authE==null ? null : new AuthCredentials(authE.getAttributeValue("method"),authE.getAttributeValue("name"),authE.getAttributeValue("password"));
} catch (Exception ex) {
throw new XMLException("Cannot unmarshall XML: "+ex.getMessage(),ex);
}
}
public void marshall()
throws XMLException
{
xml = InfosetFactory.getDefaultInfoset().createItemConstructor().createDocument().createDocumentElement(AdminXML.NM_APP);
xml.setAttributeValue("name",name);
xml.setAttributeValue("root",root.toString());
if (introspect!=null) {
xml.setAttributeValue("introspect",introspect.toString());
}
if (auth!=null) {
Element authE = xml.addElement(AdminXML.NM_AUTH);
authE.setAttributeValue("method",auth.getScheme());
authE.setAttributeValue("name",auth.getName());
authE.setAttributeValue("password",auth.getPassword());
}
rep = new InfosetRepresentation(MediaType.APPLICATION_XML,xml.getDocument());
}
public String getName()
{
return name;
}
public URI getIntrospection()
{
return introspect;
}
public URI getRoot()
{
return root;
}
public AuthCredentials getAuthCredentials()
{
return auth;
}
public void setIntrospection(URI uri)
{
introspect = uri;
}
public void setRoot(URI uri)
{
root = uri;
}
public boolean exists()
{
return getFile().exists();
}
public boolean create()
{
return update();
}
public boolean delete()
{
return getFile().delete();
}
public boolean update()
{
try {
Writer out = new OutputStreamWriter(new FileOutputStream(getFile()),"UTF-8");
XMLWriter.writeDocument(xml.getDocument(), out);
out.flush();
out.close();
return true;
} catch (Exception ex) {
db.getLogger().log(Level.SEVERE,"Cannot store remote app to "+getFile()+" due to exception.",ex);
return false;
}
}
public boolean isAvailable()
{
URI uri = getIntrospection();
if (uri==null) {
uri = getRoot();
}
AuthCredentials auth = getAuthCredentials();
Client client = new Client(new Context(db.getLogger()),Protocol.valueOf(uri.getScheme()));
client.getContext().getAttributes().put("hostnameVerifier", org.apache.commons.ssl.HostnameVerifier.DEFAULT);
Request request = new Request(Method.HEAD,uri.toString());
request.setChallengeResponse(new ChallengeResponse(ChallengeScheme.HTTP_BASIC,auth.getName(),auth.getPassword()));
Response response = client.handle(request);
return response.getStatus().isSuccess() || response.getStatus().equals(Status.CLIENT_ERROR_NOT_FOUND);
}
}