package com.sixsq.slipstream.application;
/*
* +=================================================================+
* SlipStream Server (WAR)
* =====
* Copyright (C) 2013 SixSq Sarl (sixsq.com)
* =====
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* -=================================================================-
*/
import static org.restlet.data.MediaType.APPLICATION_JSON;
import static org.restlet.data.MediaType.APPLICATION_XHTML;
import static org.restlet.data.MediaType.APPLICATION_XML;
import static org.restlet.data.MediaType.TEXT_HTML;
import static org.restlet.data.MediaType.TEXT_PLAIN;
import java.util.List;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.ClientInfo;
import org.restlet.data.Cookie;
import org.restlet.data.MediaType;
import org.restlet.data.Preference;
import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.security.Verifier;
import org.restlet.service.StatusService;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.Text;
import org.w3c.dom.Document;
import com.sixsq.slipstream.configuration.Configuration;
import com.sixsq.slipstream.cookie.CookieUtils;
import com.sixsq.slipstream.exceptions.ConfigurationException;
import com.sixsq.slipstream.exceptions.Util;
import com.sixsq.slipstream.exceptions.ValidationException;
import com.sixsq.slipstream.persistence.ServiceConfiguration;
import com.sixsq.slipstream.persistence.ServiceConfigurationParameter;
import com.sixsq.slipstream.persistence.User;
import com.sixsq.slipstream.util.HtmlUtil;
import com.sixsq.slipstream.util.ResourceUriUtil;
import com.sixsq.slipstream.util.SerializationUtil;
import com.sixsq.slipstream.util.XmlUtil;
public class CommonStatusService extends StatusService {
@Root(name="error")
private static class ErrorElement {
@Attribute
private int code;
@Attribute
private String reason;
@Attribute
private String detail;
@Attribute
private String specificationUri;
@Text
private String text;
public ErrorElement(Status status) {
this(status.getCode(), status.getReasonPhrase(), status.getDescription(), status.getUri(),
status.getDescription());
}
public ErrorElement(int code, String reason, String detail, String specificationUri, String text) {
this.code = code;
this.reason = reason;
this.detail = detail;
this.specificationUri = specificationUri;
this.text = "\n" + text + "\n";
}
}
@Override
public Representation getRepresentation(Status status, Request request, Response response) {
try {
reloadParameters();
} catch (ConfigurationException e) {
Util.throwConfigurationException(e);
} catch (ValidationException e) {
Util.throwClientValidationError(e.getMessage());
}
Representation representation = null;
User user = null;
Cookie cookie = CookieUtils.extractAuthnCookie(request);
if (CookieUtils.verifyAuthnCookie(cookie) == Verifier.RESULT_VALID) {
String username = CookieUtils.getCookieUsername(cookie);
try {
user = User.loadByName(username);
} catch (Exception e) {
e.printStackTrace();
}
}
String baseUrlSlash = ResourceUriUtil.getBaseUrlSlash(request);
ClientInfo clientInfo = request.getClientInfo();
List<Preference<MediaType>> mediaTypes = clientInfo.getAcceptedMediaTypes();
for (Preference<MediaType> preference : mediaTypes) {
MediaType desiredMediaType = preference.getMetadata();
if (TEXT_HTML.isCompatible(desiredMediaType)) {
return toXhtml(status, request, response, user, baseUrlSlash);
} else if (APPLICATION_XHTML.isCompatible(desiredMediaType)) {
return toXhtml(status, request, response, user, baseUrlSlash);
} else if (APPLICATION_JSON.isCompatible(desiredMediaType)) {
return toJson(status);
} else if (TEXT_PLAIN.isCompatible(desiredMediaType)) {
return toTxt(status);
} else if (APPLICATION_XML.isCompatible(desiredMediaType)) {
return toXml(status);
}
}
return representation;
}
private Representation toXhtml(Status status, Request request, Response response, User user, String baseUrlSlash) {
String metadata = "";
if (user != null) {
Document doc = SerializationUtil.toXmlDocument(user);
XmlUtil.addUser(doc, user);
metadata = SerializationUtil.documentToString(doc);
}
return new StringRepresentation(HtmlUtil.toHtmlError(metadata, status.getDescription(), status.getCode(),
request), MediaType.TEXT_HTML);
}
private Representation toJson(Status status) {
StringBuilder json = new StringBuilder();
json.append("{\n");
json.append(" \"error\": {\n");
json.append(" \"code\": \"" + status.getCode() + "\"");
if (status.getReasonPhrase() != null)
json.append(",\n \"reason\": \"" + status.getReasonPhrase() + "\"");
if (status.getDescription() != null)
json.append(",\n \"detail\": \"" + status.getDescription() + "\"");
if (status.getUri() != null)
json.append(",\n \"specificationUri\": \"" + status.getUri() + "\"");
json.append("\n }\n");
json.append("}");
Representation representation = new StringRepresentation(json.toString());
representation.setMediaType(APPLICATION_JSON);
return representation;
}
private Representation toTxt(Status status) {
StringBuilder txt = new StringBuilder();
txt.append(status.getCode());
if (status.getReasonPhrase() != null)
txt.append(" - " + status.getReasonPhrase());
if (status.getDescription() != null)
txt.append("\n" + status.getDescription());
Representation representation;
representation = new StringRepresentation(txt.toString());
representation.setMediaType(TEXT_PLAIN);
return representation;
}
private Representation toXml(Status status) {
String xml = SerializationUtil.toXmlString(new ErrorElement(status));
Representation representation = new StringRepresentation(xml);
representation.setMediaType(APPLICATION_XML);
return representation;
}
private void reloadParameters() throws ConfigurationException, ValidationException {
Configuration configuration = Configuration.getInstance();
String key = ServiceConfiguration.RequiredParameters.SLIPSTREAM_SUPPORT_EMAIL.getName();
ServiceConfigurationParameter parameter = configuration.getParameters().getParameter(key);
String email = parameter.getValue();
setContactEmail(email);
}
}