View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.client.console.notifications;
20  
21  import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.Iterator;
25  import java.util.List;
26  import org.apache.commons.lang3.StringUtils;
27  import org.apache.syncope.client.console.SyncopeConsoleSession;
28  import org.apache.syncope.client.console.commons.DirectoryDataProvider;
29  import org.apache.syncope.client.console.commons.IdRepoConstants;
30  import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
31  import org.apache.syncope.client.console.commons.TemplateContent;
32  import org.apache.syncope.client.console.notifications.MailTemplateDirectoryPanel.MailTemplateProvider;
33  import org.apache.syncope.client.console.pages.BasePage;
34  import org.apache.syncope.client.console.panels.DirectoryPanel;
35  import org.apache.syncope.client.console.rest.NotificationRestClient;
36  import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
37  import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
38  import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
39  import org.apache.syncope.client.console.wicket.markup.html.form.XMLEditorPanel;
40  import org.apache.syncope.client.ui.commons.Constants;
41  import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
42  import org.apache.syncope.client.ui.commons.panels.WizardModalPanel;
43  import org.apache.syncope.client.ui.commons.wizards.AbstractModalPanelBuilder;
44  import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
45  import org.apache.syncope.common.lib.SyncopeClientException;
46  import org.apache.syncope.common.lib.to.MailTemplateTO;
47  import org.apache.syncope.common.lib.types.IdRepoEntitlement;
48  import org.apache.syncope.common.lib.types.MailTemplateFormat;
49  import org.apache.wicket.PageReference;
50  import org.apache.wicket.ajax.AjaxRequestTarget;
51  import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
52  import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
53  import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
54  import org.apache.wicket.model.IModel;
55  import org.apache.wicket.model.PropertyModel;
56  import org.apache.wicket.model.ResourceModel;
57  import org.apache.wicket.model.StringResourceModel;
58  
59  public class MailTemplateDirectoryPanel
60          extends DirectoryPanel<MailTemplateTO, MailTemplateTO, MailTemplateProvider, NotificationRestClient> {
61  
62      private static final long serialVersionUID = -3789392431954221446L;
63  
64      protected final BaseModal<String> utilityModal = new BaseModal<>(Constants.OUTER);
65  
66      public MailTemplateDirectoryPanel(
67              final String id,
68              final NotificationRestClient restClient,
69              final PageReference pageRef) {
70  
71          super(id, restClient, pageRef, true);
72          disableCheckBoxes();
73  
74          modal.size(Modal.Size.Small);
75          modal.addSubmitButton();
76          modal.setWindowClosedCallback(target -> {
77              updateResultTable(target);
78              modal.show(false);
79          });
80          setFooterVisibility(true);
81  
82          addOuterObject(utilityModal);
83          setWindowClosedReloadCallback(utilityModal);
84          utilityModal.size(Modal.Size.Large);
85          utilityModal.addSubmitButton();
86  
87          addNewItemPanelBuilder(new AbstractModalPanelBuilder<MailTemplateTO>(new MailTemplateTO(), pageRef) {
88  
89              private static final long serialVersionUID = 1995192603527154740L;
90  
91              @Override
92              public WizardModalPanel<MailTemplateTO> build(
93                      final String id, final int index, final AjaxWizard.Mode mode) {
94  
95                  return new TemplateModal(modal, restClient, new MailTemplateTO(), pageRef);
96              }
97          }, true);
98  
99          initResultTable();
100 
101         MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, IdRepoEntitlement.MAIL_TEMPLATE_CREATE);
102     }
103 
104     @Override
105     protected List<IColumn<MailTemplateTO, String>> getColumns() {
106         List<IColumn<MailTemplateTO, String>> columns = new ArrayList<>();
107         columns.add(new PropertyColumn<>(
108                 new StringResourceModel(Constants.KEY_FIELD_NAME, this),
109                 Constants.KEY_FIELD_NAME, Constants.KEY_FIELD_NAME));
110         return columns;
111     }
112 
113     @Override
114     public ActionsPanel<MailTemplateTO> getActions(final IModel<MailTemplateTO> model) {
115         final ActionsPanel<MailTemplateTO> panel = super.getActions(model);
116 
117         panel.add(new ActionLink<>() {
118 
119             private static final long serialVersionUID = -7978723352517770645L;
120 
121             @Override
122             public void onClick(final AjaxRequestTarget target, final MailTemplateTO ignore) {
123                 TemplateContent<MailTemplateFormat> content = new TemplateContent<>(model.getObject().getKey(),
124                         MailTemplateFormat.HTML);
125                 content.setContent(
126                         restClient.readTemplateFormat(model.getObject().getKey(), MailTemplateFormat.HTML));
127 
128                 utilityModal.header(new ResourceModel("mail.template.html", "HTML Content"));
129                 utilityModal.setContent(new TemplateContentEditorPanel(content, pageRef));
130                 utilityModal.show(true);
131                 target.add(utilityModal);
132             }
133         }, ActionLink.ActionType.HTML, IdRepoEntitlement.MAIL_TEMPLATE_UPDATE);
134 
135         panel.add(new ActionLink<>() {
136 
137             private static final long serialVersionUID = -7978723352517770645L;
138 
139             @Override
140             public void onClick(final AjaxRequestTarget target, final MailTemplateTO ignore) {
141                 TemplateContent<MailTemplateFormat> content = new TemplateContent<>(model.getObject().getKey(),
142                         MailTemplateFormat.TEXT);
143                 content.setContent(
144                         restClient.readTemplateFormat(model.getObject().getKey(), MailTemplateFormat.TEXT));
145 
146                 utilityModal.header(new ResourceModel("mail.template.text", "TEXT Content"));
147                 utilityModal.setContent(new TemplateContentEditorPanel(content, pageRef));
148                 utilityModal.show(true);
149                 target.add(utilityModal);
150             }
151         }, ActionLink.ActionType.TEXT, IdRepoEntitlement.MAIL_TEMPLATE_UPDATE);
152 
153         panel.add(new ActionLink<>() {
154 
155             private static final long serialVersionUID = -3722207913631435501L;
156 
157             @Override
158             public void onClick(final AjaxRequestTarget target, final MailTemplateTO ignore) {
159                 try {
160                     restClient.deleteTemplate(model.getObject().getKey());
161                     SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
162                     target.add(container);
163                 } catch (SyncopeClientException e) {
164                     LOG.error("While deleting object {}", model.getObject().getKey(), e);
165                     SyncopeConsoleSession.get().onException(e);
166                 }
167                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
168             }
169         }, ActionLink.ActionType.DELETE, IdRepoEntitlement.MAIL_TEMPLATE_DELETE, true);
170 
171         return panel;
172     }
173 
174     @Override
175     protected MailTemplateProvider dataProvider() {
176         return new MailTemplateProvider(rows);
177     }
178 
179     @Override
180     protected String paginatorRowsKey() {
181         return IdRepoConstants.PREF_MAIL_TEMPLATE_PAGINATOR_ROWS;
182     }
183 
184     @Override
185     protected Collection<ActionLink.ActionType> getBatches() {
186         return List.of();
187     }
188 
189     protected final class MailTemplateProvider extends DirectoryDataProvider<MailTemplateTO> {
190 
191         private static final long serialVersionUID = -276043813563988590L;
192 
193         private final SortableDataProviderComparator<MailTemplateTO> comparator;
194 
195         public MailTemplateProvider(final int paginatorRows) {
196             super(paginatorRows);
197             comparator = new SortableDataProviderComparator<>(this);
198         }
199 
200         @Override
201         public Iterator<MailTemplateTO> iterator(final long first, final long count) {
202             List<MailTemplateTO> templates = restClient.listTemplates();
203             templates.sort(comparator);
204             return templates.subList((int) first, (int) first + (int) count).iterator();
205         }
206 
207         @Override
208         public long size() {
209             return restClient.listTemplates().size();
210         }
211 
212         @Override
213         public IModel<MailTemplateTO> model(final MailTemplateTO mailTemplateTO) {
214             return new IModel<>() {
215 
216                 private static final long serialVersionUID = 774694801558497248L;
217 
218                 @Override
219                 public MailTemplateTO getObject() {
220                     return mailTemplateTO;
221                 }
222             };
223         }
224     }
225 
226     private class TemplateContentEditorPanel extends XMLEditorPanel {
227 
228         private static final long serialVersionUID = -3528875878627216097L;
229 
230         private final TemplateContent<MailTemplateFormat> content;
231 
232         TemplateContentEditorPanel(
233                 final TemplateContent<MailTemplateFormat> content,
234                 final PageReference pageRef) {
235 
236             super(utilityModal, new PropertyModel<>(content, "content"), false, pageRef);
237             this.content = content;
238         }
239 
240         @Override
241         public void onSubmit(final AjaxRequestTarget target) {
242             if (StringUtils.isBlank(content.getContent())) {
243                 SyncopeConsoleSession.get().error("No content to save");
244             } else {
245                 try {
246                     restClient.updateTemplateFormat(
247                             content.getKey(), content.getContent(), content.getFormat());
248                     SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
249                     modal.show(false);
250                     modal.close(target);
251                 } catch (Exception e) {
252                     LOG.error("While updating template for {}", content.getKey(), e);
253                     SyncopeConsoleSession.get().onException(e);
254                 }
255             }
256             ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target);
257         }
258     }
259 }