Here's the basics of what I'm trying to do. I'm working on a project where I'm creating a mashup page from various web APIs. The mashup page contains country information.
I have a BLL layer where I create the mashup page (html page with country input using Chunk Library). This is the method used to set up the template
public String GetTemplate(Country country) throws IOException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL resource = classLoader.getResource("BLL/themes/page.html");
Theme theme = new Theme("src/BLL", "themes");
Chunk html = theme.makeChunk("page", "html");
html.set("countryName", country.getName());
html.set("countryCode", country.getCode());
html.set("countryContinent", country.getContinent());
html.set("countryCapital", country.getCapital());
html.set("countryAreaInSqKm", country.getAreaInSqKm());
html.set("countryPopulation", country.getPopulation());
html.set("countryCurrencyCode", country.getCurrencyCode());
html.set("countryExchangeRate", country.getExchangeRate());
html.set("countryFlagUrl", country.getFlagUrl());
html.set("countryDescription", country.getDescription());
html.set("countryMap", country.getMapLocation());
return html.toString();
}
Eventually I'll be using a database for all available countries.
So what I want to do on the Restlet server is iterate through all countries, like so, or in a similar manner?
public Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attach("/countries/", Countries.class);
for (Country country : cm.GetAllCountries()) {
router.attach("/countries/" + country.getName(), new CountryTemplate(country));
// Obviously this doesn't work, and it doesn't work with getClass() either.
}
return router;
}
As such I'm trying to get my resource to return the html in the get method (from the TemplateManager):
public class CountryTemplate extends ServerResource {
CountryManager cm = null;
TemplateManager tm = null;
Country country = null;
public CountryTemplate(Country _country) throws Exception {
cm = new CountryManager();
tm = new TemplateManager();
country = _country;
}
@Get("html")
public String getTemplate() throws IOException, RemoteException, UnsupportedCurrencyException {
return tm.GetTemplate(country);
}
}
Is there indeed a way to do it like this, or am I approaching this all wrong?
If anyone else should find themselves here, Tim's code worked exactly as required. The posted code was altered to his version.
Instead of trying to hard-code dynamic dynamic behaviors of your REST resources, you should be using a query parameter.
First, you can create a new REST resource /countries/html/
and bind it to the class CountryResource
. This resource will accept a query parameter countryID
corresponding to the country whose HTML you want to access:
public Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attach("/countries/", Countries.class);
router.attach("/countries/html/", CountryResource.class);
return router;
}
In your definition for CountryResource
, you can access the query parameter countryID
to get the appropriate HTML content:
public class CountryResource extends ServerResource {
CountryManager cm;
TemplateManager tm;
public CountryTemplate() throws Exception {
// Note: I usually do NOT define a constructor using Restlets,
// but you should be OK doing this
cm = new CountryManager();
tm = new TemplateManager();
}
@Get("html")
public String getTemplate() throws IOException, RemoteException, UnsupportedCurrencyException {
String countryID = getQueryValue("countryID");
Country country = tm.getCountry(countryID);
return tm.GetTemplate(country);
}
}
I assume that the CountryManager
has a method getCountry()
which can return a Country
object based on an input String. If such a method does not currently exist, then you will need to find a way to map incoming query parameters to actual Country
objects in your code.