}
@SuppressWarnings("rawtypes")
@Override
public GetMapRequest read(Object request, Map kvp, Map rawKvp) throws Exception {
GetMapRequest getMap = (GetMapRequest) super.read(request, kvp, rawKvp);
// set the raw params used to create the request
getMap.setRawKvp(rawKvp);
// wms 1.3, srs changed to crs
if (kvp.containsKey("crs")) {
getMap.setSRS((String)kvp.get("crs"));
}
// do some additional checks
// srs
String epsgCode = getMap.getSRS();
epsgCode = WMS.toInternalSRS(epsgCode, WMS.version(getMap.getVersion()));
getMap.setSRS(epsgCode);
if (epsgCode != null) {
try {
// set the crs as well
CoordinateReferenceSystem mapcrs = CRS.decode(epsgCode);
getMap.setCrs(mapcrs);
} catch (Exception e) {
// couldnt make it - we send off a service exception with the
// correct info
throw new ServiceException("Error occurred decoding the espg code " + epsgCode, e,
WMSErrorCode.INVALID_CRS.get(getMap.getVersion()));
}
}
// remote OWS
String remoteOwsType = getMap.getRemoteOwsType();
remoteOwsType = remoteOwsType != null ? remoteOwsType.toUpperCase() : null;
if (remoteOwsType != null && !"WFS".equals(remoteOwsType)) {
throw new ServiceException("Unsupported remote OWS type '" + remoteOwsType + "'");
}
// remote OWS url
URL remoteOwsUrl = getMap.getRemoteOwsURL();
if (remoteOwsUrl != null && remoteOwsType == null) {
throw new ServiceException("REMOTE_OWS_URL specified, but REMOTE_OWS_TYPE is missing");
}
final List<Object> requestedLayerInfos = new ArrayList<Object>();
// layers
String layerParam = (String) rawKvp.get("LAYERS");
if (layerParam != null) {
List<String> layerNames = KvpUtils.readFlat(layerParam);
requestedLayerInfos.addAll(parseLayers(layerNames, remoteOwsUrl, remoteOwsType));
List<MapLayerInfo> layers = new ArrayList<MapLayerInfo>();
for (Object o : requestedLayerInfos) {
if (o instanceof LayerInfo) {
layers.add(new MapLayerInfo((LayerInfo) o));
} else if (o instanceof LayerGroupInfo) {
for (LayerInfo l : ((LayerGroupInfo) o).getLayers()) {
layers.add(new MapLayerInfo(l));
}
} else if (o instanceof MapLayerInfo) {
// it was a remote OWS layer, add it directly
layers.add((MapLayerInfo) o);
}
}
getMap.setLayers(layers);
}
// raw styles parameter
String stylesParam = (String) kvp.get("STYLES");
List<String> styleNameList = new ArrayList<String>();
if (stylesParam != null) {
styleNameList.addAll(KvpUtils.readFlat(stylesParam));
}
// pre parse filters
List<Filter> filters = parseFilters(getMap);
// styles
// process SLD_BODY, SLD, then STYLES parameter
if (getMap.getSldBody() != null) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("Getting layers and styles from SLD_BODY");
}
if (getMap.getValidateSchema().booleanValue()) {
ByteArrayInputStream stream = new ByteArrayInputStream(getMap.getSldBody()
.getBytes());
List errors = validateSld(stream, getMap);
if (errors.size() != 0) {
throw new ServiceException(SLDValidator.getErrorMessage(
new ByteArrayInputStream(getMap.getSldBody().getBytes()), errors));
}
}
InputStream input = new ByteArrayInputStream(getMap.getSldBody().getBytes());
StyledLayerDescriptor sld = parseSld(getMap, input);
processSld(getMap, requestedLayerInfos, sld, styleNameList);
// set filter in, we'll check consistency later
getMap.setFilter(filters);
} else if (getMap.getSld() != null) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("Getting layers and styles from reomte SLD");
}
URL sldUrl = getMap.getSld();
if (getMap.getValidateSchema().booleanValue()) {
InputStream input = Requests.getInputStream(sldUrl);
List errors = null;
try {
errors = validateSld(input, getMap);
} finally {
input.close();
}
if ((errors != null) && (errors.size() != 0)) {
input = Requests.getInputStream(sldUrl);
try {
throw new ServiceException(SLDValidator.getErrorMessage(input, errors));
} finally {
input.close();
}
}
}
// JD: GEOS-420, Wrap the sldUrl in getINputStream method in order
// to do compression
InputStream input = Requests.getInputStream(sldUrl);
try {
StyledLayerDescriptor sld = parseSld(getMap, input);
processSld(getMap, requestedLayerInfos, sld, styleNameList);
} finally {
input.close();
}
// set filter in, we'll check consistency later
getMap.setFilter(filters);
} else {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("Getting layers and styles from LAYERS and STYLES");
}
// ok, parse the styles parameter in isolation
if (styleNameList.size() > 0) {
List<Style> parseStyles = parseStyles(styleNameList);
getMap.setStyles(parseStyles);
}
// first, expand base layers and default styles
if (isParseStyle() && requestedLayerInfos.size() > 0) {
List<Style> oldStyles = getMap.getStyles() != null ? new ArrayList(
getMap.getStyles()) : new ArrayList();
List<Style> newStyles = new ArrayList<Style>();
List<Filter> newFilters = filters == null ? null : new ArrayList<Filter>();
for (int i = 0; i < requestedLayerInfos.size(); i++) {
Object o = requestedLayerInfos.get(i);
Style style = oldStyles.isEmpty() ? null : (Style) oldStyles.get(i);
if (o instanceof LayerGroupInfo) {
LayerGroupInfo groupInfo = (LayerGroupInfo) o;
for (int j = 0; j < groupInfo.getStyles().size(); j++) {
StyleInfo si = groupInfo.getStyles().get(j);
if (si != null){
newStyles.add(si.getStyle());
} else {
LayerInfo layer = groupInfo.getLayers().get(j);
newStyles.add(getDefaultStyle(layer));
}
}
// expand the filter on the layer group to all its sublayers
if (filters != null) {
for (int j = 0; j < groupInfo.getLayers().size(); j++) {
newFilters.add(getFilter(filters, i));
}
}
} else if (o instanceof LayerInfo) {
style = oldStyles.size() > 0 ? oldStyles.get(i) : null;
if (style != null) {
newStyles.add(style);
} else {
LayerInfo layer = (LayerInfo) o;
newStyles.add(getDefaultStyle(layer));
}
// add filter if needed
if (filters != null)
newFilters.add(getFilter(filters, i));
} else if (o instanceof MapLayerInfo) {
style = oldStyles.size() > 0 ? oldStyles.get(i) : null;
if (style != null) {
newStyles.add(style);
} else {
throw new ServiceException("no style requested for layer "
+ ((MapLayerInfo) o).getName(), "NoDefaultStyle");
}
// add filter if needed
if (filters != null)
newFilters.add(getFilter(filters, i));
}
}
getMap.setStyles(newStyles);
getMap.setFilter(newFilters);
}
// then proceed with standard processing
List<MapLayerInfo> layers = getMap.getLayers();
if (isParseStyle() && (layers != null) && (layers.size() > 0)) {
final List styles = getMap.getStyles();
if (layers.size() != styles.size()) {
String msg = layers.size() + " layers requested, but found " + styles.size()
+ " styles specified. ";
throw new ServiceException(msg, getClass().getName());
}
for (int i = 0; i < styles.size(); i++) {
Style currStyle = (Style) getMap.getStyles().get(i);
if (currStyle == null)
throw new ServiceException(
"Could not find a style for layer "
+ getMap.getLayers().get(i).getName()
+ ", either none was specified or no default style is available for it",
"NoDefaultStyle");
checkStyle(currStyle, layers.get(i));
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine(new StringBuffer("establishing ").append(currStyle.getName())
.append(" style for ").append(layers.get(i).getName()).toString());
}
}
}
// check filter size matches with the layer list size
List mapFilters = getMap.getFilter();
List<MapLayerInfo> mapLayers = getMap.getLayers();
if (mapFilters != null && mapFilters.size() != mapLayers.size()) {
String msg = mapLayers.size() + " layers requested, but found " + mapFilters.size()
+ " filters specified. ";
throw new ServiceException(msg, getClass().getName());
}
}
// check the view params
List<Map<String, String>> viewParams = getMap.getViewParams();
if(viewParams != null && viewParams.size() > 0) {
int layerCount = getMap.getLayers().size();
// if we have just one replicate over all layers
if(viewParams.size() == 1 && layerCount > 1) {
List<Map<String, String>> replacement = new ArrayList<Map<String,String>>();
for (int i = 0; i < layerCount; i++) {
replacement.add(viewParams.get(0));
}
getMap.setViewParams(replacement);
} else if(viewParams.size() != layerCount) {
String msg = layerCount + " layers requested, but found " + viewParams.size()
+ " view params specified. ";
throw new ServiceException(msg, getClass().getName());
}