package tap.resource; /* * This file is part of TAPLibrary. * * TAPLibrary is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * TAPLibrary is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with TAPLibrary. If not, see <http://www.gnu.org/licenses/>. * * Copyright 2012-2016 - UDS/Centre de DonnĂ©es astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ import java.io.IOException; import java.io.PrintWriter; import java.util.Iterator; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import tap.TAPException; import uk.ac.starlink.votable.VOSerializer; import uws.UWSToolBox; /** * <p>TAP resource describing the capabilities of a TAP service.</p> * * <p>This resource just return an XML document giving a description of the TAP service and list all its VOSI resources.</p> * * @author Grégory Mantelet (CDS;ARI) * @version 2.1 (07/2016) */ public class Capabilities implements TAPResource, VOSIResource { /** Name of this TAP resource. */ public static final String RESOURCE_NAME = "capabilities"; /** Representation of the whole TAP service. This object list all available resources ; * resources that correspond to the capabilities this resource must list. */ private final TAP tap; /** <p>URL toward this TAP resource. * This URL is particularly important for its declaration in the capabilities of the TAP service.</p> * * <p><i>Note: By default, it is just the name of this resource. It is updated after initialization of the service * when the TAP service base URL is communicated to its resources. Then, it is: baseTAPURL + "/" + RESOURCE_NAME.</i></p> */ protected String accessURL = getName(); /** The path of the XSLT style-sheet to apply. * @version 2.1 */ protected String xsltPath = null; /** * Build a "/capabilities" resource. * * @param tap Object representation of the whole TAP service. */ public Capabilities(final TAP tap){ this.tap = tap; } /** * Gets the path/URL of the XSLT style-sheet to use. * * @return XSLT path/url. * * @version 2.1 */ public final String getXSLTPath(){ return xsltPath; } /** * Sets the path/URL of the XSLT style-sheet to use. * * @param path The new XSLT path/URL. * * @version 2.1 */ public final void setXSLTPath(final String path){ if (path == null) xsltPath = null; else{ xsltPath = path.trim(); if (xsltPath.isEmpty()) xsltPath = null; } } @Override public final void setTAPBaseURL(String baseURL){ accessURL = ((baseURL == null) ? "" : (baseURL + "/")) + getName(); } @Override public final String getName(){ return RESOURCE_NAME; } @Override public final String getStandardID(){ return "ivo://ivoa.net/std/VOSI#capabilities"; } @Override public final String getAccessURL(){ return accessURL; } @Override public String getCapability(){ return getDefaultCapability(this); } @Override public void init(ServletConfig config) throws ServletException{ ; } @Override public void destroy(){ ; } @Override public boolean executeResource(HttpServletRequest request, HttpServletResponse response) throws IOException, TAPException{ /* "In the REST binding, the support interfaces shall have distinct URLs in the HTTP scheme and shall be accessible by the GET operation in the HTTP protocol. * The response to an HTTP POST, PUT or DELETE to these resources is not defined by this specification. However, if an implementation has no special action * to perform for these requests, the normal response would be a 405 "Method not allowed" error." * (Extract of the VOSI definition: http://www.ivoa.net/documents/VOSI/20100311/PR-VOSI-1.0-20100311.html#sec2) */ if (!request.getMethod().equalsIgnoreCase("GET")) throw new TAPException("The CAPABILITIES resource is only accessible in HTTP-GET! No special action can be perfomed with another HTTP method.", HttpServletResponse.SC_METHOD_NOT_ALLOWED); // Set the response MIME type (XML): response.setContentType("application/xml"); // Set the character encoding: response.setCharacterEncoding(UWSToolBox.DEFAULT_CHAR_ENCODING); // Get the response stream: PrintWriter out = response.getWriter(); // Write the XML document header: out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); if (xsltPath != null){ out.print("<?xml-stylesheet type=\"text/xsl\" "); out.print(VOSerializer.formatAttribute("href", xsltPath)); out.println("?>"); } out.print("<vosi:capabilities xmlns:vosi=\"http://www.ivoa.net/xml/VOSICapabilities/v1.0\""); out.print(" xmlns:tr=\"http://www.ivoa.net/xml/TAPRegExt/v1.0\""); out.print(" xmlns:vr=\"http://www.ivoa.net/xml/VOResource/v1.0\""); out.print(" xmlns:vs=\"http://www.ivoa.net/xml/VODataService/v1.0\""); out.print(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""); out.println(" xsi:schemaLocation=\"http://www.ivoa.net/xml/VOSICapabilities/v1.0 http://www.ivoa.net/xml/VOSICapabilities/v1.0 http://www.ivoa.net/xml/TAPRegExt/v1.0 http://www.ivoa.net/xml/TAPRegExt/v1.0 http://www.ivoa.net/xml/VOResource/v1.0 http://www.ivoa.net/xml/VOResource/v1.0 http://www.ivoa.net/xml/VODataService/v1.0 http://www.ivoa.net/xml/VODataService/v1.0\">"); // Write the full list of this TAP capabilities: out.print(tap.getCapability()); // Write the capabilities of all VOSI resources: Iterator<TAPResource> it = tap.getResources(); while(it.hasNext()){ TAPResource res = it.next(); if (res instanceof VOSIResource){ String cap = ((VOSIResource)res).getCapability(); if (cap != null){ out.println(); out.print(cap); } } } // Write the end of the XML document: out.println("\n</vosi:capabilities>"); out.flush(); return true; } /** * Write the XML description of the given VOSI resource. * * @param res Resource to describe in XML. * * @return XML description of the given VOSI resource. */ public static final String getDefaultCapability(final VOSIResource res){ return "\t<capability " + VOSerializer.formatAttribute("standardID", res.getStandardID()) + ">\n" + "\t\t<interface xsi:type=\"vs:ParamHTTP\" role=\"std\">\n" + "\t\t\t<accessURL use=\"full\"> " + ((res.getAccessURL() == null) ? "" : VOSerializer.formatText(res.getAccessURL())) + " </accessURL>\n" + "\t\t</interface>\n" + "\t</capability>"; } }