All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mapfish.print.servlet.oldapi.OldAPIRequestConverter Maven / Gradle / Ivy

There is a newer version: 3.22.0
Show newest version
package org.mapfish.print.servlet.oldapi;


import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mapfish.print.config.Configuration;
import org.mapfish.print.config.OldApiConfig;
import org.mapfish.print.config.Template;
import org.mapfish.print.processor.Processor;
import org.mapfish.print.processor.jasper.LegendProcessor;
import org.mapfish.print.processor.jasper.TableProcessor;
import org.mapfish.print.processor.map.CreateMapProcessor;
import org.mapfish.print.servlet.MapPrinterServlet;
import org.mapfish.print.wrapper.PArray;
import org.mapfish.print.wrapper.PObject;
import org.mapfish.print.wrapper.json.PJsonArray;
import org.mapfish.print.wrapper.json.PJsonObject;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import static org.mapfish.print.Constants.JSON_LAYOUT_KEY;
import static org.mapfish.print.Constants.OUTPUT_FILENAME_KEY;
import static org.mapfish.print.servlet.MapPrinterServlet.JSON_OUTPUT_FORMAT;

/**
 * Converter for print requests of the old API.
 */
public final class OldAPIRequestConverter {

    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(OldAPIRequestConverter.class);

    private static final Set NON_CUSTOM_PARAMS = Sets.newHashSet(
            "units", "srs", "layout", "dpi", "layers", "pages", "legends",
            "geodetic", "outputFilename", "outputFormat", "app");

    private OldAPIRequestConverter() {
    }

    /**
     * Converts a print request of the old API into the new request format.
     * 

* Note that the converter does not support all features of the old API, for example only requests * containing a single map are supported. * * @param oldRequest the request in the format of the old API * @param configuration the configuration */ public static PJsonObject convert(final PJsonObject oldRequest, final Configuration configuration) throws JSONException { final String layout = oldRequest.getString(JSON_LAYOUT_KEY); if (configuration.getTemplate(layout) == null) { throw new IllegalArgumentException("Layout '" + layout + "' is not configured"); } final JSONObject request = new JSONObject(); request.put(JSON_LAYOUT_KEY, oldRequest.getString(JSON_LAYOUT_KEY)); if (oldRequest.has(OUTPUT_FILENAME_KEY)) { request.put(OUTPUT_FILENAME_KEY, oldRequest.getString(OUTPUT_FILENAME_KEY)); } if (oldRequest.has(JSON_OUTPUT_FORMAT)) { request.put(JSON_OUTPUT_FORMAT, oldRequest.getString(JSON_OUTPUT_FORMAT)); } request.put(MapPrinterServlet.JSON_ATTRIBUTES, getAttributes(oldRequest, configuration.getTemplate(layout))); return new PJsonObject(request, "spec"); } private static JSONObject getAttributes(final PJsonObject oldRequest, final Template template) throws JSONException { final JSONObject attributes = new JSONObject(); setMapAttribute(attributes, oldRequest, template); setTableAttribute(attributes, oldRequest, template); setLegendAttribute(attributes, oldRequest, template); // TODO legends, scales, ... // copy custom parameters Iterator keys = oldRequest.keys(); while (keys.hasNext()) { String key = keys.next(); if (!NON_CUSTOM_PARAMS.contains(key)) { attributes.put(key, oldRequest.getInternalObj().get(key)); } } return attributes; } private static void setMapAttribute( final JSONObject attributes, final PJsonObject oldRequest, final Template template) throws JSONException { final CreateMapProcessor mapProcessor = getMapProcessor(template); final PJsonObject oldMapPage = (PJsonObject) getOldMapPage(oldRequest); if (mapProcessor == null) { if (oldMapPage == null) { // no map, no work return; } else { LOGGER.warn( "The request json data has attribute information for creating the map but config " + "does not have a" + "map attribute. Check that the request and the config.yaml are correct."); return; } } else if (oldMapPage == null) { LOGGER.warn("The request json data does not have attribute information for creating the map." + " Check that the request and the config.yaml are correct."); return; } String mapAttributeName = "map"; if (mapProcessor.getInputMapperBiMap().containsValue("map")) { mapAttributeName = mapProcessor.getInputMapperBiMap().inverse().get("map"); } final JSONObject map = new JSONObject(); attributes.put(mapAttributeName, map); if (oldRequest.has("srs")) { map.put("projection", oldRequest.getString("srs")); } if (oldRequest.has("dpi")) { map.put("dpi", oldRequest.getInt("dpi")); } if (oldMapPage.has("rotation")) { // rotation must be inverted map.put("rotation", -oldMapPage.getDouble("rotation")); } if (oldMapPage.has("bbox")) { map.put("bbox", oldMapPage.getInternalObj().getJSONArray("bbox")); } else if (oldMapPage.has("center") && oldMapPage.has("scale")) { map.put("center", oldMapPage.getInternalObj().getJSONArray("center")); map.put("scale", oldMapPage.getDouble("scale")); } setMapLayers(map, oldRequest, template.getConfiguration().getOldApi()); } private static CreateMapProcessor getMapProcessor(final Template template) { CreateMapProcessor mapProcessor = null; for (Processor processor: template.getProcessors()) { if (processor instanceof CreateMapProcessor) { if (mapProcessor == null) { mapProcessor = (CreateMapProcessor) processor; } else { throw new UnsupportedOperationException("Template contains " + "more than one map configuration. The " + "legacy API " + "supports only one map per template."); } } } return mapProcessor; } private static PObject getOldMapPage(final PJsonObject oldRequest) { final PArray pages = oldRequest.getArray("pages"); PObject mapPage = null; for (int i = 0; i < pages.size(); i++) { final PObject page = pages.getObject(i); if (isMapPage(page)) { if (mapPage == null) { mapPage = page; } else { throw new UnsupportedOperationException("Request contains " + "more than one page with a map. The " + "legacy API " + "supports only one map per report."); } } } return mapPage; } private static boolean isMapPage(final PObject page) { if (page.has("bbox") || (page.has("center") && page.has("scale"))) { return page.optBool("showMap", true); } return false; } private static void setMapLayers( final JSONObject map, final PJsonObject oldRequest, final OldApiConfig oldApi) throws JSONException { final JSONArray layers = new JSONArray(); map.put("layers", layers); if (!oldRequest.has("layers")) { return; } PArray oldLayers = oldRequest.getArray("layers"); if (oldApi.isLayersFirstIsBaseLayer()) { for (int i = oldLayers.size() - 1; i > -1; i--) { PJsonObject oldLayer = (PJsonObject) oldLayers.getObject(i); layers.put(OldAPILayerConverter.convert(oldLayer, oldApi)); } } else { for (int i = 0; i < oldLayers.size(); i++) { PJsonObject oldLayer = (PJsonObject) oldLayers.getObject(i); layers.put(OldAPILayerConverter.convert(oldLayer, oldApi)); } } } /** * Converts the old API legend requestData. "legends": [{ "name": "", "classes": [{ "name": "test", * "icons": ["http://ref.geoview.bl.ch/print3/wsgi/mapserv_proxy?"] }] }] *

* to the new API: "legend": { "name": "", "classes": [{ "name": "Arbres", "icons": * ["http://localhost:9876/e2egeoserver/www/legends/arbres.png"] }, { "name": "Peturbations", "icons": * ["http://localhost:9876/e2egeoserver/www/legends/perturbations.png"] }, { "name": "Points de vente", * "icons": ["http://localhost:9876/e2egeoserver/www/legends/points-de-vente.png"] }, { "name": * "Stationement", "icons": ["http://localhost:9876/e2egeoserver/www/legends/stationement.png"] }] }, */ private static void setLegendAttribute( final JSONObject attributes, final PJsonObject oldRequest, final Template template) throws JSONException { final List legendProcessors = getLegendProcessor(template); PJsonArray oldLegendJson = getLegendJson(oldRequest); if (legendProcessors.isEmpty()) { if (oldLegendJson == null) { // no table, no work return; } else { LOGGER.warn( "The request json data has attribute information for creating the map but config " + "does not have a" + "map attribute. Check that the request and the config.yaml are correct."); return; } } else if (oldLegendJson == null) { LOGGER.warn("Configuration expects a table, but no table data is defined in the request"); oldLegendJson = new PJsonArray(oldRequest, new JSONArray(), "generated"); } if (legendProcessors.size() != oldLegendJson.size()) { LOGGER.warn( "Not all legends processors have request data. There are " + legendProcessors.size() + " and there are " + oldLegendJson.size() + " legend request objects."); } String legendAttName = "legend"; for (int i = 0; i < legendProcessors.size(); i++) { LegendProcessor legendProcessor = legendProcessors.get(i); if (legendProcessor.getInputMapperBiMap().containsValue("legend")) { legendAttName = legendProcessor.getInputMapperBiMap().inverse().get("legend"); } final JSONObject value; if (oldLegendJson.size() > i) { value = oldLegendJson.getJSONObject(i).getInternalObj(); } else { value = new JSONObject(); } attributes.put(legendAttName, value); } if (legendProcessors.size() < oldLegendJson.size()) { JSONObject newApiValue = new JSONObject(); JSONArray classes = new JSONArray(); newApiValue.put("classes", classes); classes.put(attributes.get(legendAttName)); attributes.put(legendAttName, newApiValue); for (int i = legendProcessors.size(); i < oldLegendJson.size(); i++) { classes.put(oldLegendJson.getJSONObject(i).getInternalObj()); } } } private static PJsonArray getLegendJson(final PJsonObject oldRequest) { return oldRequest.optJSONArray("legends"); } private static List getLegendProcessor(final Template template) { List processors = Lists.newArrayList(); for (Processor processor: template.getProcessors()) { if (processor instanceof LegendProcessor) { LegendProcessor legendProcessor = (LegendProcessor) processor; processors.add(legendProcessor); } } return processors; } /** * Converts a table definition from something like: *

* "table":{ "data":[ { "col0":"a", "col1":"b", "col2":"c" }, { "col0":"d", "col1":"e", "col2":"f" }, {}, * {} ], "columns":[ "col0", "col1", "col2" ] }, "col0":"Column 1", "col1":"Column 2", "col2":"Column 3" *

* ... to ...: *

* "table": { "columns": ["Column 1", "Column 2", "Column 3"], "data": [ ["a", "b", "c"], ["d", "e", "f"] * ] }, */ private static void setTableAttribute( final JSONObject attributes, final PJsonObject oldRequest, final Template template) throws JSONException { final TableProcessor tableProcessor = getTableProcessor(template); PJsonObject oldTablePage = (PJsonObject) getOldTablePage(oldRequest); if (tableProcessor == null) { if (oldTablePage == null) { // no table, no work return; } else { LOGGER.warn( "The request json data has attribute information for creating the map but config " + "does not have a" + "map attribute. Check that the request and the config.yaml are correct."); return; } } else if (oldTablePage == null) { LOGGER.warn("Configuration expects a table, but no table data is defined in the request"); oldTablePage = new PJsonObject(oldRequest, new JSONObject(), "generated"); } String tableAttributeName = "table"; if (tableProcessor.getInputMapperBiMap().containsValue("table")) { tableAttributeName = tableProcessor.getInputMapperBiMap().inverse().get("table"); } final JSONObject table = new JSONObject(); attributes.put(tableAttributeName, table); final List columnKeys = getTableColumnKeys(oldTablePage); final List columnLabels = getTableColumnLabels(columnKeys, oldTablePage); final List tableData = getTableData(columnKeys, oldTablePage); table.put("columns", columnLabels); table.put("data", tableData); } private static TableProcessor getTableProcessor(final Template template) { TableProcessor tableProcessor = null; for (Processor processor: template.getProcessors()) { if (processor instanceof TableProcessor) { if (tableProcessor == null) { tableProcessor = (TableProcessor) processor; } else { throw new UnsupportedOperationException("Template contains " + "more than one table configuration. The" + " legacy API " + "supports only one table per template."); } } } return tableProcessor; } private static PObject getOldTablePage(final PJsonObject oldRequest) { final PArray pages = oldRequest.getArray("pages"); PObject tablePage = null; for (int i = 0; i < pages.size(); i++) { final PObject page = pages.getObject(i); if (isTablePage(page)) { if (tablePage == null) { tablePage = page; } else { throw new UnsupportedOperationException("Request contains " + "more than one page with a table. The " + "legacy API " + "supports only one table per report."); } } } return tablePage; } private static boolean isTablePage(final PObject page) { if (page.has("table")) { // page has a table, but let's check if it's not a "dummy" table created by GeoExt, // like this one: // // "table":{ // "data":[ // { // "col0":"" // } // ], // "columns":[ // "col0" // ] // } PObject table = page.getObject("table"); if (table.getArray("columns").size() == 1 && table.getArray("data").size() == 1) { String columnName = table.getArray("columns").getString(0); String value = table.getArray("data").getObject(0).getString(columnName); return !Strings.isNullOrEmpty(value); } return true; } return false; } private static List getTableColumnKeys(final PJsonObject oldTablePage) { final PJsonObject table = oldTablePage.optJSONObject("table"); final List columnKeys = new LinkedList<>(); if (table != null) { final PArray columns = table.optArray("columns", new PJsonArray(table, new JSONArray(), "columns")); for (int i = 0; i < columns.size(); i++) { columnKeys.add(columns.getString(i)); } } return columnKeys; } private static List getTableColumnLabels( final List columnKeys, final PJsonObject oldTablePage) { final List columnLabels = new LinkedList<>(); for (String key: columnKeys) { if (oldTablePage.has(key)) { columnLabels.add(oldTablePage.getString(key)); } else { columnLabels.add(""); } } return columnLabels; } private static List getTableData( final List columnKeys, final PJsonObject oldTablePage) { final PJsonObject table = oldTablePage.optJSONObject("table"); final List tableData = new LinkedList<>(); if (table != null) { final PArray oldTableRows = table.optArray("data", new PJsonArray(table, new JSONArray(), "data")); for (int i = 0; i < oldTableRows.size(); i++) { final PObject oldRow = oldTableRows.getObject(i); if (!oldRow.keys().hasNext()) { // row is empty, skip continue; } // copy the values for each column final JSONArray row = new JSONArray(); for (String key: columnKeys) { row.put(oldRow.getString(key)); } tableData.add(row); } } return tableData; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy