001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software GmbH & Co. KG, please see the
018 * company website: https://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: https://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.workplace.tools.workplace.broadcast;
029
030import org.opencms.file.CmsUser;
031import org.opencms.jsp.CmsJspActionElement;
032import org.opencms.main.CmsIllegalStateException;
033import org.opencms.main.CmsLog;
034import org.opencms.util.CmsStringUtil;
035import org.opencms.widgets.CmsDisplayWidget;
036import org.opencms.widgets.CmsInputWidget;
037import org.opencms.widgets.CmsTextareaWidget;
038import org.opencms.workplace.CmsDialog;
039import org.opencms.workplace.CmsWidgetDialog;
040import org.opencms.workplace.CmsWidgetDialogParameter;
041import org.opencms.workplace.CmsWorkplaceSettings;
042import org.opencms.workplace.list.CmsHtmlList;
043
044import java.util.ArrayList;
045import java.util.Collections;
046import java.util.Iterator;
047import java.util.List;
048
049import org.apache.commons.logging.Log;
050
051import jakarta.servlet.http.HttpServletRequest;
052import jakarta.servlet.http.HttpServletResponse;
053import jakarta.servlet.jsp.PageContext;
054
055/**
056 * Dialog to send a new email to the selected groups.<p>
057 *
058 * @since 6.5.6
059 */
060public class CmsSendEmailGroupsDialog extends CmsWidgetDialog {
061
062    /** localized messages Keys prefix. */
063    public static final String KEY_PREFIX = "email";
064
065    /** Defines which pages are valid for this dialog. */
066    public static final String[] PAGES = {"page1"};
067
068    /** Parameter name constant. */
069    public static final String PARAM_GROUPS = "groups";
070
071    /** The static log object for this class. */
072    private static final Log LOG = CmsLog.getLog(CmsSendEmailGroupsDialog.class);
073
074    /** Message info object. */
075    protected CmsMessageInfo m_msgInfo;
076
077    /** a warning about excluded users with no email. */
078    private String m_excludedUsers;
079
080    /** The selected groups. */
081    private String m_paramGroups;
082
083    /**
084     * Public constructor with JSP action element.<p>
085     *
086     * @param jsp an initialized JSP action element
087     */
088    public CmsSendEmailGroupsDialog(CmsJspActionElement jsp) {
089
090        super(jsp);
091    }
092
093    /**
094     * Public constructor with JSP variables.<p>
095     *
096     * @param context the JSP page context
097     * @param req the JSP request
098     * @param res the JSP response
099     */
100    public CmsSendEmailGroupsDialog(PageContext context, HttpServletRequest req, HttpServletResponse res) {
101
102        this(new CmsJspActionElement(context, req, res));
103    }
104
105    /**
106     * Commits the edited project to the db.<p>
107     */
108    @Override
109    public void actionCommit() {
110
111        List<Throwable> errors = new ArrayList<Throwable>();
112
113        if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_msgInfo.getTo())) {
114            setCommitErrors(
115                Collections.singletonList(
116                    (Throwable)new CmsIllegalStateException(
117                        Messages.get().container(Messages.ERR_NO_SELECTED_USER_WITH_EMAIL_0))));
118            return;
119        }
120        try {
121            m_msgInfo.setTo(getEmailAddresses());
122            m_msgInfo.sendEmail(getCms());
123        } catch (Throwable t) {
124            errors.add(t);
125        } finally {
126            m_msgInfo.setTo(getToNames());
127        }
128        // set the list of errors to display when saving failed
129        setCommitErrors(errors);
130    }
131
132    /**
133     * Returns a warning if users have been excluded.<p>
134     *
135     * @return a warning
136     */
137    public String getExcludedUsers() {
138
139        if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_excludedUsers)) {
140            getToNames();
141        }
142        if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_excludedUsers)) {
143            return "";
144        }
145        return m_excludedUsers;
146    }
147
148    /**
149     * Returns the selected groups.<p>
150     *
151     * @return the selected groups
152     */
153    public List<String> getGroups() {
154
155        return CmsStringUtil.splitAsList(getParamGroups(), CmsHtmlList.ITEM_SEPARATOR);
156    }
157
158    /**
159     * Returns the list of selected groups.<p>
160     *
161     * @return the list of selected groups
162     */
163    public String getParamGroups() {
164
165        return m_paramGroups;
166    }
167
168    /**
169     * Sets the warning message if users have been excluded.<p>
170     *
171     * @param excludedUsers the warning message
172     */
173    public void setExcludedUsers(String excludedUsers) {
174
175        m_excludedUsers = excludedUsers;
176    }
177
178    /**
179     * Sets the list of selected groups.<p>
180     *
181     * @param paramGroups the list of selected groups to set
182     */
183    public void setParamGroups(String paramGroups) {
184
185        m_paramGroups = paramGroups;
186    }
187
188    /**
189     * @see org.opencms.workplace.CmsWidgetDialog#createDialogHtml(java.lang.String)
190     */
191    @Override
192    protected String createDialogHtml(String dialog) {
193
194        StringBuffer result = new StringBuffer(1024);
195
196        result.append(createWidgetTableStart());
197        // show error header once if there were validation errors
198        result.append(createWidgetErrorHeader());
199
200        if (dialog.equals(PAGES[0])) {
201            int n = 4;
202            if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(getExcludedUsers())) {
203                n++;
204            }
205            // create the widgets for the second dialog page
206            result.append(dialogBlockStart(key(Messages.GUI_MESSAGE_EDITOR_LABEL_HEADER_BLOCK_0)));
207            result.append(createWidgetTableStart());
208            result.append(createDialogRowsHtml(0, n - 1));
209            result.append(createWidgetTableEnd());
210            result.append(dialogBlockEnd());
211            result.append(dialogBlockStart(key(Messages.GUI_MESSAGE_EDITOR_LABEL_CONTENT_BLOCK_0)));
212            result.append(createWidgetTableStart());
213            result.append(createDialogRowsHtml(n, n));
214            result.append(createWidgetTableEnd());
215            result.append(dialogBlockEnd());
216        }
217
218        result.append(createWidgetTableEnd());
219        return result.toString();
220    }
221
222    /**
223     * Creates the list of widgets for this dialog.<p>
224     */
225    @Override
226    protected void defineWidgets() {
227
228        // initialize the project object to use for the dialog
229        initMessageObject();
230
231        setKeyPrefix(KEY_PREFIX);
232
233        addWidget(new CmsWidgetDialogParameter(m_msgInfo, "from", PAGES[0], new CmsDisplayWidget()));
234        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(getExcludedUsers())) {
235            addWidget(new CmsWidgetDialogParameter(this, "excludedUsers", PAGES[0], new CmsDisplayWidget()));
236        }
237        addWidget(new CmsWidgetDialogParameter(m_msgInfo, "to", PAGES[0], new CmsDisplayWidget()));
238        addWidget(new CmsWidgetDialogParameter(m_msgInfo, "cc", PAGES[0], "", new CmsInputWidget(), 0, 1));
239        addWidget(new CmsWidgetDialogParameter(m_msgInfo, "subject", PAGES[0], new CmsInputWidget()));
240        addWidget(new CmsWidgetDialogParameter(m_msgInfo, "msg", PAGES[0], new CmsTextareaWidget(12)));
241    }
242
243    /**
244     * @see org.opencms.workplace.CmsWidgetDialog#getPageArray()
245     */
246    @Override
247    protected String[] getPageArray() {
248
249        return PAGES;
250    }
251
252    /**
253     * Returns a semicolon separated list of user names.<p>
254     *
255     * @return a semicolon separated list of user names
256     */
257    protected String getToNames() {
258
259        List<String> excluded = new ArrayList<String>();
260        List<String> users = new ArrayList<String>();
261        Iterator<String> itGroups = getGroups().iterator();
262        while (itGroups.hasNext()) {
263            String groupName = itGroups.next();
264            try {
265                Iterator<CmsUser> itUsers = getCms().getUsersOfGroup(groupName, true).iterator();
266                while (itUsers.hasNext()) {
267                    CmsUser user = itUsers.next();
268                    String userName = user.getFullName();
269                    if (!users.contains(userName)) {
270                        String emailAddress = user.getEmail();
271                        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(emailAddress)) {
272                            users.add(userName);
273                        } else {
274                            excluded.add(userName);
275                        }
276                    }
277                }
278            } catch (Exception e) {
279                LOG.error(e.getLocalizedMessage(), e);
280            }
281        }
282        if (!excluded.isEmpty()) {
283            StringBuffer text = new StringBuffer(500);
284            text.append(Messages.get().container(Messages.GUI_EXCLUDED_USERS_WARNING_0).key(getLocale()));
285            text.append("<br>");
286            Iterator<String> it = excluded.iterator();
287            while (it.hasNext()) {
288                text.append("- ");
289                text.append(it.next());
290                text.append("<br>");
291            }
292            setExcludedUsers(text.toString());
293        }
294        if (users.isEmpty()) {
295            setCommitErrors(
296                Collections.singletonList(
297                    (Throwable)new CmsIllegalStateException(
298                        Messages.get().container(Messages.ERR_NO_SELECTED_USER_WITH_EMAIL_0))));
299            return "";
300        }
301        StringBuffer result = new StringBuffer(256);
302        Iterator<String> itUsers = users.iterator();
303        while (itUsers.hasNext()) {
304            result.append(itUsers.next().toString());
305            if (itUsers.hasNext()) {
306                result.append("; ");
307            }
308        }
309        return result.toString();
310    }
311
312    /**
313     * Initializes the message info object to work with depending on the dialog state and request parameters.<p>
314     */
315    protected void initMessageObject() {
316
317        try {
318            if (CmsStringUtil.isEmpty(getParamAction()) || CmsDialog.DIALOG_INITIAL.equals(getParamAction())) {
319                // create a new message info object
320                m_msgInfo = new CmsMessageInfo();
321            } else {
322                // this is not the initial call, get the message info object from session
323                m_msgInfo = (CmsMessageInfo)getDialogObject();
324            }
325        } catch (Exception e) {
326            // create a new message info object
327            m_msgInfo = new CmsMessageInfo();
328        }
329        m_msgInfo.setFrom(getCms().getRequestContext().getCurrentUser().getFullName());
330        m_msgInfo.setTo(getToNames());
331    }
332
333    /**
334     * @see org.opencms.workplace.CmsWorkplace#initMessages()
335     */
336    @Override
337    protected void initMessages() {
338
339        // add specific dialog resource bundle
340        addMessages(Messages.get().getBundleName());
341        addMessages(org.opencms.workplace.tools.workplace.Messages.get().getBundleName());
342        // add default resource bundles
343        super.initMessages();
344    }
345
346    /**
347     * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, jakarta.servlet.http.HttpServletRequest)
348     */
349    @Override
350    protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) {
351
352        // initialize parameters and dialog actions in super implementation
353        super.initWorkplaceRequestValues(settings, request);
354
355        // save the current state of the message (may be changed because of the widget values)
356        setDialogObject(m_msgInfo);
357    }
358
359    /**
360     * @see org.opencms.workplace.CmsWidgetDialog#validateParamaters()
361     */
362    @Override
363    protected void validateParamaters() throws Exception {
364
365        if ((getGroups() == null) || getGroups().isEmpty()) {
366            throw new Exception();
367        }
368    }
369
370    /**
371     * Returns a semicolon separated list of email addresses.<p>
372     *
373     * @return a semicolon separated list of email addresses
374     */
375    private String getEmailAddresses() {
376
377        List<String> emails = new ArrayList<String>();
378        Iterator<String> itGroups = getGroups().iterator();
379        while (itGroups.hasNext()) {
380            String groupName = itGroups.next();
381            try {
382                Iterator<CmsUser> itUsers = getCms().getUsersOfGroup(groupName, true).iterator();
383                while (itUsers.hasNext()) {
384                    CmsUser user = itUsers.next();
385                    String emailAddress = user.getEmail();
386                    if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(emailAddress) && !emails.contains(emailAddress)) {
387                        emails.add(emailAddress);
388                    }
389                }
390            } catch (Exception e) {
391                LOG.error(e.getLocalizedMessage(), e);
392            }
393        }
394        StringBuffer result = new StringBuffer(256);
395        Iterator<String> itEmails = emails.iterator();
396        while (itEmails.hasNext()) {
397            result.append(itEmails.next());
398            if (itEmails.hasNext()) {
399                result.append("; ");
400            }
401        }
402        return result.toString();
403    }
404}