public static Layout addLayout(
      Group group,
      boolean privateLayout,
      long parentLayoutId,
      String name,
      String friendlyURL,
      String layoutTemplateId)
      throws Exception {

    ServiceContext serviceContext = new ServiceContext();

    Layout layout =
        LayoutLocalServiceUtil.addLayout(
            group.getCreatorUserId(),
            group.getGroupId(),
            privateLayout,
            parentLayoutId,
            name,
            StringPool.BLANK,
            StringPool.BLANK,
            LayoutConstants.TYPE_PORTLET,
            false,
            friendlyURL,
            serviceContext);

    LayoutTypePortlet layoutTypePortlet = (LayoutTypePortlet) layout.getLayoutType();

    layoutTypePortlet.setLayoutTemplateId(0, layoutTemplateId, false);

    return LayoutLocalServiceUtil.updateLayout(
        layout.getGroupId(),
        layout.isPrivateLayout(),
        layout.getLayoutId(),
        layout.getTypeSettings());
  }
 /*
  * NOTE FOR DEVELOPERS:
  *
  * Never modify or reference this class directly. All methods that expect a layout model instance should use the {@link Layout} interface instead.
  */
 @Override
 public void persist() {
   if (this.isNew()) {
     LayoutLocalServiceUtil.addLayout(this);
   } else {
     LayoutLocalServiceUtil.updateLayout(this);
   }
 }
  protected void addLayout(long parentLayoutId, JSONObject layoutJSONObject) throws Exception {

    String name = layoutJSONObject.getString("name");
    String title = layoutJSONObject.getString("title");
    boolean hidden = layoutJSONObject.getBoolean("hidden");

    String friendlyURL = layoutJSONObject.getString("friendlyURL");

    if (Validator.isNotNull(friendlyURL) && !friendlyURL.startsWith(StringPool.SLASH)) {

      friendlyURL = StringPool.SLASH + friendlyURL;
    }

    Layout layout =
        LayoutLocalServiceUtil.addLayout(
            userId,
            groupId,
            privateLayout,
            parentLayoutId,
            name,
            title,
            StringPool.BLANK,
            LayoutConstants.TYPE_PORTLET,
            hidden,
            friendlyURL,
            serviceContext);

    LayoutTypePortlet layoutTypePortlet = (LayoutTypePortlet) layout.getLayoutType();

    String layoutTemplateId =
        layoutJSONObject.getString("layoutTemplateId", _defaultLayoutTemplateId);

    if (Validator.isNotNull(layoutTemplateId)) {
      layoutTypePortlet.setLayoutTemplateId(userId, layoutTemplateId, false);
    }

    JSONArray columnsJSONArray = layoutJSONObject.getJSONArray("columns");

    addLayoutColumns(layout, columnsJSONArray);

    LayoutLocalServiceUtil.updateLayout(
        groupId, layout.isPrivateLayout(), layout.getLayoutId(), layout.getTypeSettings());

    JSONArray layoutsJSONArray = layoutJSONObject.getJSONArray("layouts");

    addLayouts(layout.getLayoutId(), layoutsJSONArray);
  }
  protected void addLayout(long groupId, boolean privateLayout, Map<Locale, String> friendlyURLMap)
      throws Exception {

    ServiceContext serviceContext = ServiceContextTestUtil.getServiceContext(groupId);

    LayoutLocalServiceUtil.addLayout(
        TestPropsValues.getUserId(),
        groupId,
        privateLayout,
        LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
        RandomTestUtil.randomLocaleStringMap(),
        RandomTestUtil.randomLocaleStringMap(),
        RandomTestUtil.randomLocaleStringMap(),
        RandomTestUtil.randomLocaleStringMap(),
        RandomTestUtil.randomLocaleStringMap(),
        LayoutConstants.TYPE_PORTLET,
        StringPool.BLANK,
        false,
        friendlyURLMap,
        serviceContext);
  }
  @Override
  public void setUp() throws Exception {
    super.setUp();

    layout = LayoutTestUtil.addLayout(stagingGroup.getGroupId(), ServiceTestUtil.randomString());

    ServiceContext serviceContext = new ServiceContext();

    serviceContext.setUuid(layout.getUuid());

    LayoutLocalServiceUtil.addLayout(
        TestPropsValues.getUserId(),
        liveGroup.getGroupId(),
        layout.getPrivateLayout(),
        layout.getParentLayoutId(),
        layout.getName(),
        layout.getTitle(),
        layout.getDescription(),
        layout.getType(),
        layout.getHidden(),
        layout.getFriendlyURL(),
        serviceContext);
  }
  @Test
  public void testChildLayoutFriendlyURL() throws Exception {
    ServiceContext serviceContext = ServiceContextTestUtil.getServiceContext();

    UserGroup userGroup =
        UserGroupLocalServiceUtil.addUserGroup(
            TestPropsValues.getUserId(),
            TestPropsValues.getCompanyId(),
            "Test " + RandomTestUtil.nextInt(),
            StringPool.BLANK,
            serviceContext);

    _group = userGroup.getGroup();

    Layout homeLayout =
        LayoutLocalServiceUtil.addLayout(
            serviceContext.getUserId(),
            _group.getGroupId(),
            true,
            LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
            "Home",
            StringPool.BLANK,
            StringPool.BLANK,
            LayoutConstants.TYPE_PORTLET,
            false,
            StringPool.BLANK,
            serviceContext);

    LayoutLocalServiceUtil.addLayout(
        serviceContext.getUserId(),
        _group.getGroupId(),
        true,
        homeLayout.getLayoutId(),
        "Child Layout",
        StringPool.BLANK,
        StringPool.BLANK,
        LayoutConstants.TYPE_PORTLET,
        false,
        StringPool.BLANK,
        serviceContext);

    String actualURL =
        PortalUtil.getActualURL(
            userGroup.getGroup().getGroupId(),
            true,
            Portal.PATH_MAIN,
            "/~/" + userGroup.getUserGroupId() + "/child-layout",
            new HashMap<String, String[]>(),
            getRequestContext());

    Assert.assertNotNull(actualURL);

    try {
      PortalUtil.getActualURL(
          userGroup.getGroup().getGroupId(),
          true,
          Portal.PATH_MAIN,
          "/~/" + userGroup.getUserGroupId() + "/non-existing-child-layout",
          new HashMap<String, String[]>(),
          getRequestContext());

      Assert.fail();
    } catch (NoSuchLayoutException nsle) {
    }
  }
  @Test
  public void testWithModuleLayoutTypeController() throws Exception {
    final String prpName = "categoryId";
    final String prpValue =
        RandomTestUtil.randomString(
            FriendlyURLRandomizerBumper.INSTANCE,
            NumericStringRandomizerBumper.INSTANCE,
            UniqueStringRandomizerBumper.INSTANCE);
    final AtomicBoolean success = new AtomicBoolean(false);

    properties.put(
        "com.liferay.portlet.application-type",
        new String[] {
          ApplicationType.FULL_PAGE_APPLICATION.toString(), ApplicationType.WIDGET.toString()
        });
    properties.put("javax.portlet.supported-public-render-parameter", prpName);

    testPortlet =
        new TestPortlet() {

          @Override
          public void render(RenderRequest renderRequest, RenderResponse renderResponse)
              throws IOException, PortletException {

            PrintWriter writer = renderResponse.getWriter();

            String value = renderRequest.getParameter(prpName);

            if (prpValue.equals(value)) {
              success.set(true);
            }

            writer.write(value);
          }
        };

    setUpPortlet(testPortlet, properties, TEST_PORTLET_ID, false);

    Portlet portlet =
        PortletLocalServiceUtil.getPortletById(TestPropsValues.getCompanyId(), TEST_PORTLET_ID);

    Assert.assertFalse(portlet.isUndeployedPortlet());

    String name =
        RandomTestUtil.randomString(
            FriendlyURLRandomizerBumper.INSTANCE,
            NumericStringRandomizerBumper.INSTANCE,
            UniqueStringRandomizerBumper.INSTANCE);

    layout =
        LayoutLocalServiceUtil.addLayout(
            TestPropsValues.getUserId(),
            group.getGroupId(),
            false,
            LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
            name,
            null,
            null,
            "full_page_application",
            false,
            StringPool.SLASH + FriendlyURLNormalizerUtil.normalize(name),
            ServiceContextTestUtil.getServiceContext());

    HttpServletRequest httpServletRequest = getHttpServletRequest();

    PortletURL portletURL =
        new PortletURLImpl(
            httpServletRequest, TEST_PORTLET_ID, layout.getPlid(), PortletRequest.RENDER_PHASE);

    portletURL.setParameter(prpName, prpValue);

    String portletURLString = portletURL.toString();

    Assert.assertTrue(portletURLString.contains(PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE));

    Map<String, List<String>> responseMap = request(portletURLString);

    Assert.assertEquals("200", getString(responseMap, "code"));
    Assert.assertTrue(success.get());
  }