private JSONObject user2Json(User user) throws JSONException {
    // TODO: User.toJSON() should be used
    JSONObject uo = new JSONObject();
    uo.put("id", user.getId());
    uo.put("firstName", user.getFirstname());
    uo.put("lastName", user.getLastname());
    uo.put("user", user.getScreenname());
    uo.put("email", user.getEmail());

    JSONArray rolesArray = new JSONArray();
    for (Role role : user.getRoles()) {
      rolesArray.put(role.getId());
    }
    JSONHelper.put(uo, "roles", rolesArray);

    return uo;
  }
  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());
  }
  private View getBaseView(final JSONObject publisherInput, final User user)
      throws ActionException {

    if (user.isGuest()) {
      throw new ActionDeniedException("Trying to publish map, but couldn't determine user");
    }

    // not editing, use template view
    if (PUBLISHED_VIEW_TEMPLATE_ID == -1) {
      log.error("Publish template id not configured (property: view.template.publish)!");
      throw new ActionParamsException("Trying to publish map, but template isn't configured");
    }
    log.debug("Using template to create a new view");
    // Get publisher defaults
    View templateView = viewService.getViewWithConf(PUBLISHED_VIEW_TEMPLATE_ID);
    if (templateView == null) {
      log.error("Could not get template View with id:", PUBLISHED_VIEW_TEMPLATE_ID);
      throw new ActionParamsException("Could not get template View");
    }

    // clone a blank view based on template (so template doesn't get updated!!)
    final View view = templateView.cloneBasicInfo();
    final long viewId = publisherInput.optLong("id", -1);
    if (viewId != -1) {
      // check loaded view against user if we are updating a view
      log.debug("Loading view for editing:", viewId);
      final View existingView = viewService.getViewWithConf(viewId);
      if (user.getId() != existingView.getCreator()) {
        throw new ActionDeniedException("No permissions to update view with id:" + viewId);
      }
      // setup ids for updating a view
      view.setId(existingView.getId());
      view.setSupplementId(existingView.getSupplementId());
      view.setUuid(existingView.getUuid());
      view.setOldId(existingView.getOldId());
    }

    return view;
  }
  @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);
  }
  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);
    }
  }