D. How to customize a UWS ?

7. Serializations

As said previously all UWS resources are formatted by default in XML according to the IVOA Recommendation. With this library it is possible to manage more formats. Besides the format to use is choosen in function of the HTTP header Accept, and so, of the specified MIME types.

The classes UWSSerializer and SerializableUWSObject

The class UWSSerializer is the abstract class used to define the serialization of any UWS resource in a given format. XMLSerializer and JSONSerializer correspond respectively to the XML and the JSON formats.

Notes:

All UWS objects extend the abstract class SerializableUWSObject. Only one function is abstract: serialize(UWSSerializer, String ownerId). It lets calling the good method of the given UWSSerializer (ex: in JobList the function UWSSerializer.getJobList(...) is called) and may consider the given owner ID to adapt the returned content to the current user (ex: in JobList a user can not get the job of another user, he gets only its own jobs). Thus you just have to call any method of SerializableUWSObject on the UWS objects to "serialize" them.

How does it work ?

Any HTTP request sent to a UWS ends with the serialization of a UWS resource. So the corresponding UWS action has to make a serialization of the asked objects in the specified format. As said previously this format is given by the HTTP header Accept. It gives a list of allowed formats which is actually an ordered list of MIME types. The choice of the format to apply is done by the method AbstractUWS.getSerializer(String) which takes the full MIME types list.

Below is the way that the action ListJobs returns the serialization of the specified job list:

public class ListJobs<JL extends JobList<J>, J extends AbstractJob> extends UWSAction<JL, J> {
...
	@Override
	public boolean apply(UWSUrl urlInterpreter, String userId, HttpServletRequest request, HttpServletResponse response) throws UWSException, IOException {
	// Get the jobs list:
		JL jobsList = getJobsList(urlInterpreter);
		
	// Write the jobs list:
		UWSSerializer serializer = uws.getSerializer(request.getHeader("Accept"));
		response.setContentType(serializer.getMimeType());
		jobsList.serialize(response.getOutputStream(), serializer, userId);
		
		return true;
	}
...
}

AbstractUWS has a list of UWSSerializer instances: the attribute serializers. AbstractUWS.getSerializer(String) chooses the serializer corresponding to the prefered MIME types among the given list. If there is no match the default serializer (specified by the attribute defaultSerializer) is returned.

How to customize ?

You can add or remove easily some serializers to you UWS thanks to the functions: addSerializer(UWSSerializer) and removeSerializer(String mimeType).

It is also possible to iterate on all existing serializers thanks to getSerializers().

Besides you can change the default serializer with setDefaultSerializer(String).

As in the version 2 of this library, it is also possible to associate a XML document to a XSLT style-sheet. It must be done in the instance of XMLSerializer used by your UWS, with the function XMLSerializer.setXSLTPath(String). As in the previous version, the function AbstractUWS.setXsltURL(String) still works. But now it calls the function XMLSerializer.setXSLTPath(String) on the used instance of XMLSerializer.

Here is how this function could be used to set the XSLT style sheet to any XML output:

public class UWSAlgorithms extends HttpServlet {
...
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		...
		// Sets the XSLT URL:
		uws.setXsltURL(req.getContextPath()+"/styles/uws.xsl");
		...
	}
...
}

Warnings:

Trick !

Some formats are often associated with several MIME types, like XML (application/xml and text/xml). If you want to associate several MIME types to one serializer, you can add manually some entries in the map attribute serializers. For instance:

public class MyExtendedUWS extends ExtendedUWS {

	public MyExtendedUWS(URL baseURL) throws UWSException {
		super(baseURL);
		addUWSAction(0, new AboutAction<JobList<AbstractJob>, AbstractJob>(this));
		if (hasSerializerFor(UWSSerializer.MIME_TYPE_XML))
			serializers.put("text/xml", getSerializer(UWSSerializer.MIME_TYPE_XML));
	}
...
}
(MIME_TYPE_XML="application/xml")