private Resource getSourcePermission(final String layerId, final User user) {
    if (layerId == null) {
      return null;
    }

    if (layerId.startsWith(AnalysisParser.ANALYSIS_LAYER_PREFIX)) {

      final Resource resource = new Resource();
      resource.setType(AnalysisLayer.TYPE);
      resource.setMapping(
          "analysis", Long.toString(AnalysisHelper.getAnalysisIdFromLayerId(layerId)));
      return permissionsService.findResource(resource);
    } else if (layerId.startsWith(AnalysisParser.MYPLACES_LAYER_PREFIX)
        || layerId.equals("-1")
        || layerId.startsWith(AnalysisParser.USERLAYER_PREFIX)) {

      final Resource resource = new Resource();
      // permission to publish for self
      final Permission permPublish = new Permission();
      permPublish.setExternalType(Permissions.EXTERNAL_TYPE_USER);
      permPublish.setExternalId("" + user.getId());
      permPublish.setType(Permissions.PERMISSION_TYPE_PUBLISH);
      resource.addPermission(permPublish);
      try {
        // add VIEW_PUBLISHED for all roles currently in the system
        for (Role role : UserService.getInstance().getRoles()) {
          final Permission perm = new Permission();
          perm.setExternalType(Permissions.EXTERNAL_TYPE_ROLE);
          perm.setExternalId("" + role.getId());
          perm.setType(Permissions.PERMISSION_TYPE_VIEW_PUBLISHED);
          resource.addPermission(perm);
        }
      } catch (Exception e) {
        log.error(
            "Something went wrong when generating source permissions for myplaces layer or temporary or user data layer");
      }
      return resource;
    }
    // default to usual layer
    final OskariLayer layer = mapLayerService.find(layerId);
    // copy permissions from source layer to new analysis
    return permissionsService.getResource(
        Permissions.RESOURCE_TYPE_MAP_LAYER, new OskariLayerResource(layer).getMapping());
  }
  public void migrate(Connection connection) {
    List<OskariLayer> layers = LAYER_SERVICE.findAll();

    LOG.info("Start populating capabilities for layers - count:", layers.size());
    Set<String> keys = new HashSet<>();
    int progress = 0;
    for (OskariLayer layer : layers) {
      try {
        final String layerKey =
            (layer.getSimplifiedUrl(true) + "----" + layer.getType()).toLowerCase();
        if (keys.contains(layerKey)) {
          progress++;
          continue;
        }
        keys.add(layerKey);
        CAPABILITIES_SERVICE.getCapabilities(layer);
        progress++;
        LOG.info("Capabilities populated:", progress, "/", layers.size());
      } catch (ServiceException e) {
        LOG.error(e, "Error getting capabilities for layer", layer);
      }
    }
  }
  /**
   * Parses method parameters to WPS execute xml syntax definition
   *
   * @param layerJSON method parameters and layer info from the front
   * @param baseUrl Url for Geoserver WPS reference input (input FeatureCollection)
   * @return AnalysisLayer parameters for WPS execution
   *     **********************************************************************
   */
  public AnalysisLayer parseAnalysisLayer(String layerJSON, String filter, String baseUrl)
      throws ServiceException {
    AnalysisLayer analysisLayer = new AnalysisLayer();

    JSONObject json = JSONHelper.createJSONObject(layerJSON);
    WFSLayerConfiguration lc = null;

    // analysis input data type - default is WFS layer
    analysisLayer.setInputType(ANALYSIS_INPUT_TYPE_WFS);
    // analysis rendering url
    analysisLayer.setWpsUrl(analysisRenderingUrl);
    // analysis element name
    analysisLayer.setWpsName(analysisRenderingElement);

    analysisLayer.setInputAnalysisId(null);
    int id = 0;
    try {
      // Analysis input property types
      this.prepareFieldtypeMap(analysisLayer, json);

      String sid = json.getString(JSON_KEY_LAYERID);

      // Input is wfs layer or analaysis layer or my places
      if (sid.indexOf(LAYER_PREFIX) == 0) {
        // Analysislayer is input
        if (!this.prepareAnalysis4Analysis(analysisLayer, json))
          throw new ServiceException("AnalysisInAnalysis parameters are invalid");
        id = analysisLayer.getId();
      } else if (sid.indexOf(MYPLACES_LAYER_PREFIX) == 0) {
        // myplaces is input
        if (!this.prepareAnalysis4Myplaces(analysisLayer, json))
          throw new ServiceException("AnalysisInMyPlaces parameters are invalid");
        id = analysisLayer.getId();
      } else {
        // Wfs layer id
        id = ConversionHelper.getInt(sid, -1);
      }
    } catch (JSONException e) {
      throw new ServiceException("AnalysisInAnalysis parameters are invalid");
    }
    // --- WFS layer is analysis input
    analysisLayer.setId(id);

    // Get wfs layer configuration
    lc = layerConfigurationService.findConfiguration(id);

    final OskariLayer wfsLayer = mapLayerService.find(id);
    log.debug("got wfs layer", wfsLayer);
    analysisLayer.setMinScale(wfsLayer.getMinScale());
    analysisLayer.setMaxScale(wfsLayer.getMaxScale());

    // Set WFS input type, other than analysis_ and myplaces_- default is REFERENCE
    this.setWpsInputLayerType(lc.getWps_params(), analysisLayer);

    // Extract parameters for analysis methods from layer

    String name = json.optString("name");
    if (name.isEmpty()) {
      throw new ServiceException("Analysis name missing.");
    } else {
      analysisLayer.setName(name);
    }

    JSONArray fields_in = json.optJSONArray("fields");
    List<String> fields = new ArrayList<String>();

    if (fields_in == null) {
      throw new ServiceException("Fields missing.");
    } else {
      // Add fields of WFS service, if empty and all fields mode on
      if (fields_in.length() == 0) fields_in = this.getWfsFields(analysisLayer);
      // Remove internal fields
      try {
        for (int i = 0; i < fields_in.length(); i++) {
          if (!HIDDEN_FIELDS.contains(fields_in.getString(i))) fields.add(fields_in.getString(i));
        }
      } catch (JSONException e) {
        throw new ServiceException("Method fields parameters missing.");
      }
      analysisLayer.setFields(fields);
    }

    String style = json.optString("style");
    if (style.isEmpty()) {
      throw new ServiceException("Style missing.");
    } else {
      analysisLayer.setStyle(style);
    }

    Integer opacity = json.optInt("opacity");
    if (opacity == 0) opacity = DEFAULT_OPACITY;
    analysisLayer.setOpacity(opacity);

    String analysisMethod = json.optString("method"); // "union_geom"; test
    analysisLayer.setMethod(analysisMethod);

    analysisLayer.setAggreFunctions(null);
    analysisLayer.setMergeAnalysisLayers(null);

    // ------------------LAYER_UNION -----------------------
    if (LAYER_UNION.equals(analysisMethod)) {
      JSONObject params;
      try {
        params = json.getJSONObject(JSON_KEY_METHODPARAMS);
      } catch (JSONException e) {
        throw new ServiceException("Method parameters missing.");
      }
      JSONArray sids = params.optJSONArray(JSON_KEY_LAYERS);
      // Loop merge layers - get analysis ids
      List<Long> ids = new ArrayList<Long>();
      List<String> mergelays = new ArrayList<String>();
      if (sids == null) {
        throw new ServiceException("merge layers missing");
      } else {
        try {
          for (int i = 0; i < sids.length(); i++) {
            Long aid = this.getAnalysisId(sids.getString(i));
            if (aid > 0) {
              ids.add(aid);
              mergelays.add(sids.getString(i));
            }
          }
        } catch (JSONException e) {
          throw new ServiceException("Merge layers missing.");
        }
        // Merge analysis Ids
        analysisLayer.setMergeAnalysisIds(ids);
        // Merge analysis Layers
        analysisLayer.setMergeAnalysisLayers(mergelays);
      }
    }
    // ------------------ BUFFER -----------------------
    else if (BUFFER.equals(analysisMethod)) {
      // when analysisMethod == vec:BufferFeatureCollection

      // Set params for WPS execute

      BufferMethodParams method = this.parseBufferParams(lc, json, baseUrl);

      method.setWps_reference_type(analysisLayer.getInputType());
      analysisLayer.setAnalysisMethodParams(method);

      // WFS filter
      analysisLayer
          .getAnalysisMethodParams()
          .setFilter(
              this.parseFilter(
                  lc,
                  filter,
                  analysisLayer.getInputAnalysisId(),
                  analysisLayer.getInputCategoryId()));
      // WFS Query properties
      analysisLayer
          .getAnalysisMethodParams()
          .setProperties(
              this.parseProperties(
                  analysisLayer.getFields(),
                  lc.getFeatureNamespace(),
                  lc.getGMLGeometryProperty()));
      // ------------------ INTERSECT -----------------------
    } else if (INTERSECT.equals(analysisMethod)) {
      JSONObject params;
      try {
        params = json.getJSONObject(JSON_KEY_METHODPARAMS);
      } catch (JSONException e) {
        throw new ServiceException("Method parameters missing.");
      }
      WFSLayerConfiguration lc2 = null;
      int id2 = 0;
      String sid = "";
      try {
        sid = params.getString(JSON_KEY_LAYERID);
        // Input is wfs layer or analaysis layer
        if (sid.indexOf(LAYER_PREFIX) == 0) {
          // Analysislayer is input
          // eg. analyse_216_340
          id2 = ConversionHelper.getInt(analysisBaseLayerId, 0);

        } else if (sid.indexOf(MYPLACES_LAYER_PREFIX) == 0) {
          // Myplaces is input
          id2 = ConversionHelper.getInt(myplacesBaseLayerId, 0);

        } else {
          // Wfs layer id
          id2 = ConversionHelper.getInt(sid, -1);
        }
      } catch (JSONException e) {
        throw new ServiceException("AnalysisInAnalysis parameters are invalid");
      }

      // Get wfs layer configuration for union input 2
      lc2 = layerConfigurationService.findConfiguration(id2);

      // Set params for WPS execute

      IntersectMethodParams method = this.parseIntersectParams(lc, lc2, json, baseUrl);

      method.setWps_reference_type(analysisLayer.getInputType());
      if (sid.indexOf(LAYER_PREFIX) == 0 || sid.indexOf(MYPLACES_LAYER_PREFIX) == 0) {
        method.setWps_reference_type2(ANALYSIS_INPUT_TYPE_GS_VECTOR);
      } else {
        method.setWps_reference_type2(ANALYSIS_INPUT_TYPE_WFS);
      }
      // Set WFS input type, other than analysis_ and myplaces_- default is REFERENCE
      this.setWpsInputLayerType(lc.getWps_params(), analysisLayer);

      // WFS filter

      method.setFilter(
          this.parseFilter(
              lc, filter, analysisLayer.getInputAnalysisId(), analysisLayer.getInputCategoryId()));

      if (sid.indexOf(MYPLACES_LAYER_PREFIX) == 0) {
        method.setFilter2(this.parseFilter(lc2, null, null, this.getAnalysisInputId(params)));
      } else {
        method.setFilter2(this.parseFilter(lc2, null, this.getAnalysisInputId(params), null));
      }
      // WFS Query properties
      method.setProperties(
          this.parseProperties(
              analysisLayer.getFields(), lc.getFeatureNamespace(), lc.getGMLGeometryProperty()));

      analysisLayer.setAnalysisMethodParams(method);
      // ------------------ AGGREGATE -----------------------
    } else if (AGGREGATE.equals(analysisMethod)) {

      // 1 to n aggregate wps tasks
      String aggre_field = null;
      try {

        aggre_field = json.getJSONObject(JSON_KEY_METHODPARAMS).optString(JSON_KEY_AGGRE_ATTRIBUTE);
        if (analysisLayer.getInputType().equals(ANALYSIS_INPUT_TYPE_GS_VECTOR)) {
          if (analysisLayer.getInputAnalysisId() != null) {
            aggre_field =
                analysisDataService.SwitchField2AnalysisField(
                    aggre_field, analysisLayer.getInputAnalysisId());
          }
        }
        JSONArray aggre_func_in =
            json.getJSONObject(JSON_KEY_METHODPARAMS).optJSONArray(JSON_KEY_FUNCTIONS);
        List<String> aggre_funcs = new ArrayList<String>();
        if (aggre_func_in == null) {
          throw new ServiceException("Aggregate functions missing.");
        } else {
          try {
            for (int i = 0; i < aggre_func_in.length(); i++) {
              aggre_funcs.add(aggre_func_in.getString(i));
            }
          } catch (JSONException e) {
            throw new ServiceException("Aggregate functions missing.");
          }
          analysisLayer.setAggreFunctions(aggre_funcs);
        }

      } catch (JSONException e) {
        throw new ServiceException("Method parameters missing.");
      }

      // Set params for WPS execute
      if (aggre_field == null) throw new ServiceException("Aggregate field parameter missing.");
      AggregateMethodParams method =
          this.parseAggregateParams(
              lc, json, baseUrl, aggre_field, analysisLayer.getAggreFunctions());

      method.setWps_reference_type(analysisLayer.getInputType());
      analysisLayer.setAnalysisMethodParams(method);
      // WFS filter

      analysisLayer
          .getAnalysisMethodParams()
          .setFilter(
              this.parseFilter(
                  lc,
                  filter,
                  analysisLayer.getInputAnalysisId(),
                  analysisLayer.getInputCategoryId()));
      // ------------------ UNION -----------------------
    } else if (UNION.equals(analysisMethod)) {
      JSONObject params;
      try {
        params = json.getJSONObject(JSON_KEY_METHODPARAMS);
      } catch (JSONException e) {
        throw new ServiceException("Method parameters missing.");
      }

      // Set params for WPS execute

      UnionMethodParams method = this.parseUnionParams(lc, json, baseUrl);
      method.setWps_reference_type(analysisLayer.getInputType());

      // WFS filter

      method.setFilter(
          this.parseFilter(
              lc, filter, analysisLayer.getInputAnalysisId(), analysisLayer.getInputCategoryId()));

      analysisLayer.setAnalysisMethodParams(method);

    } else {
      throw new ServiceException("Method parameters missing.");
    }

    return analysisLayer;
  }