001
014
015 package com.liferay.portlet.layoutsadmin.action;
016
017 import com.liferay.portal.ImageTypeException;
018 import com.liferay.portal.LayoutFriendlyURLException;
019 import com.liferay.portal.LayoutFriendlyURLsException;
020 import com.liferay.portal.LayoutNameException;
021 import com.liferay.portal.LayoutParentLayoutIdException;
022 import com.liferay.portal.LayoutSetVirtualHostException;
023 import com.liferay.portal.LayoutTypeException;
024 import com.liferay.portal.NoSuchGroupException;
025 import com.liferay.portal.NoSuchLayoutException;
026 import com.liferay.portal.RequiredLayoutException;
027 import com.liferay.portal.SitemapChangeFrequencyException;
028 import com.liferay.portal.SitemapIncludeException;
029 import com.liferay.portal.SitemapPagePriorityException;
030 import com.liferay.portal.events.EventsProcessorUtil;
031 import com.liferay.portal.kernel.exception.PortalException;
032 import com.liferay.portal.kernel.exception.SystemException;
033 import com.liferay.portal.kernel.log.Log;
034 import com.liferay.portal.kernel.log.LogFactoryUtil;
035 import com.liferay.portal.kernel.servlet.SessionErrors;
036 import com.liferay.portal.kernel.servlet.SessionMessages;
037 import com.liferay.portal.kernel.staging.StagingUtil;
038 import com.liferay.portal.kernel.upload.UploadException;
039 import com.liferay.portal.kernel.upload.UploadPortletRequest;
040 import com.liferay.portal.kernel.util.Constants;
041 import com.liferay.portal.kernel.util.FileUtil;
042 import com.liferay.portal.kernel.util.HtmlUtil;
043 import com.liferay.portal.kernel.util.HttpUtil;
044 import com.liferay.portal.kernel.util.LocalizationUtil;
045 import com.liferay.portal.kernel.util.ParamUtil;
046 import com.liferay.portal.kernel.util.PropertiesParamUtil;
047 import com.liferay.portal.kernel.util.PropsKeys;
048 import com.liferay.portal.kernel.util.StringPool;
049 import com.liferay.portal.kernel.util.StringUtil;
050 import com.liferay.portal.kernel.util.ThemeFactoryUtil;
051 import com.liferay.portal.kernel.util.UnicodeProperties;
052 import com.liferay.portal.kernel.util.Validator;
053 import com.liferay.portal.kernel.workflow.WorkflowConstants;
054 import com.liferay.portal.model.ColorScheme;
055 import com.liferay.portal.model.Group;
056 import com.liferay.portal.model.Layout;
057 import com.liferay.portal.model.LayoutConstants;
058 import com.liferay.portal.model.LayoutPrototype;
059 import com.liferay.portal.model.LayoutRevision;
060 import com.liferay.portal.model.LayoutSet;
061 import com.liferay.portal.model.LayoutSetBranch;
062 import com.liferay.portal.model.LayoutTypePortlet;
063 import com.liferay.portal.model.Theme;
064 import com.liferay.portal.model.ThemeSetting;
065 import com.liferay.portal.model.User;
066 import com.liferay.portal.model.impl.ThemeSettingImpl;
067 import com.liferay.portal.security.auth.PrincipalException;
068 import com.liferay.portal.security.permission.ActionKeys;
069 import com.liferay.portal.security.permission.PermissionChecker;
070 import com.liferay.portal.service.LayoutLocalServiceUtil;
071 import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
072 import com.liferay.portal.service.LayoutPrototypeServiceUtil;
073 import com.liferay.portal.service.LayoutRevisionLocalServiceUtil;
074 import com.liferay.portal.service.LayoutServiceUtil;
075 import com.liferay.portal.service.LayoutSetBranchLocalServiceUtil;
076 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
077 import com.liferay.portal.service.PortletLocalServiceUtil;
078 import com.liferay.portal.service.ServiceContext;
079 import com.liferay.portal.service.ServiceContextFactory;
080 import com.liferay.portal.service.ThemeLocalServiceUtil;
081 import com.liferay.portal.service.UserLocalServiceUtil;
082 import com.liferay.portal.service.permission.GroupPermissionUtil;
083 import com.liferay.portal.service.permission.LayoutPermissionUtil;
084 import com.liferay.portal.service.permission.LayoutPrototypePermissionUtil;
085 import com.liferay.portal.service.permission.LayoutSetPrototypePermissionUtil;
086 import com.liferay.portal.service.permission.UserPermissionUtil;
087 import com.liferay.portal.struts.PortletAction;
088 import com.liferay.portal.theme.ThemeDisplay;
089 import com.liferay.portal.util.LayoutSettings;
090 import com.liferay.portal.util.PortalUtil;
091 import com.liferay.portal.util.PropsValues;
092 import com.liferay.portal.util.WebKeys;
093 import com.liferay.portlet.mobiledevicerules.model.MDRAction;
094 import com.liferay.portlet.mobiledevicerules.model.MDRRuleGroupInstance;
095 import com.liferay.portlet.mobiledevicerules.service.MDRActionLocalServiceUtil;
096 import com.liferay.portlet.mobiledevicerules.service.MDRActionServiceUtil;
097 import com.liferay.portlet.mobiledevicerules.service.MDRRuleGroupInstanceLocalServiceUtil;
098 import com.liferay.portlet.mobiledevicerules.service.MDRRuleGroupInstanceServiceUtil;
099 import com.liferay.portlet.sites.action.ActionUtil;
100 import com.liferay.portlet.sites.util.SitesUtil;
101
102 import java.io.IOException;
103 import java.io.InputStream;
104
105 import java.util.Iterator;
106 import java.util.List;
107 import java.util.Locale;
108 import java.util.Map;
109 import java.util.Set;
110
111 import javax.portlet.ActionRequest;
112 import javax.portlet.ActionResponse;
113 import javax.portlet.PortletConfig;
114 import javax.portlet.PortletContext;
115 import javax.portlet.PortletRequest;
116 import javax.portlet.PortletRequestDispatcher;
117 import javax.portlet.RenderRequest;
118 import javax.portlet.RenderResponse;
119 import javax.portlet.ResourceRequest;
120 import javax.portlet.ResourceResponse;
121
122 import javax.servlet.http.HttpServletRequest;
123 import javax.servlet.http.HttpServletResponse;
124
125 import org.apache.struts.action.ActionForm;
126 import org.apache.struts.action.ActionForward;
127 import org.apache.struts.action.ActionMapping;
128
129
133 public class EditLayoutsAction extends PortletAction {
134
135 @Override
136 public void processAction(
137 ActionMapping actionMapping, ActionForm actionForm,
138 PortletConfig portletConfig, ActionRequest actionRequest,
139 ActionResponse actionResponse)
140 throws Exception {
141
142 try {
143 checkPermissions(actionRequest);
144 }
145 catch (PrincipalException pe) {
146 return;
147 }
148
149 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
150 WebKeys.THEME_DISPLAY);
151
152 String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
153
154 String redirect = ParamUtil.getString(actionRequest, "redirect");
155 String closeRedirect = ParamUtil.getString(
156 actionRequest, "closeRedirect");
157
158 try {
159 Layout layout = null;
160 String oldFriendlyURL = StringPool.BLANK;
161
162 if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
163 Object[] returnValue = updateLayout(
164 actionRequest, actionResponse);
165
166 layout = (Layout)returnValue[0];
167 oldFriendlyURL = (String)returnValue[1];
168
169 redirect = updateCloseRedirect(
170 themeDisplay, redirect, null, layout, oldFriendlyURL);
171 closeRedirect = updateCloseRedirect(
172 themeDisplay, closeRedirect, null, layout, oldFriendlyURL);
173
174 SessionMessages.add(
175 actionRequest,
176 PortalUtil.getPortletId(actionRequest) + "pageAdded",
177 layout);
178 }
179 else if (cmd.equals(Constants.DELETE)) {
180 long plid = ParamUtil.getLong(actionRequest, "plid");
181
182 if (plid <= 0) {
183 long groupId = ParamUtil.getLong(actionRequest, "groupId");
184 boolean privateLayout = ParamUtil.getBoolean(
185 actionRequest, "privateLayout");
186 long layoutId = ParamUtil.getLong(
187 actionRequest, "layoutId");
188
189 layout = LayoutLocalServiceUtil.getLayout(
190 groupId, privateLayout, layoutId);
191
192 plid = layout.getPlid();
193 }
194
195 Object[] returnValue = SitesUtil.deleteLayout(
196 actionRequest, actionResponse);
197
198 Group group = (Group)returnValue[0];
199 oldFriendlyURL = (String)returnValue[1];
200 long newRefererPlid = (Long)returnValue[2];
201
202 redirect = updateCloseRedirect(
203 themeDisplay, redirect, group, null, oldFriendlyURL);
204
205 long refererPlid = themeDisplay.getRefererPlid();
206
207 if (plid == refererPlid) {
208 redirect = HttpUtil.setParameter(
209 redirect, "refererPlid", newRefererPlid);
210 redirect = HttpUtil.setParameter(
211 redirect, actionResponse.getNamespace() + "selPlid", 0);
212 }
213
214 closeRedirect = updateCloseRedirect(
215 themeDisplay, closeRedirect, group, null, oldFriendlyURL);
216
217 redirect = HttpUtil.addParameter(
218 redirect, actionResponse.getNamespace() + "closeRedirect",
219 closeRedirect);
220 }
221 else if (cmd.equals("display_order")) {
222 updateDisplayOrder(actionRequest);
223 }
224 else if (cmd.equals("delete_layout_revision")) {
225 deleteLayoutRevision(actionRequest);
226 }
227 else if (cmd.equals("enable")) {
228 enableLayout(actionRequest);
229 }
230 else if (cmd.equals("reset_customized_view")) {
231 LayoutTypePortlet layoutTypePortlet =
232 themeDisplay.getLayoutTypePortlet();
233
234 if ((layoutTypePortlet != null) &&
235 layoutTypePortlet.isCustomizable() &&
236 layoutTypePortlet.isCustomizedView()) {
237
238 layoutTypePortlet.resetUserPreferences();
239 }
240 }
241 else if (cmd.equals("reset_merge_fail_count_and_merge")) {
242 resetMergeFailCountAndMerge(actionRequest);
243 }
244 else if (cmd.equals("reset_prototype")) {
245 SitesUtil.resetPrototype(themeDisplay.getLayout());
246 }
247 else if (cmd.equals("select_layout_set_branch")) {
248 selectLayoutSetBranch(actionRequest);
249 }
250 else if (cmd.equals("select_layout_branch")) {
251 selectLayoutBranch(actionRequest);
252 }
253 else if (cmd.equals("update_layout_revision")) {
254 updateLayoutRevision(actionRequest, themeDisplay);
255 }
256
257 sendRedirect(
258 portletConfig, actionRequest, actionResponse, redirect,
259 closeRedirect);
260 }
261 catch (Exception e) {
262 if (e instanceof NoSuchLayoutException ||
263 e instanceof PrincipalException) {
264
265 SessionErrors.add(actionRequest, e.getClass());
266
267 setForward(actionRequest, "portlet.layouts_admin.error");
268 }
269 else if (e instanceof ImageTypeException ||
270 e instanceof LayoutFriendlyURLException ||
271 e instanceof LayoutFriendlyURLsException ||
272 e instanceof LayoutNameException ||
273 e instanceof LayoutParentLayoutIdException ||
274 e instanceof LayoutSetVirtualHostException ||
275 e instanceof LayoutTypeException ||
276 e instanceof RequiredLayoutException ||
277 e instanceof SitemapChangeFrequencyException ||
278 e instanceof SitemapIncludeException ||
279 e instanceof SitemapPagePriorityException ||
280 e instanceof UploadException) {
281
282 SessionErrors.add(actionRequest, e.getClass(), e);
283
284 if (cmd.equals(Constants.ADD)) {
285 SessionMessages.add(
286 actionRequest,
287 PortalUtil.getPortletId(actionRequest) + "addError", e);
288 }
289 }
290 else if (e instanceof SystemException) {
291 SessionErrors.add(actionRequest, e.getClass(), e);
292
293 redirect = ParamUtil.getString(actionRequest, "pagesRedirect");
294
295 sendRedirect(
296 portletConfig, actionRequest, actionResponse, redirect,
297 closeRedirect);
298 }
299 else {
300 throw e;
301 }
302 }
303 }
304
305 @Override
306 public ActionForward render(
307 ActionMapping actionMapping, ActionForm actionForm,
308 PortletConfig portletConfig, RenderRequest renderRequest,
309 RenderResponse renderResponse)
310 throws Exception {
311
312 try {
313 checkPermissions(renderRequest);
314 }
315 catch (PrincipalException pe) {
316 SessionErrors.add(
317 renderRequest, PrincipalException.class.getName());
318
319 return actionMapping.findForward("portlet.layouts_admin.error");
320 }
321
322 try {
323 getGroup(renderRequest);
324 }
325 catch (Exception e) {
326 if (e instanceof NoSuchGroupException ||
327 e instanceof PrincipalException) {
328
329 SessionErrors.add(renderRequest, e.getClass());
330
331 return actionMapping.findForward("portlet.layouts_admin.error");
332 }
333 else {
334 throw e;
335 }
336 }
337
338 return actionMapping.findForward(
339 getForward(renderRequest, "portlet.layouts_admin.edit_layouts"));
340 }
341
342 @Override
343 public void serveResource(
344 ActionMapping actionMapping, ActionForm actionForm,
345 PortletConfig portletConfig, ResourceRequest resourceRequest,
346 ResourceResponse resourceResponse)
347 throws Exception {
348
349 String cmd = ParamUtil.getString(resourceRequest, Constants.CMD);
350
351 PortletContext portletContext = portletConfig.getPortletContext();
352
353 PortletRequestDispatcher portletRequestDispatcher = null;
354
355 if (cmd.equals(ActionKeys.VIEW_TREE)) {
356 getGroup(resourceRequest);
357
358 portletRequestDispatcher = portletContext.getRequestDispatcher(
359 "/html/portlet/layouts_admin/tree_js.jsp");
360 }
361 else {
362 getGroup(resourceRequest);
363
364 portletRequestDispatcher = portletContext.getRequestDispatcher(
365 "/html/portlet/layouts_admin/view_resources.jsp");
366 }
367
368 portletRequestDispatcher.include(resourceRequest, resourceResponse);
369 }
370
371 protected void checkPermission(
372 PermissionChecker permissionChecker, Group group, Layout layout,
373 long selPlid)
374 throws PortalException, SystemException {
375
376 if (selPlid > 0) {
377 LayoutPermissionUtil.check(
378 permissionChecker, layout, ActionKeys.VIEW);
379 }
380 else {
381 GroupPermissionUtil.check(
382 permissionChecker, group, ActionKeys.VIEW);
383 }
384 }
385
386 protected void checkPermissions(PortletRequest portletRequest)
387 throws Exception {
388
389 Group group = getGroup(portletRequest);
390
391 if (group == null) {
392 throw new PrincipalException();
393 }
394
395 ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
396 WebKeys.THEME_DISPLAY);
397
398 PermissionChecker permissionChecker =
399 themeDisplay.getPermissionChecker();
400
401 Layout layout = themeDisplay.getLayout();
402
403 String cmd = ParamUtil.getString(portletRequest, Constants.CMD);
404
405 long selPlid = ParamUtil.getLong(portletRequest, "selPlid");
406
407 if (selPlid > 0) {
408 layout = LayoutLocalServiceUtil.getLayout(selPlid);
409 }
410
411 if (cmd.equals(Constants.ADD)) {
412 long parentPlid = ParamUtil.getLong(portletRequest, "parentPlid");
413
414 if (parentPlid == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
415 if (!GroupPermissionUtil.contains(
416 permissionChecker, group.getGroupId(),
417 ActionKeys.ADD_LAYOUT)) {
418
419 throw new PrincipalException();
420 }
421 }
422 else {
423 layout = LayoutLocalServiceUtil.getLayout(parentPlid);
424
425 if (!LayoutPermissionUtil.contains(
426 permissionChecker, layout, ActionKeys.ADD_LAYOUT)) {
427
428 throw new PrincipalException();
429 }
430 }
431 }
432 else if (cmd.equals(Constants.DELETE)) {
433 if (!LayoutPermissionUtil.contains(
434 permissionChecker, layout, ActionKeys.DELETE)) {
435
436 throw new PrincipalException();
437 }
438 }
439 else if (cmd.equals(Constants.UPDATE)) {
440 if (group.isCompany()) {
441 if (!permissionChecker.isCompanyAdmin()) {
442 throw new PrincipalException();
443 }
444 }
445 else if (group.isLayoutPrototype()) {
446 LayoutPrototypePermissionUtil.check(
447 permissionChecker, group.getClassPK(), ActionKeys.UPDATE);
448 }
449 else if (group.isLayoutSetPrototype()) {
450 LayoutSetPrototypePermissionUtil.check(
451 permissionChecker, group.getClassPK(), ActionKeys.UPDATE);
452 }
453 else if (group.isUser()) {
454 long groupUserId = group.getClassPK();
455
456 User groupUser = UserLocalServiceUtil.getUserById(groupUserId);
457
458 long[] organizationIds = groupUser.getOrganizationIds();
459
460 UserPermissionUtil.check(
461 permissionChecker, groupUserId, organizationIds,
462 ActionKeys.UPDATE);
463 }
464 else {
465 checkPermission(permissionChecker, group, layout, selPlid);
466 }
467 }
468 else if (cmd.equals("publish_to_live") ||
469 cmd.equals("publish_to_remote") ||
470 cmd.equals("schedule_publish_to_live") ||
471 cmd.equals("schedule_publish_to_remote")) {
472
473 boolean hasUpdateLayoutPermission = false;
474
475 if (layout != null) {
476 hasUpdateLayoutPermission = LayoutPermissionUtil.contains(
477 permissionChecker, layout, ActionKeys.UPDATE);
478 }
479
480 if (group.isCompany() || group.isSite()) {
481 boolean publishToLive = GroupPermissionUtil.contains(
482 permissionChecker, group.getGroupId(),
483 ActionKeys.PUBLISH_STAGING);
484
485 if (!hasUpdateLayoutPermission && !publishToLive) {
486 throw new PrincipalException();
487 }
488 }
489 else {
490 checkPermission(permissionChecker, group, layout, selPlid);
491 }
492 }
493 else if (cmd.equals("reset_customized_view")) {
494 if (!LayoutPermissionUtil.contains(
495 permissionChecker, layout, ActionKeys.CUSTOMIZE)) {
496
497 throw new PrincipalException();
498 }
499 }
500 else {
501 checkPermission(permissionChecker, group, layout, selPlid);
502 }
503 }
504
505 protected void deleteLayoutRevision(ActionRequest actionRequest)
506 throws Exception {
507
508 HttpServletRequest request = PortalUtil.getHttpServletRequest(
509 actionRequest);
510
511 long layoutRevisionId = ParamUtil.getLong(
512 actionRequest, "layoutRevisionId");
513
514 LayoutRevision layoutRevision =
515 LayoutRevisionLocalServiceUtil.getLayoutRevision(layoutRevisionId);
516
517 LayoutRevisionLocalServiceUtil.deleteLayoutRevision(layoutRevision);
518
519 boolean updateRecentLayoutRevisionId = ParamUtil.getBoolean(
520 actionRequest, "updateRecentLayoutRevisionId");
521
522 if (updateRecentLayoutRevisionId) {
523 StagingUtil.setRecentLayoutRevisionId(
524 request, layoutRevision.getLayoutSetBranchId(),
525 layoutRevision.getPlid(),
526 layoutRevision.getParentLayoutRevisionId());
527 }
528 }
529
530 protected void deleteThemeSettingsProperties(
531 UnicodeProperties typeSettingsProperties, String device) {
532
533 String keyPrefix = ThemeSettingImpl.namespaceProperty(device);
534
535 Set<String> keys = typeSettingsProperties.keySet();
536
537 Iterator<String> itr = keys.iterator();
538
539 while (itr.hasNext()) {
540 String key = itr.next();
541
542 if (key.startsWith(keyPrefix)) {
543 itr.remove();
544 }
545 }
546 }
547
548 protected void enableLayout(ActionRequest actionRequest) throws Exception {
549 long incompleteLayoutRevisionId = ParamUtil.getLong(
550 actionRequest, "incompleteLayoutRevisionId");
551
552 LayoutRevision incompleteLayoutRevision =
553 LayoutRevisionLocalServiceUtil.getLayoutRevision(
554 incompleteLayoutRevisionId);
555
556 long layoutBranchId = ParamUtil.getLong(
557 actionRequest, "layoutBranchId",
558 incompleteLayoutRevision.getLayoutBranchId());
559
560 ServiceContext serviceContext = ServiceContextFactory.getInstance(
561 actionRequest);
562
563 serviceContext.setWorkflowAction(WorkflowConstants.ACTION_SAVE_DRAFT);
564
565 LayoutRevisionLocalServiceUtil.updateLayoutRevision(
566 serviceContext.getUserId(),
567 incompleteLayoutRevision.getLayoutRevisionId(), layoutBranchId,
568 incompleteLayoutRevision.getName(),
569 incompleteLayoutRevision.getTitle(),
570 incompleteLayoutRevision.getDescription(),
571 incompleteLayoutRevision.getKeywords(),
572 incompleteLayoutRevision.getRobots(),
573 incompleteLayoutRevision.getTypeSettings(),
574 incompleteLayoutRevision.getIconImage(),
575 incompleteLayoutRevision.getIconImageId(),
576 incompleteLayoutRevision.getThemeId(),
577 incompleteLayoutRevision.getColorSchemeId(),
578 incompleteLayoutRevision.getWapThemeId(),
579 incompleteLayoutRevision.getWapColorSchemeId(),
580 incompleteLayoutRevision.getCss(), serviceContext);
581 }
582
583 protected String getColorSchemeId(
584 long companyId, String themeId, String colorSchemeId,
585 boolean wapTheme)
586 throws Exception {
587
588 Theme theme = ThemeLocalServiceUtil.getTheme(
589 companyId, themeId, wapTheme);
590
591 if (!theme.hasColorSchemes()) {
592 colorSchemeId = StringPool.BLANK;
593 }
594
595 if (Validator.isNull(colorSchemeId)) {
596 ColorScheme colorScheme = ThemeLocalServiceUtil.getColorScheme(
597 companyId, themeId, colorSchemeId, wapTheme);
598
599 colorSchemeId = colorScheme.getColorSchemeId();
600 }
601
602 return colorSchemeId;
603 }
604
605 protected String getDefaultThemeSetting(
606 Layout layout, String key, String device, boolean inheritLookAndFeel) {
607
608 if (!inheritLookAndFeel) {
609 try {
610 Theme theme = null;
611
612 if (device.equals("regular")) {
613 theme = layout.getTheme();
614 }
615 else {
616 theme = layout.getWapTheme();
617 }
618
619 return theme.getSetting(key);
620 }
621 catch (Exception e) {
622 }
623 }
624
625 try {
626 LayoutSet layoutSet = layout.getLayoutSet();
627
628 return layoutSet.getThemeSetting(key, device);
629 }
630 catch (Exception e) {
631 }
632
633 return StringPool.BLANK;
634 }
635
636 protected Group getGroup(PortletRequest portletRequest) throws Exception {
637 return ActionUtil.getGroup(portletRequest);
638 }
639
640 protected byte[] getIconBytes(
641 UploadPortletRequest uploadPortletRequest, String iconFileName) {
642
643 InputStream inputStream = null;
644
645 try {
646 inputStream = uploadPortletRequest.getFileAsStream(iconFileName);
647
648 if (inputStream != null) {
649 return FileUtil.getBytes(inputStream);
650 }
651 }
652 catch (IOException ioe) {
653 if (_log.isWarnEnabled()) {
654 _log.warn("Unable to retrieve icon", ioe);
655 }
656 }
657
658 return new byte[0];
659 }
660
661 protected void inheritMobileRuleGroups(
662 Layout layout, ServiceContext serviceContext)
663 throws PortalException, SystemException {
664
665 List<MDRRuleGroupInstance> parentMDRRuleGroupInstances =
666 MDRRuleGroupInstanceLocalServiceUtil.getRuleGroupInstances(
667 Layout.class.getName(), layout.getParentPlid());
668
669 for (MDRRuleGroupInstance parentMDRRuleGroupInstance :
670 parentMDRRuleGroupInstances) {
671
672 MDRRuleGroupInstance mdrRuleGroupInstance =
673 MDRRuleGroupInstanceServiceUtil.addRuleGroupInstance(
674 layout.getGroupId(), Layout.class.getName(),
675 layout.getPlid(),
676 parentMDRRuleGroupInstance.getRuleGroupId(),
677 parentMDRRuleGroupInstance.getPriority(), serviceContext);
678
679 List<MDRAction> parentMDRActions =
680 MDRActionLocalServiceUtil.getActions(
681 parentMDRRuleGroupInstance.getRuleGroupInstanceId());
682
683 for (MDRAction mdrAction : parentMDRActions) {
684 MDRActionServiceUtil.addAction(
685 mdrRuleGroupInstance.getRuleGroupInstanceId(),
686 mdrAction.getNameMap(), mdrAction.getDescriptionMap(),
687 mdrAction.getType(), mdrAction.getTypeSettings(),
688 serviceContext);
689 }
690 }
691 }
692
693 @Override
694 protected boolean isCheckMethodOnProcessAction() {
695 return _CHECK_METHOD_ON_PROCESS_ACTION;
696 }
697
698
713 protected void resetMergeFailCountAndMerge(ActionRequest actionRequest)
714 throws Exception {
715
716 long layoutPrototypeId = ParamUtil.getLong(
717 actionRequest, "layoutPrototypeId");
718
719 LayoutPrototype layoutPrototype =
720 LayoutPrototypeLocalServiceUtil.getLayoutPrototype(
721 layoutPrototypeId);
722
723 SitesUtil.setMergeFailCount(layoutPrototype, 0);
724
725 long selPlid = ParamUtil.getLong(actionRequest, "selPlid");
726
727 Layout selLayout = LayoutLocalServiceUtil.getLayout(selPlid);
728
729 SitesUtil.resetPrototype(selLayout);
730
731 SitesUtil.mergeLayoutPrototypeLayout(selLayout.getGroup(), selLayout);
732
733 layoutPrototype = LayoutPrototypeServiceUtil.getLayoutPrototype(
734 layoutPrototypeId);
735
736 int mergeFailCountAfterMerge = SitesUtil.getMergeFailCount(
737 layoutPrototype);
738
739 if (mergeFailCountAfterMerge > 0) {
740 SessionErrors.add(actionRequest, "resetMergeFailCountAndMerge");
741 }
742 }
743
744 protected void selectLayoutBranch(ActionRequest actionRequest)
745 throws Exception {
746
747 HttpServletRequest request = PortalUtil.getHttpServletRequest(
748 actionRequest);
749
750 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
751 WebKeys.THEME_DISPLAY);
752
753 long layoutSetBranchId = ParamUtil.getLong(
754 actionRequest, "layoutSetBranchId");
755
756 long layoutBranchId = ParamUtil.getLong(
757 actionRequest, "layoutBranchId");
758
759 StagingUtil.setRecentLayoutBranchId(
760 request, layoutSetBranchId, themeDisplay.getPlid(), layoutBranchId);
761 }
762
763 protected void selectLayoutSetBranch(ActionRequest actionRequest)
764 throws Exception {
765
766 HttpServletRequest request = PortalUtil.getHttpServletRequest(
767 actionRequest);
768
769 long groupId = ParamUtil.getLong(actionRequest, "groupId");
770 boolean privateLayout = ParamUtil.getBoolean(
771 actionRequest, "privateLayout");
772
773 LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
774 groupId, privateLayout);
775
776 long layoutSetBranchId = ParamUtil.getLong(
777 actionRequest, "layoutSetBranchId");
778
779
780
781 LayoutSetBranch layoutSetBranch =
782 LayoutSetBranchLocalServiceUtil.getLayoutSetBranch(
783 layoutSetBranchId);
784
785 StagingUtil.setRecentLayoutSetBranchId(
786 request, layoutSet.getLayoutSetId(),
787 layoutSetBranch.getLayoutSetBranchId());
788 }
789
790 protected void setThemeSettingProperties(
791 ActionRequest actionRequest,
792 UnicodeProperties typeSettingsProperties, String themeId,
793 Map<String, ThemeSetting> themeSettings, String device,
794 String deviceThemeId)
795 throws PortalException, SystemException {
796
797 long groupId = ParamUtil.getLong(actionRequest, "groupId");
798 boolean privateLayout = ParamUtil.getBoolean(
799 actionRequest, "privateLayout");
800 long layoutId = ParamUtil.getLong(actionRequest, "layoutId");
801
802 Layout layout = LayoutLocalServiceUtil.getLayout(
803 groupId, privateLayout, layoutId);
804
805 for (String key : themeSettings.keySet()) {
806 ThemeSetting themeSetting = themeSettings.get(key);
807
808 String property =
809 device + "ThemeSettingsProperties--" + key +
810 StringPool.DOUBLE_DASH;
811
812 String value = ParamUtil.getString(
813 actionRequest, HtmlUtil.escapeAttribute(property),
814 themeSetting.getValue());
815
816 if (!Validator.equals(
817 value,
818 getDefaultThemeSetting(layout, key, device, false))) {
819
820 typeSettingsProperties.setProperty(
821 ThemeSettingImpl.namespaceProperty(device, key), value);
822 }
823 }
824 }
825
826 protected String updateCloseRedirect(
827 ThemeDisplay themeDisplay, String closeRedirect, Group group,
828 Layout layout, String oldLayoutFriendlyURL) {
829
830 if (Validator.isNull(closeRedirect) ||
831 Validator.isNull(oldLayoutFriendlyURL)) {
832
833 return closeRedirect;
834 }
835
836 if (layout != null) {
837 String oldPath = oldLayoutFriendlyURL;
838 String newPath = layout.getFriendlyURL(themeDisplay.getLocale());
839
840 return PortalUtil.updateRedirect(closeRedirect, oldPath, newPath);
841 }
842 else if (group != null) {
843 String oldPath = group.getFriendlyURL() + oldLayoutFriendlyURL;
844 String newPath = group.getFriendlyURL();
845
846 return PortalUtil.updateRedirect(closeRedirect, oldPath, newPath);
847 }
848
849 return closeRedirect;
850 }
851
852 protected void updateDisplayOrder(ActionRequest actionRequest)
853 throws Exception {
854
855 long groupId = ParamUtil.getLong(actionRequest, "groupId");
856 boolean privateLayout = ParamUtil.getBoolean(
857 actionRequest, "privateLayout");
858 long parentLayoutId = ParamUtil.getLong(
859 actionRequest, "parentLayoutId");
860 long[] layoutIds = StringUtil.split(
861 ParamUtil.getString(actionRequest, "layoutIds"), 0L);
862
863 ServiceContext serviceContext = ServiceContextFactory.getInstance(
864 actionRequest);
865
866 LayoutServiceUtil.setLayouts(
867 groupId, privateLayout, parentLayoutId, layoutIds, serviceContext);
868 }
869
870 protected Object[] updateLayout(
871 ActionRequest actionRequest, ActionResponse actionResponse)
872 throws Exception {
873
874 UploadPortletRequest uploadPortletRequest =
875 PortalUtil.getUploadPortletRequest(actionRequest);
876
877 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
878 WebKeys.THEME_DISPLAY);
879
880 String cmd = ParamUtil.getString(uploadPortletRequest, Constants.CMD);
881
882 long groupId = ParamUtil.getLong(actionRequest, "groupId");
883 long liveGroupId = ParamUtil.getLong(actionRequest, "liveGroupId");
884 long stagingGroupId = ParamUtil.getLong(
885 actionRequest, "stagingGroupId");
886 boolean privateLayout = ParamUtil.getBoolean(
887 actionRequest, "privateLayout");
888 long layoutId = ParamUtil.getLong(actionRequest, "layoutId");
889 long parentLayoutId = ParamUtil.getLong(
890 uploadPortletRequest, "parentLayoutId");
891 Map<Locale, String> nameMap = LocalizationUtil.getLocalizationMap(
892 actionRequest, "name");
893 Map<Locale, String> titleMap = LocalizationUtil.getLocalizationMap(
894 actionRequest, "title");
895 Map<Locale, String> descriptionMap =
896 LocalizationUtil.getLocalizationMap(actionRequest, "description");
897 Map<Locale, String> keywordsMap = LocalizationUtil.getLocalizationMap(
898 actionRequest, "keywords");
899 Map<Locale, String> robotsMap = LocalizationUtil.getLocalizationMap(
900 actionRequest, "robots");
901 String type = ParamUtil.getString(uploadPortletRequest, "type");
902 boolean hidden = ParamUtil.getBoolean(uploadPortletRequest, "hidden");
903 Map<Locale, String> friendlyURLMap =
904 LocalizationUtil.getLocalizationMap(actionRequest, "friendlyURL");
905 boolean iconImage = ParamUtil.getBoolean(
906 uploadPortletRequest, "iconImage");
907 byte[] iconBytes = getIconBytes(uploadPortletRequest, "iconFileName");
908 long layoutPrototypeId = ParamUtil.getLong(
909 uploadPortletRequest, "layoutPrototypeId");
910
911 ServiceContext serviceContext = ServiceContextFactory.getInstance(
912 Layout.class.getName(), actionRequest);
913
914 Layout layout = null;
915 UnicodeProperties layoutTypeSettingsProperties = null;
916 String oldFriendlyURL = StringPool.BLANK;
917
918 if (cmd.equals(Constants.ADD)) {
919
920
921
922 boolean inheritFromParentLayoutId = ParamUtil.getBoolean(
923 uploadPortletRequest, "inheritFromParentLayoutId");
924
925 UnicodeProperties typeSettingsProperties =
926 PropertiesParamUtil.getProperties(
927 actionRequest, "TypeSettingsProperties--");
928
929 if (inheritFromParentLayoutId && (parentLayoutId > 0)) {
930 Layout parentLayout = LayoutLocalServiceUtil.getLayout(
931 groupId, privateLayout, parentLayoutId);
932
933 layout = LayoutServiceUtil.addLayout(
934 groupId, privateLayout, parentLayoutId, nameMap, titleMap,
935 parentLayout.getDescriptionMap(),
936 parentLayout.getKeywordsMap(), parentLayout.getRobotsMap(),
937 parentLayout.getType(), parentLayout.getTypeSettings(),
938 hidden, friendlyURLMap, serviceContext);
939
940 inheritMobileRuleGroups(layout, serviceContext);
941
942 if (parentLayout.isTypePortlet()) {
943 ActionUtil.copyPreferences(
944 actionRequest, layout, parentLayout);
945
946 SitesUtil.copyLookAndFeel(layout, parentLayout);
947 }
948 }
949 else if (layoutPrototypeId > 0) {
950 LayoutPrototype layoutPrototype =
951 LayoutPrototypeServiceUtil.getLayoutPrototype(
952 layoutPrototypeId);
953
954 String layoutPrototypeLinkEnabled = ParamUtil.getString(
955 uploadPortletRequest, "layoutPrototypeLinkEnabled");
956
957 if (Validator.isNotNull(layoutPrototypeLinkEnabled)) {
958 serviceContext.setAttribute(
959 "layoutPrototypeLinkEnabled",
960 layoutPrototypeLinkEnabled);
961 }
962
963 serviceContext.setAttribute(
964 "layoutPrototypeUuid", layoutPrototype.getUuid());
965
966 layout = LayoutServiceUtil.addLayout(
967 groupId, privateLayout, parentLayoutId, nameMap, titleMap,
968 descriptionMap, keywordsMap, robotsMap,
969 LayoutConstants.TYPE_PORTLET,
970 typeSettingsProperties.toString(), hidden, friendlyURLMap,
971 serviceContext);
972 }
973 else {
974 long copyLayoutId = ParamUtil.getLong(
975 uploadPortletRequest, "copyLayoutId");
976
977 Layout copyLayout = null;
978
979 String layoutTemplateId = ParamUtil.getString(
980 uploadPortletRequest, "layoutTemplateId",
981 PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID);
982
983 if (copyLayoutId > 0) {
984 try {
985 copyLayout = LayoutLocalServiceUtil.getLayout(
986 groupId, privateLayout, copyLayoutId);
987
988 if (copyLayout.isTypePortlet()) {
989 LayoutTypePortlet copyLayoutTypePortlet =
990 (LayoutTypePortlet)copyLayout.getLayoutType();
991
992 layoutTemplateId =
993 copyLayoutTypePortlet.getLayoutTemplateId();
994
995 typeSettingsProperties =
996 copyLayout.getTypeSettingsProperties();
997 }
998 }
999 catch (NoSuchLayoutException nsle) {
1000 }
1001 }
1002
1003 layout = LayoutServiceUtil.addLayout(
1004 groupId, privateLayout, parentLayoutId, nameMap, titleMap,
1005 descriptionMap, keywordsMap, robotsMap, type,
1006 typeSettingsProperties.toString(), hidden, friendlyURLMap,
1007 serviceContext);
1008
1009 LayoutTypePortlet layoutTypePortlet =
1010 (LayoutTypePortlet)layout.getLayoutType();
1011
1012 layoutTypePortlet.setLayoutTemplateId(
1013 themeDisplay.getUserId(), layoutTemplateId);
1014
1015 LayoutServiceUtil.updateLayout(
1016 groupId, privateLayout, layout.getLayoutId(),
1017 layout.getTypeSettings());
1018
1019 if (copyLayout != null) {
1020 if (copyLayout.isTypePortlet()) {
1021 ActionUtil.copyPreferences(
1022 actionRequest, layout, copyLayout);
1023
1024 SitesUtil.copyLookAndFeel(layout, copyLayout);
1025 }
1026 }
1027 }
1028
1029 layoutTypeSettingsProperties = layout.getTypeSettingsProperties();
1030 }
1031 else {
1032
1033
1034
1035 layout = LayoutLocalServiceUtil.getLayout(
1036 groupId, privateLayout, layoutId);
1037
1038 oldFriendlyURL = layout.getFriendlyURL(themeDisplay.getLocale());
1039
1040 layout = LayoutServiceUtil.updateLayout(
1041 groupId, privateLayout, layoutId, layout.getParentLayoutId(),
1042 nameMap, titleMap, descriptionMap, keywordsMap, robotsMap, type,
1043 hidden, friendlyURLMap, Boolean.valueOf(iconImage), iconBytes,
1044 serviceContext);
1045
1046 layoutTypeSettingsProperties = layout.getTypeSettingsProperties();
1047
1048 if (oldFriendlyURL.equals(
1049 layout.getFriendlyURL(themeDisplay.getLocale()))) {
1050
1051 oldFriendlyURL = StringPool.BLANK;
1052 }
1053
1054 UnicodeProperties formTypeSettingsProperties =
1055 PropertiesParamUtil.getProperties(
1056 actionRequest, "TypeSettingsProperties--");
1057
1058 if (type.equals(LayoutConstants.TYPE_PORTLET)) {
1059 LayoutTypePortlet layoutTypePortlet =
1060 (LayoutTypePortlet)layout.getLayoutType();
1061
1062 String layoutTemplateId = ParamUtil.getString(
1063 uploadPortletRequest, "layoutTemplateId",
1064 PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID);
1065
1066 layoutTypePortlet.setLayoutTemplateId(
1067 themeDisplay.getUserId(), layoutTemplateId);
1068
1069 long copyLayoutId = ParamUtil.getLong(
1070 uploadPortletRequest, "copyLayoutId");
1071
1072 if ((copyLayoutId > 0) &&
1073 (copyLayoutId != layout.getLayoutId())) {
1074
1075 try {
1076 Layout copyLayout = LayoutLocalServiceUtil.getLayout(
1077 groupId, privateLayout, copyLayoutId);
1078
1079 if (copyLayout.isTypePortlet()) {
1080 layoutTypeSettingsProperties =
1081 copyLayout.getTypeSettingsProperties();
1082
1083 ActionUtil.removePortletIds(actionRequest, layout);
1084
1085 ActionUtil.copyPreferences(
1086 actionRequest, layout, copyLayout);
1087
1088 SitesUtil.copyLookAndFeel(layout, copyLayout);
1089 }
1090 }
1091 catch (NoSuchLayoutException nsle) {
1092 }
1093 }
1094 else {
1095 layoutTypeSettingsProperties.putAll(
1096 formTypeSettingsProperties);
1097
1098 LayoutServiceUtil.updateLayout(
1099 groupId, privateLayout, layoutId,
1100 layout.getTypeSettings());
1101 }
1102 }
1103 else {
1104 layout.setTypeSettingsProperties(formTypeSettingsProperties);
1105
1106 layoutTypeSettingsProperties.putAll(
1107 layout.getTypeSettingsProperties());
1108
1109 LayoutServiceUtil.updateLayout(
1110 groupId, privateLayout, layoutId, layout.getTypeSettings());
1111 }
1112
1113 String[] removeEmbeddedPortletIds = ParamUtil.getParameterValues(
1114 actionRequest, "removeEmbeddedPortletIds");
1115
1116 if (removeEmbeddedPortletIds.length > 0) {
1117 PortletLocalServiceUtil.deletePortlets(
1118 themeDisplay.getCompanyId(), removeEmbeddedPortletIds,
1119 layout.getPlid());
1120 }
1121
1122 LayoutSettings layoutSettings = LayoutSettings.getInstance(layout);
1123
1124 HttpServletResponse response = PortalUtil.getHttpServletResponse(
1125 actionResponse);
1126
1127 EventsProcessorUtil.process(
1128 PropsKeys.LAYOUT_CONFIGURATION_ACTION_UPDATE,
1129 layoutSettings.getConfigurationActionUpdate(),
1130 uploadPortletRequest, response);
1131 }
1132
1133 updateLookAndFeel(
1134 actionRequest, themeDisplay.getCompanyId(), liveGroupId,
1135 stagingGroupId, privateLayout, layout.getLayoutId(),
1136 layoutTypeSettingsProperties, layout.getThemeId());
1137
1138 return new Object[] {layout, oldFriendlyURL};
1139 }
1140
1141 protected void updateLayoutRevision(
1142 ActionRequest actionRequest, ThemeDisplay themeDisplay)
1143 throws Exception {
1144
1145 long layoutRevisionId = ParamUtil.getLong(
1146 actionRequest, "layoutRevisionId");
1147
1148 LayoutRevision layoutRevision =
1149 LayoutRevisionLocalServiceUtil.getLayoutRevision(layoutRevisionId);
1150
1151 ServiceContext serviceContext = ServiceContextFactory.getInstance(
1152 actionRequest);
1153
1154 LayoutRevision enableLayoutRevision =
1155 LayoutRevisionLocalServiceUtil.updateLayoutRevision(
1156 serviceContext.getUserId(), layoutRevisionId,
1157 layoutRevision.getLayoutBranchId(), layoutRevision.getName(),
1158 layoutRevision.getTitle(), layoutRevision.getDescription(),
1159 layoutRevision.getKeywords(), layoutRevision.getRobots(),
1160 layoutRevision.getTypeSettings(), layoutRevision.getIconImage(),
1161 layoutRevision.getIconImageId(), layoutRevision.getThemeId(),
1162 layoutRevision.getColorSchemeId(),
1163 layoutRevision.getWapThemeId(),
1164 layoutRevision.getWapColorSchemeId(), layoutRevision.getCss(),
1165 serviceContext);
1166
1167 if (layoutRevision.getStatus() != WorkflowConstants.STATUS_INCOMPLETE) {
1168 StagingUtil.setRecentLayoutRevisionId(
1169 themeDisplay.getUser(), layoutRevision.getLayoutSetBranchId(),
1170 layoutRevision.getPlid(), layoutRevision.getLayoutRevisionId());
1171
1172 return;
1173 }
1174
1175 LayoutRevision lastLayoutRevision =
1176 LayoutRevisionLocalServiceUtil.fetchLastLayoutRevision(
1177 enableLayoutRevision.getPlid(), true);
1178
1179 if (lastLayoutRevision != null) {
1180 LayoutRevision newLayoutRevision =
1181 LayoutRevisionLocalServiceUtil.addLayoutRevision(
1182 serviceContext.getUserId(),
1183 layoutRevision.getLayoutSetBranchId(),
1184 layoutRevision.getLayoutBranchId(),
1185 enableLayoutRevision.getLayoutRevisionId(), false,
1186 layoutRevision.getPlid(),
1187 lastLayoutRevision.getLayoutRevisionId(),
1188 lastLayoutRevision.isPrivateLayout(),
1189 lastLayoutRevision.getName(), lastLayoutRevision.getTitle(),
1190 lastLayoutRevision.getDescription(),
1191 lastLayoutRevision.getKeywords(),
1192 lastLayoutRevision.getRobots(),
1193 lastLayoutRevision.getTypeSettings(),
1194 lastLayoutRevision.isIconImage(),
1195 lastLayoutRevision.getIconImageId(),
1196 lastLayoutRevision.getThemeId(),
1197 lastLayoutRevision.getColorSchemeId(),
1198 lastLayoutRevision.getWapThemeId(),
1199 lastLayoutRevision.getWapColorSchemeId(),
1200 lastLayoutRevision.getCss(), serviceContext);
1201
1202 StagingUtil.setRecentLayoutRevisionId(
1203 themeDisplay.getUser(),
1204 newLayoutRevision.getLayoutSetBranchId(),
1205 newLayoutRevision.getPlid(),
1206 newLayoutRevision.getLayoutRevisionId());
1207 }
1208 }
1209
1210 protected void updateLookAndFeel(
1211 ActionRequest actionRequest, long companyId, long liveGroupId,
1212 long stagingGroupId, boolean privateLayout, long layoutId,
1213 UnicodeProperties typeSettingsProperties, String themeId)
1214 throws Exception {
1215
1216 String[] devices = StringUtil.split(
1217 ParamUtil.getString(actionRequest, "devices"));
1218
1219 for (String device : devices) {
1220 String deviceThemeId = ParamUtil.getString(
1221 actionRequest, device + "ThemeId");
1222 String deviceColorSchemeId = ParamUtil.getString(
1223 actionRequest, device + "ColorSchemeId");
1224 String deviceCss = ParamUtil.getString(
1225 actionRequest, device + "Css");
1226 boolean deviceWapTheme = device.equals("wap");
1227
1228 boolean deviceInheritLookAndFeel = ParamUtil.getBoolean(
1229 actionRequest, device + "InheritLookAndFeel");
1230
1231 if (deviceInheritLookAndFeel) {
1232 deviceThemeId = ThemeFactoryUtil.getDefaultRegularThemeId(
1233 companyId);
1234 deviceColorSchemeId = StringPool.BLANK;
1235
1236 deleteThemeSettingsProperties(typeSettingsProperties, device);
1237 }
1238 else if (Validator.isNotNull(deviceThemeId)) {
1239 deviceColorSchemeId = getColorSchemeId(
1240 companyId, deviceThemeId, deviceColorSchemeId,
1241 deviceWapTheme);
1242
1243 updateThemeSettingsProperties(
1244 actionRequest, companyId, typeSettingsProperties, themeId,
1245 device, deviceThemeId, deviceWapTheme);
1246 }
1247
1248 long groupId = liveGroupId;
1249
1250 if (stagingGroupId > 0) {
1251 groupId = stagingGroupId;
1252 }
1253
1254 LayoutServiceUtil.updateLayout(
1255 groupId, privateLayout, layoutId,
1256 typeSettingsProperties.toString());
1257
1258 LayoutServiceUtil.updateLookAndFeel(
1259 groupId, privateLayout, layoutId, deviceThemeId,
1260 deviceColorSchemeId, deviceCss, deviceWapTheme);
1261 }
1262 }
1263
1264 protected UnicodeProperties updateThemeSettingsProperties(
1265 ActionRequest actionRequest, long companyId,
1266 UnicodeProperties typeSettingsProperties, String themeId,
1267 String device, String deviceThemeId, boolean wapTheme)
1268 throws Exception {
1269
1270 Theme theme = ThemeLocalServiceUtil.getTheme(
1271 companyId, deviceThemeId, wapTheme);
1272
1273 deleteThemeSettingsProperties(typeSettingsProperties, device);
1274
1275 Map<String, ThemeSetting> themeSettings =
1276 theme.getConfigurableSettings();
1277
1278 if (themeSettings.isEmpty()) {
1279 return typeSettingsProperties;
1280 }
1281
1282 setThemeSettingProperties(
1283 actionRequest, typeSettingsProperties, themeId, themeSettings,
1284 device, deviceThemeId);
1285
1286 return typeSettingsProperties;
1287 }
1288
1289 private static final boolean _CHECK_METHOD_ON_PROCESS_ACTION = false;
1290
1291 private static Log _log = LogFactoryUtil.getLog(EditLayoutsAction.class);
1292
1293 }