package org.vfny.geoserver.wms.responses.map.georss;
import java.io.IOException;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import org.geoserver.wms.util.WMSRequests;
import org.geotools.map.MapLayer;
import org.opengis.feature.simple.SimpleFeature;
import org.vfny.geoserver.util.Requests;
import org.vfny.geoserver.wms.WMSMapContext;
import org.vfny.geoserver.wms.responses.featureInfo.FeatureTemplate;
/**
* The AtomUtils class provides some static methods useful in producing atom metadata related to
* GeoServer features.
*
* @author David Winslow
*/
public final class AtomUtils {
/**
* A date formatting object that does most of the formatting work for RFC3339. Note that since
* Java's SimpleDateFormat does not provide all the facilities needed for RFC3339 there is still
* some custom code to finish the job.
*/
private static DateFormat rfc3339 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
/**
* A number formatting object to format the the timezone offset info in RFC3339 output.
*/
private static NumberFormat doubleDigit = new DecimalFormat("00");
/**
* A FeatureTemplate used for formatting feature info.
* @TODO: Are these things threadsafe?
*/
private static FeatureTemplate featureTemplate = new FeatureTemplate();
/**
* This is a utility class so don't allow instantiation.
*/
private AtomUtils(){ /* Nothing to do */ }
/**
* Format dates as specified in rfc3339 (required for Atom dates)
* @param d the Date to be formatted
* @return the formatted date
*/
public static String dateToRFC3339(Date d){
StringBuilder result = new StringBuilder(rfc3339.format(d));
Calendar cal = new GregorianCalendar();
cal.setTime(d);
cal.setTimeZone(TimeZone.getDefault());
int offset_millis = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET);
int offset_hours = Math.abs(offset_millis / (1000 * 60 * 60));
int offset_minutes = Math.abs((offset_millis / (1000 * 60)) % 60);
if (offset_millis == 0) {
result.append("Z");
} else {
result
.append((offset_millis > 0) ? "+" : "-")
.append(doubleDigit.format(offset_hours))
.append(":")
.append(doubleDigit.format(offset_minutes));
}
return result.toString();
}
//TODO: use an html based output format
public static String getEntryURL(SimpleFeature feature, WMSMapContext context){
String nsUri = feature.getType().getName().getNamespaceURI();
String nsPrefix = context.getRequest().getWMS().getNameSpacePrefix(nsUri);
return Requests.getBaseUrl(
context.getRequest().getHttpServletRequest(),
context.getRequest().getWMS().getGeoServer()
)
+ "wms/reflect?format=application/atom+xml&layers="
+ nsPrefix + ":" + feature.getType().getTypeName()
+ "&featureid=" + feature.getID();
}
public static String getEntryURI(SimpleFeature feature, WMSMapContext context){
return getEntryURL(feature, context);
}
public static String getFeatureTitle(SimpleFeature feature){
try{
return featureTemplate.title(feature);
} catch (IOException ioe){
return feature.getID();
}
}
public static String getFeatureDescription(SimpleFeature feature){
try{
return featureTemplate.description(feature);
} catch (IOException ioe) {
return feature.getID();
}
}
public static String getFeedURL(WMSMapContext context){
return WMSRequests.getGetMapUrl(context.getRequest(), null, 0, null, null).replace(' ', '+');
}
public static String getFeedURI(WMSMapContext context){
return getFeedURL(context);
}
public static String getFeedTitle(WMSMapContext context){
StringBuffer title = new StringBuffer();
for (int i = 0; i < context.getLayerCount(); i++) {
MapLayer layer = context.getLayer(i);
title.append(layer.getTitle()).append(",");
}
title.setLength(title.length()-1);
return title.toString();
}
private static String commaSeparatedLayers(WMSMapContext con){
StringBuilder layers = new StringBuilder();
MapLayer[] mapLayers = con.getLayers();
for (int i = 0; i < mapLayers.length; i++){
layers.append(mapLayers[i].getTitle());
if (i < mapLayers.length - 1) layers.append(",");
}
return layers.toString();
}
}