/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.wms.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.HashMap; import java.util.List; import java.util.TimeZone; import org.geoserver.ows.URLMangler.URLType; import org.geoserver.ows.util.ResponseUtils; import org.geoserver.wms.WMS; import org.geoserver.wms.WMSMapContent; import org.geoserver.wms.WMSRequests; import org.geoserver.wms.featureinfo.FeatureTemplate; import org.geotools.map.Layer; import org.opengis.feature.simple.SimpleFeature; /** * 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(WMS wms, SimpleFeature feature, WMSMapContent context){ try { return featureTemplate.link(feature); } catch (IOException ioe){ String nsUri = feature.getType().getName().getNamespaceURI(); String nsPrefix = wms.getNameSpacePrefix(nsUri); HashMap<String,String> params = new HashMap<String,String>(); params.put("format", "application/atom+xml"); params.put("layers", nsPrefix + ":" + feature.getType().getTypeName()); params.put("featureid", feature.getID()); return ResponseUtils.buildURL(context.getRequest().getBaseUrl(), "wms/reflect", params, URLType.SERVICE); } } public static String getEntryURI(WMS wms, SimpleFeature feature, WMSMapContent context){ return getEntryURL(wms, 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(WMSMapContent context){ return WMSRequests.getGetMapUrl(context.getRequest(), null, 0, null, null).replace(' ', '+'); } public static String getFeedURI(WMSMapContent context){ return getFeedURL(context); } public static String getFeedTitle(WMSMapContent context){ StringBuffer title = new StringBuffer(); for( Layer layer : context.layers() ){ title.append(layer.getTitle()).append(","); } title.setLength(title.length()-1); return title.toString(); } public static String getFeedDescription(WMSMapContent context) { StringBuffer description = new StringBuffer(); for (Layer layer : context.layers()) { description.append(layer.getUserData().get("abstract")).append("\n"); } if (description.length() == 0) { return "Auto-generated by geoserver"; } else { description.setLength(description.length() - 1); return description.toString(); } } private static String commaSeparatedLayers(WMSMapContent con){ StringBuilder layers = new StringBuilder(); List<Layer> mapLayers = con.layers(); for (int i = 0; i < mapLayers.size(); i++){ layers.append(mapLayers.get(i).getTitle()); if (i < mapLayers.size() - 1) layers.append(","); } return layers.toString(); } }