private JSONObject populateTableData(ActionParameters params) throws ActionException {

    try {
      // Get template
      final String tableLayout = params.getHttpParam(PARM_TABLETEMPLATE, "");
      if (tableLayout.isEmpty()) return null;
      String tabledata = OskariLayoutWorker.getTableTemplate(tableLayout);
      if (tabledata == null) return null;

      JSONObject jstable = JSONHelper.createJSONObject(tabledata);
      if (jstable == null) return null;

      // Get table row data
      final String rows = params.getHttpParam(PARM_TABLE, "");
      JSONObject jsrows = JSONHelper.createJSONObject(rows);
      if (jsrows == null) return null;

      JSONObject jsprint = jstable.optJSONObject(KEY_PRINTOUT);

      // Add data rows

      return OskariLayoutWorker.fillTables(jsprint, jsrows);

      // Get table row data
      // final String rows = params.getHttpParam(PARM_TABLE, "");

    } catch (Exception e) {
      throw new ActionException("Failed to populate printout table data", e);
    }
  }
  @Override
  public void handleAction(ActionParameters params) throws ActionException {
    if (params.getUser().isGuest()) {
      throw new ActionDeniedException("Session expired");
    }
    final long id = ConversionHelper.getLong(params.getHttpParam(PARAM_ID), -1);
    if (id == -1) {
      throw new ActionParamsException(
          "Parameter missing or non-numeric: " + PARAM_ID + "=" + params.getHttpParam(PARAM_ID));
    }

    final Analysis analysis = analysisDataService.getAnalysisById(id);
    if (analysis == null) {
      throw new ActionParamsException("Analysis id didn't match any analysis: " + id);
    }
    if (!params.getUser().getUuid().equals(analysis.getUuid())) {
      throw new ActionDeniedException("Analysis belongs to another user");
    }

    try {
      analysisDataService.deleteAnalysis(analysis);
      // write static response to notify success {"result" : "success"}
      ResponseHelper.writeResponse(params, JSONHelper.createJSONObject("result", "success"));
    } catch (ServiceException ex) {
      throw new ActionException("Error deleting analysis", ex);
    }
  }
 private void getUserParams(User user, ActionParameters params) throws ActionParamsException {
   user.setId(getId(params));
   user.setFirstname(params.getRequiredParam(PARAM_FIRSTNAME));
   user.setLastname(params.getRequiredParam(PARAM_LASTNAME));
   user.setScreenname(params.getRequiredParam(PARAM_SCREENNAME));
   user.setEmail(params.getRequiredParam(PARAM_EMAIL));
 }
 @Override
 public void handleAction(ActionParameters ap) throws ActionException {
   final long pluginId = ap.getRequiredParamInt(PARAM_PLUGIN_ID);
   final String indicatorId = ap.getRequiredParam(PARAM_INDICATOR_ID);
   JSONObject response = getIndicatorMetadataJSON(ap.getUser(), pluginId, indicatorId);
   ResponseHelper.writeResponse(ap, response);
 }
  public void handleAction(ActionParameters params) throws ActionException {

    final JSONObject root = new JSONObject();

    // Because of analysis layers
    String sid = params.getHttpParam(ID, "n/a");
    final int id = ConversionHelper.getInt(getBaseLayerId(sid), 0);

    final HttpServletResponse response = params.getResponse();
    response.setContentType("application/json");

    if (id == 0) {
      JSONHelper.putValue(root, ERROR, ERROR_NO_ID);
      ResponseHelper.writeResponse(params, root);
      // FIXME: throw ActionParamsException instead and modify client
      // response parsing
      return;
    }

    String json = WFSLayerConfiguration.getCache(id + "");
    if (json == null) {
      WFSLayerConfiguration lc = layerConfigurationService.findConfiguration(id);

      log.warn("id", id);
      log.warn(lc);

      // Extra manage for analysis
      if (sid.indexOf(ANALYSIS_PREFIX) > -1) {
        log.warn("sid", sid);
        // set id to original analysis layer id
        lc.setLayerId(sid);
        // Set analysis layer fields as id based
        lc.setSelectedFeatureParams(getAnalysisFeatureProperties(sid));
      }
      // Extra manage for analysis
      else if (sid.indexOf(MYPLACES_PREFIX) > -1) {
        log.warn("sid", sid);
        // set id to original my places layer id
        lc.setLayerId(sid);
      } else if (sid.indexOf(USERLAYER_PREFIX) > -1) {
        log.warn("sid", sid);
        // set id to original user layer id
        lc.setLayerId(sid);
      }
      if (lc == null) {
        JSONHelper.putValue(root, ERROR, ERROR_NOT_FOUND);
        ResponseHelper.writeResponse(params, root);
        // FIXME: throw ActionParamsException instead and modify client
        // response parsing
        return;
      }
      lc.save();
    }
    JSONHelper.putValue(root, RESULT, RESULT_SUCCESS);
    ResponseHelper.writeResponse(params, root);
  }
  public void handleAction(ActionParameters params) throws ActionException {

    final String wmsurl = params.getRequiredParam(PARM_WMSURL);

    if (!params.getUser().hasAnyRoleIn(permittedRoles)) {
      throw new ActionDeniedException("Unauthorized user tried to get wmsservices");
    }
    try {
      // New method for parsing WMSCetGapabilites to Oskari layers structure
      final JSONObject capabilities = GetGtWMSCapabilities.getWMSCapabilities(wmsurl);
      ResponseHelper.writeResponse(params, capabilities);
    } catch (Exception ee) {
      throw new ActionException("WMS Capabilities parsing failed: ", ee);
    }
  }
  /**
   * Parses WPS Proxy url via Oskari action route
   *
   * @param params Action parameters
   * @return String baseurl for Geoserver WPS reference WFS data input
   *     **********************************************************************
   */
  public String getBaseProxyUrl(ActionParameters params) {
    String baseurl = GEOSERVER_PROXY_BASE_URL;
    if (baseurl == null) {
      try {
        final URL url = new URL(params.getRequest().getRequestURL().toString());
        baseurl = url.getProtocol() + "://" + url.getHost() + ":" + url.getPort();
      } catch (Exception ignored) {
      }
    }

    final String baseAjaxUrl =
        PropertyUtil.get(params.getLocale(), GetAppSetupHandler.PROPERTY_AJAXURL);
    baseurl = baseurl + baseAjaxUrl + PARAMS_PROXY;
    log.debug("Analysis baseURL:", baseurl);
    return baseurl;
  }
  public void handleAction(ActionParameters params) throws ActionException {

    final HttpServletResponse response = params.getResponse();
    final HttpServletRequest httpRequest = params.getRequest();
    // default print format is application/pdf
    final String pformat = params.getHttpParam(PARM_FORMAT, "application/pdf");
    final JSONObject jsonprint = getPrintJSON(params);
    String file_save = params.getHttpParam(PARM_SAVE, "");
    boolean geojsCase = false;
    if (!params.getHttpParam(PARM_GEOJSON, "").isEmpty()) geojsCase = true;

    final HttpURLConnection con = getConnection(pformat, geojsCase);
    for (Enumeration<String> e = httpRequest.getHeaderNames(); e.hasMoreElements(); ) {
      final String key = e.nextElement();
      final String value = httpRequest.getHeader(key);
      con.setRequestProperty(key, value);
    }
    try {
      con.setRequestMethod("POST");
      con.setDoOutput(true);
      con.setDoInput(true);
      HttpURLConnection.setFollowRedirects(false);
      con.setUseCaches(false);
      con.setRequestProperty(HEADER_CONTENT_TYPE, "application/json");
      con.connect();
      if (log.isDebugEnabled()) {
        log.debug(jsonprint.toString(2));
      }

      IOHelper.writeToConnection(con, jsonprint.toString());

      final byte[] presponse = IOHelper.readBytes(con.getInputStream());
      // Save plot for future use
      if (!file_save.isEmpty()) savePdfPng(presponse, file_save, pformat);

      final String contentType = con.getHeaderField(HEADER_CONTENT_TYPE);
      response.addHeader(HEADER_CONTENT_TYPE, contentType);

      response.getOutputStream().write(presponse, 0, presponse.length);
      response.getOutputStream().flush();
      response.getOutputStream().close();
    } catch (Exception e) {
      throw new ActionException("Couldn't proxy request to print server", e);
    } finally {
      con.disconnect();
    }
  }
  @Override
  public void handleAction(ActionParameters params) throws ActionException {
    String jsessionid = params.getRequest().getSession().getId();

    // remove cache
    log.debug("deleting session:", jsessionid);
    WFSLayerPermissionsStore.destroy(jsessionid);
  }
 private long getId(ActionParameters params) throws NumberFormatException {
   // see if params contains an ID
   long id = -1l;
   String idString = params.getHttpParam(PARAM_ID, "-1");
   if (idString != null && idString.length() > 0) {
     id = Long.parseLong(idString);
   }
   return id;
 }
 @Override
 public void handlePut(ActionParameters params) throws ActionException {
   log.debug("handlePut");
   User user = new User();
   getUserParams(user, params);
   String password = params.getRequiredParam(PARAM_PASSWORD);
   String[] roles = params.getRequest().getParameterValues("roles");
   User retUser = null;
   try {
     retUser = userService.createUser(user, roles);
     userService.setUserPassword(retUser.getScreenname(), password);
   } catch (ServiceException se) {
     throw new ActionException(se.getMessage(), se);
   }
   JSONObject response = null;
   try {
     response = user2Json(retUser);
   } catch (JSONException je) {
     throw new ActionException(je.getMessage(), je);
   }
   ResponseHelper.writeResponse(params, response);
 }
  @Override
  public void handlePost(ActionParameters params) throws ActionException {
    log.debug("handlePost");
    User user = new User();
    getUserParams(user, params);
    String[] roles = params.getRequest().getParameterValues("roles");
    String password = params.getHttpParam(PARAM_PASSWORD);
    User retUser = null;
    try {
      if (user.getId() > -1) {
        // retUser = userService.modifyUser(user);
        log.debug("roles size: " + roles.length);
        retUser = userService.modifyUserwithRoles(user, roles);
        log.debug("done modifying user");
        if (password != null && !"".equals(password.trim())) {
          userService.updateUserPassword(retUser.getScreenname(), password);
        }
      } else {
        log.debug("NOW IN POST and creating a new user!!!!!!!!!!!!!");
        if (password == null || password.trim().isEmpty()) {
          throw new ActionException("Parameter 'password' not found.");
        }
        retUser = userService.createUser(user);
        userService.setUserPassword(retUser.getScreenname(), password);
      }

    } catch (ServiceException se) {
      throw new ActionException(se.getMessage(), se);
    }
    JSONObject response = null;
    try {
      response = user2Json(retUser);
    } catch (JSONException je) {
      throw new ActionException(je.getMessage(), je);
    }
    ResponseHelper.writeResponse(params, response);
  }
  @Override
  public void handleAction(ActionParameters params) throws ActionException {

    final HttpServletRequest request = params.getRequest();
    try {
      final int groupId = params.getHttpParam(PARAM_ID, -1);
      final LayerGroup group = new LayerGroup();
      group.setId(groupId);
      handleLocalizations(group, PARAM_NAME_PREFIX, request);
      if (group.getLocale() == null) {
        throw new ActionParamsException("Missing names for group!");
      }

      // ************** UPDATE ************************
      if (groupId != -1) {
        if (!layerGroupService.hasPermissionToUpdate(params.getUser(), groupId)) {
          throw new ActionDeniedException(
              "Unauthorized user tried to update layer group - id=" + groupId);
        }
        layerGroupService.update(group);
        ResponseHelper.writeResponse(params, group.getAsJSON());
      }
      // ************** INSERT ************************
      else if (params.getUser().isAdmin()) {
        final int id = layerGroupService.insert(group);
        group.setId(id);
        ResponseHelper.writeResponse(params, group.getAsJSON());
      } else {
        throw new ActionDeniedException(
            "Unauthorized user tried to update layer group - id=" + groupId);
      }

    } catch (Exception e) {
      throw new ActionException("Couldn't update/insert map layer group", e);
    }
  }
  private JSONArray getTilesJSON(ActionParameters params) throws ActionException {
    JSONArray tilesjs = null;
    try {
      // GeoJson graphics layers to selected layers
      final String tiles = params.getHttpParam(PARM_TILES, "");

      if (!tiles.isEmpty()) {
        tilesjs = new JSONArray(tiles);
      }

      // Get print area bbox
      final String response = ProxyService.proxy("print", params);
      JSONObject printbbox = JSONHelper.createJSONObject(response);
      // Fix bbox to print size area only for statslayer
      fixBbox(printbbox, tilesjs);

    } catch (Exception e) {
      throw new ActionException("Failed to get tiles json ", e);
    }

    return tilesjs;
  }
  /**
   * Handles action_route CreateAnalysisLayer
   *
   * @param params Ajax request parameters
   *     **********************************************************************
   */
  public void handleAction(ActionParameters params) throws ActionException {

    if (params.getUser().isGuest()) {
      throw new ActionDeniedException("Session expired");
    }

    final String analyse = params.getRequiredParam(PARAM_ANALYSE, ERROR_ANALYSE_PARAMETER_MISSING);
    JSONObject analyseJson = JSONHelper.createJSONObject(analyse);
    if (analyseJson == null) {
      // json corrupted/parsing failed
      throw new ActionParamsException(ERROR_ANALYSE_PARAMETER_MISSING);
    }

    // filter conf data
    final String filter1 = params.getHttpParam(PARAM_FILTER1);
    final String filter2 = params.getHttpParam(PARAM_FILTER2);

    // Get baseProxyUrl
    final String baseUrl = getBaseProxyUrl(params);

    // User
    String uuid = params.getUser().getUuid();
    // note! analysisLayer is replaced in aggregate handling!!
    AnalysisLayer analysisLayer = getAnalysisLayer(analyseJson, filter1, filter2, baseUrl, uuid);
    Analysis analysis = null;

    if (analysisLayer.getMethod().equals(AnalysisParser.LAYER_UNION)) {
      // no WPS for merge analysis
      analysis = analysisDataService.mergeAnalysisData(analysisLayer, analyse, params.getUser());
    } else {
      // Generate WPS XML
      String featureSet = executeWPSprocess(analysisLayer);
      if (analysisLayer.getMethod().equals(AnalysisParser.UNION)
          || analysisLayer.getMethod().equals(AnalysisParser.INTERSECT)
          || analysisLayer.getMethod().equals(AnalysisParser.SPATIAL_JOIN)) {
        // Harmonize namespaces and element names
        featureSet = analysisParser.harmonizeElementNames(featureSet, analysisLayer);
      }

      // Add data to analysis db  - we must create still an union in aggregate case
      if (analysisLayer.getMethod().equals(AnalysisParser.AGGREGATE)) {
        // No store to analysis db for aggregate - set results in to the
        // response
        // Save analysis results - use union of input data
        analysisLayer.setWpsLayerId(-1);
        final String aggregateResult =
            this.localiseAggregateResult(
                analysisParser.parseAggregateResults(featureSet, analysisLayer), analyseJson);
        log.debug("\nAggregate results:\n", aggregateResult, "\n");
        /*
        Aggregate results:
         {"fi_url_1":{"Count":4},"tmp_id":{"Sum":45301,"Median":12232,"Count":4,"Standar
        d deviation":3186.3551571505645,"Maximum":14592,"Average":11325.25,"Minimum":624
        5},"fi_url_3":{"Count":4},"postinumero":{"Count":4},"fi_url_2":{"Count":4},"fi_s
        posti_1":{"Count":4},"kuntakoodi":{"Count":4},"fi_osoite":{"Count":4},"fi_nimi":
        {"Count":4},"kto_tarkennus":{"Count":4}}
                         */
        analysisLayer.setResult(aggregateResult);

        // Get geometry for aggretage features
        try {
          // Just return result as JSON and don't save analysis to DB
          if (!params.getHttpParam(PARAM_SAVE_BLN, true)) {
            // NOTE!! Replacing the analysisLayer!
            // Get response as geojson when no db store
            analysisLayer =
                getAggregateLayer(analyse, filter1, filter2, baseUrl, analysisLayer, JSONFORMAT);
            featureSet = wpsService.requestFeatureSet(analysisLayer);
            // Just return result as JSON and don't save analysis to DB
            // Get geometry as geojson for hilighting features of aggregate result
            JSONObject geojson = JSONHelper.createJSONObject(featureSet);
            JSONObject jsaggregate = JSONHelper.createJSONObject(aggregateResult);
            JSONObject results = new JSONObject();
            JSONHelper.putValue(results, JSON_KEY_GEOJSON, geojson);
            JSONHelper.putValue(results, JSON_KEY_AGGREGATE_RESULT, jsaggregate);
            ResponseHelper.writeResponse(params, results);
            return;
          }
          // NOTE!! Replacing the analysisLayer!  - response is gml
          analysisLayer =
              getAggregateLayer(analyse, filter1, filter2, baseUrl, analysisLayer, null);
          featureSet = wpsService.requestFeatureSet(analysisLayer);
          // Harmonize namespaces and element names
          featureSet = analysisParser.harmonizeElementNames(featureSet, analysisLayer);
          featureSet =
              analysisParser.mergeAggregateResults2FeatureSet(
                  featureSet,
                  analysisLayer,
                  this.getRowOrder(analyseJson),
                  this.getColumnOrder(analyseJson));
          // Redefine column types
          analysisLayer.setFieldtypeMap(
              this.getAggregateFieldTypes(this.getColumnOrder(analyseJson)));
        } catch (ServiceException e) {
          throw new ActionException(ERROR_UNABLE_TO_GET_FEATURES_FOR_UNION, e);
        }
      }
      // Add extra TypeNames (depends on wps method)
      analysisParser.fixTypeNames(analysisLayer);

      // Fix geometry property name for WFST (could be any, depends on Wps method )
      fixGeometryPropertyName(analysisLayer);

      analysis =
          analysisDataService.storeAnalysisData(
              featureSet, analysisLayer, analyse, params.getUser());
    }

    if (analysis == null) {
      this.MyError(ERROR_UNABLE_TO_STORE_ANALYSIS_DATA, params, null);
      return;
    }

    analysisLayer.setWpsLayerId(analysis.getId()); // aka. analysis_id
    // Analysis field mapping
    analysisLayer.setLocaleFields(analysis);
    analysisLayer.setNativeFields(analysis);

    // copy permissions from source layer to new analysis
    final Resource sourceResource =
        getSourcePermission(analysisParser.getSourceLayerId(analyseJson), params.getUser());
    if (sourceResource != null) {
      final Resource analysisResource = new Resource();
      analysisResource.setType(AnalysisLayer.TYPE);
      analysisResource.setMapping("analysis", Long.toString(analysis.getId()));
      for (Permission p : sourceResource.getPermissions()) {
        // check if user has role matching permission?
        if (p.isOfType(Permissions.PERMISSION_TYPE_PUBLISH)
            || p.isOfType(Permissions.PERMISSION_TYPE_VIEW_PUBLISHED)) {
          analysisResource.addPermission(p.clonePermission());
        }
      }
      log.debug(
          "Trying to save permissions for analysis",
          analysisResource,
          analysisResource.getPermissions());
      permissionsService.saveResourcePermissions(analysisResource);
    } else {
      log.warn("Couldn't get source permissions for analysis, result will have none");
    }

    // Get analysisLayer JSON for response to front
    final JSONObject analysisLayerJSON = AnalysisHelper.getlayerJSON(analysis);

    // Additional param for new layer creation when merging layers:
    // - Notify client to remove merged layers since they are removed from backend
    JSONArray mlayers = new JSONArray();
    if (analysisLayer.getMergeAnalysisLayers() != null) {
      for (String lay : analysisLayer.getMergeAnalysisLayers()) {
        mlayers.put(lay);
      }
    }
    JSONHelper.putValue(analysisLayerJSON, "mergeLayers", mlayers);

    Set<String> permissionsList = permissionsService.getPublishPermissions(AnalysisLayer.TYPE);
    Set<String> downloadPermissionsList =
        permissionsService.getDownloadPermissions(AnalysisLayer.TYPE);
    Set<String> editAccessList = null;
    String permissionKey = "analysis+" + analysis.getId();
    JSONObject permissions =
        OskariLayerWorker.getPermissions(
            params.getUser(),
            permissionKey,
            permissionsList,
            downloadPermissionsList,
            editAccessList);
    JSONHelper.putValue(analysisLayerJSON, "permissions", permissions);

    ResponseHelper.writeResponse(params, analysisLayerJSON);
  }
  private JSONObject getPrintJSON(ActionParameters params) throws ActionException {
    final JSONObject jsonprint = new JSONObject();
    try {
      final HttpServletRequest httpRequest = params.getRequest();

      // copy parameters
      JSONObject jsparamdata = new JSONObject();
      for (Object key : httpRequest.getParameterMap().keySet()) {
        String keyStr = (String) key;
        // not geojson, tiles, tabledata param ..
        if (!EXTRA_PARAMS.contains(keyStr)) {
          jsparamdata.put(keyStr, params.getHttpParam(keyStr));
        }
      }
      jsonprint.put(KEY_MAPLINK, jsparamdata);

      // Table data
      final JSONObject jsTableData = this.populateTableData(params);
      if (jsTableData != null) jsonprint.put(KEY_PRINTOUT, jsTableData);

      // construct state
      final JSONObject jsonstatedata = new JSONObject();

      final String[] coords = CoordinateParamHandler.parseParam(params.getHttpParam(PARM_COORD));
      if (coords.length == 2) {
        try {
          final double east = ConversionHelper.getDouble(coords[0], -1);
          final double north = ConversionHelper.getDouble(coords[1], -1);
          if (east == -1 || north == -1) {
            throw new IllegalArgumentException(
                "Coordinates not set: " + params.getHttpParam(PARM_COORD));
          }
          jsonstatedata.put(ViewModifier.KEY_EAST, east);
          jsonstatedata.put(ViewModifier.KEY_NORTH, north);
        } catch (Exception ex) {
          throw new ActionException("Could not set coordinates from URL param.", ex);
        }
      }
      jsonstatedata.put(
          ViewModifier.KEY_ZOOM, ConversionHelper.getInt(params.getHttpParam(PARM_ZOOMLEVEL), 10));

      final String[] layers = params.getHttpParam(PARM_MAPLAYERS).split(",");
      final JSONArray configLayers = new JSONArray();
      final JSONArray selectedlayers = new JSONArray();

      // final String referer =
      // RequestHelper.getDomainFromReferer(params.getHttpHeader("Referer"));
      for (String layerString : layers) {
        final String[] layerProps = layerString.split(" ");
        final JSONObject layer =
            LayersParamHandler.getLayerJson(layerProps, "paikkatietoikkuna.fi");
        if (layer != null) {
          selectedlayers.put(layer);
          configLayers.put(layer);
        }
      }

      // GeoJson graphics layers to selected layers
      final String geojs64 = params.getHttpParam(PARM_GEOJSON, "");

      JSONArray geojs = null;
      if (!geojs64.isEmpty()) {
        // decoding geojson
        byte[] decoded = Base64.decodeBase64(geojs64.getBytes());

        geojs = new JSONArray(new String(decoded));

        JSONArray jslays = getGeojsonLayers(geojs);
        for (int i = 0; i < jslays.length(); i++) {
          selectedlayers.put(jslays.getJSONObject(i));
        }
      }
      jsonstatedata.put(ViewModifier.KEY_SELECTEDLAYERS, selectedlayers);
      jsonprint.put(ViewModifier.KEY_STATE, jsonstatedata);

      // printservice uses direct urls to myplaces instead of servletfilter/actionroute proxy
      final boolean useDirectURLForMyplaces = true;
      // populate layer details
      final JSONArray fullLayersConfigJson =
          MapfullHandler.getFullLayerConfig(
              configLayers,
              params.getUser(),
              params.getLocale().getLanguage(),
              PRINT_VIEW,
              ViewTypes.PRINT,
              Collections.EMPTY_SET,
              useDirectURLForMyplaces);

      // GeoJson graphics layers + styles
      if (geojs != null) {
        // Add geojson geometry and styles to layers section
        for (int i = 0; i < geojs.length(); i++) {
          fullLayersConfigJson.put(geojs.getJSONObject(i));
        }
      }

      // Add tiles, (statslayer, wfs)
      //      if (fullLayersConfigJson.toString().contains(VALUE_STATSLAYER)) {
      // Tiles in params ?
      if (!params.getHttpParam(PARM_TILES, "").isEmpty()) {

        JSONArray tiles = getTilesJSON(params);
        addTiles2Layers(fullLayersConfigJson, tiles);
      }
      //    }

      jsonprint.put(KEY_LAYERS, fullLayersConfigJson);

    } catch (Exception e) {
      throw new ActionException("Failed to create image", e);
    }

    return jsonprint;
  }
 @Override
 public void preProcess(ActionParameters params) throws ActionException {
   if (!params.getUser().isAdmin()) {
     throw new ActionDeniedException("Admin only");
   }
 }
  public void handleAction(final ActionParameters params) throws ActionException {
    log.debug("in handle action");

    final String term = params.getHttpParam(PARAM_TERM);
    if (term == null || term.equals("")) {
      throw new ActionParamsException("Search string was null");
    }

    final String error = SearchWorker.checkLegalSearch(term);

    if (!SearchWorker.STR_TRUE.equals(error)) {
      // write error message key
      ResponseHelper.writeResponse(params, error);
    } else {
      final Locale locale = params.getLocale();
      final SearchCriteria sc = new SearchCriteria();

      final String geographical_names = params.getHttpParam(PARAM_GEO_NAMES);
      final String addresses = params.getHttpParam(PARAM_ADDRESSES);
      final String epsg = params.getHttpParam(PARAM_EPSG_KEY);

      sc.setSearchString(term);
      sc.setSRS(epsg); // eg. EPSG:3067
      sc.setLocale(locale.getLanguage());

      sc.addParam(PARAM_REGION, params.getHttpParam(PARAM_REGION, ""));
      sc.addParam(PARAM_COUNTRY, params.getHttpParam(PARAM_COUNTRY, ""));
      sc.addParam(PARAM_FILTER, params.getHttpParam(PARAM_FILTER, "false"));
      sc.addParam(PARAM_NORMAL, params.getHttpParam(PARAM_NORMAL, "false"));
      sc.addParam(PARAM_LON, params.getHttpParam(PARAM_LON, ""));
      sc.addParam(PARAM_LAT, params.getHttpParam(PARAM_LAT, ""));
      sc.addParam(PARAM_ADDRESSES, params.getHttpParam(PARAM_ADDRESSES));
      sc.addParam(PARAM_LOCATION_TYPE, params.getHttpParam(PARAM_LOCATION_TYPE, ""));
      sc.addParam(PARAM_NAME_LANG, params.getHttpParam(PARAM_NAME_LANG, ""));
      sc.addParam(PARAM_NEAREST, params.getHttpParam(PARAM_NEAREST, ""));

      if (isFuzzy(sc)) {
        sc.addParam(PARAM_FUZZY, "true");
      }

      for (String channelId : channels) {
        if (geographical_names != null
            && geographical_names.equals("true")
            && channelId.equals(ELFGEOLOCATOR_CHANNEL)) {
          log.debug("adding channel: ELFGEOLOCATOR_CHANNEL");
          sc.addChannel(channelId);
        }
        if (addresses != null
            && addresses.equals("true")
            && channelId.equals(ELFADDRESSLOCATOR_CHANNEL)) {
          log.debug("adding channel: ELFADDRESSLOCATOR_CHANNEL");
          sc.addChannel(channelId);
        }
      }

      final JSONObject result = SearchWorker.doSearch(sc);
      ResponseHelper.writeResponse(params, result);
    }
  }
  public void handleAction(ActionParameters params) throws ActionException {

    final User user = params.getUser();

    // Parse stuff sent by JS
    final JSONObject publisherData = getPublisherInput(params.getRequiredParam(KEY_PUBDATA));
    final View currentView = getBaseView(publisherData, user);

    final Bundle mapFullBundle = currentView.getBundleByName(ViewModifier.BUNDLE_MAPFULL);
    if (mapFullBundle == null) {
      throw new ActionParamsException("Could find mapfull bundle from view:" + currentView.getId());
    }

    // Setup user
    try {
      JSONObject userJson = new JSONObject();
      userJson.put(KEY_FIRSTNAME, user.getFirstname());
      userJson.put(KEY_LASTNAME, user.getLastname());
      userJson.put(KEY_NICKNAME, user.getScreenname());
      userJson.put(KEY_LOGINNAME, user.getEmail());
      JSONHelper.putValue(mapFullBundle.getConfigJSON(), KEY_USER, userJson);
      // mapfullTemplateConfig.put(KEY_USER, userJson);
    } catch (JSONException jsonex) {
      log.error("Could not create user object:", user, "- Error:", jsonex.getMessage());
      throw new ActionParamsException("User data problem");
    }

    // setup basic info about view
    final String domain = JSONHelper.getStringFromJSON(publisherData, KEY_DOMAIN, null);
    if (domain == null) {
      throw new ActionParamsException("Domain missing");
    }
    final String name =
        JSONHelper.getStringFromJSON(
            publisherData, KEY_NAME, "Published map " + System.currentTimeMillis());
    final String language =
        JSONHelper.getStringFromJSON(
            publisherData, KEY_LANGUAGE, PropertyUtil.getDefaultLanguage());

    currentView.setPubDomain(domain);
    currentView.setName(name);
    currentView.setType(params.getHttpParam(ViewTypes.VIEW_TYPE, ViewTypes.PUBLISHED));
    currentView.setCreator(user.getId());
    currentView.setIsPublic(true);
    // application/page/developmentPath should be configured to publish template view
    currentView.setLang(language);

    // setup map state
    setupMapState(mapFullBundle, publisherData, user);

    // setup infobox
    final JSONObject tmpInfoboxState = publisherData.optJSONObject(ViewModifier.BUNDLE_INFOBOX);
    if (tmpInfoboxState != null) {
      final Bundle infoboxTemplateBundle = currentView.getBundleByName(ViewModifier.BUNDLE_INFOBOX);
      if (infoboxTemplateBundle != null) {
        infoboxTemplateBundle.setState(tmpInfoboxState.toString());
      } else {
        log.warn(
            "Publisher sent state for infobox, but infobox isn't available in template view! State:",
            tmpInfoboxState);
      }
    }

    // Setup publishedmyplaces2 bundle if user has configured it/has permission to do so
    if (user.hasAnyRoleIn(drawToolsEnabledRoles)) {
      setupBundle(currentView, publisherData, ViewModifier.BUNDLE_PUBLISHEDMYPLACES2);
    }

    // Setup toolbar bundle if user has configured it
    setupBundle(currentView, publisherData, ViewModifier.BUNDLE_TOOLBAR);

    // Setup thematic map/published grid bundle
    final JSONObject gridState = publisherData.optJSONObject(KEY_GRIDSTATE);
    log.debug("Grid state:", gridState);
    if (gridState != null) {
      final Bundle gridBundle = addBundle(currentView, ViewModifier.BUNDLE_PUBLISHEDGRID);
      log.debug("Grid bundle added:", gridBundle);
      mergeBundleConfiguration(gridBundle, null, gridState);
    }

    log.debug("Save view:", currentView);
    final View newView = saveView(currentView);
    log.debug("Published a map:", newView);

    try {
      JSONObject newViewJson = new JSONObject(newView.toString());
      ResponseHelper.writeResponse(params, newViewJson);
    } catch (JSONException je) {
      log.error(je, "Could not create JSON response.");
      ResponseHelper.writeResponse(params, false);
    }
  }