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, 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.ui.apps.sitemanager;
029
030import org.opencms.ade.configuration.CmsADEManager;
031import org.opencms.file.CmsObject;
032import org.opencms.file.CmsProject;
033import org.opencms.file.CmsProperty;
034import org.opencms.file.CmsPropertyDefinition;
035import org.opencms.file.CmsResource;
036import org.opencms.file.CmsResourceFilter;
037import org.opencms.file.types.CmsResourceTypeFolderSubSitemap;
038import org.opencms.file.types.CmsResourceTypeJsp;
039import org.opencms.file.types.I_CmsResourceType;
040import org.opencms.i18n.CmsLocaleManager;
041import org.opencms.main.CmsException;
042import org.opencms.main.CmsIllegalArgumentException;
043import org.opencms.main.CmsLog;
044import org.opencms.main.OpenCms;
045import org.opencms.relations.CmsRelation;
046import org.opencms.relations.CmsRelationFilter;
047import org.opencms.security.CmsOrganizationalUnit;
048import org.opencms.site.CmsAlternativeSiteRootMapping;
049import org.opencms.site.CmsSSLMode;
050import org.opencms.site.CmsSite;
051import org.opencms.site.CmsSiteMatcher;
052import org.opencms.site.CmsSiteMatcher.RedirectMode;
053import org.opencms.ui.A_CmsUI;
054import org.opencms.ui.CmsVaadinUtils;
055import org.opencms.ui.apps.Messages;
056import org.opencms.ui.components.CmsBasicDialog;
057import org.opencms.ui.components.CmsRemovableFormRow;
058import org.opencms.ui.components.CmsResourceInfo;
059import org.opencms.ui.components.editablegroup.CmsEditableGroup;
060import org.opencms.ui.components.editablegroup.I_CmsEditableGroupRow;
061import org.opencms.ui.components.fileselect.CmsPathSelectField;
062import org.opencms.ui.report.CmsReportWidget;
063import org.opencms.util.CmsFileUtil;
064import org.opencms.util.CmsMacroResolver;
065import org.opencms.util.CmsPath;
066import org.opencms.util.CmsStringUtil;
067import org.opencms.util.CmsUUID;
068
069import java.io.ByteArrayInputStream;
070import java.io.ByteArrayOutputStream;
071import java.io.IOException;
072import java.io.InputStream;
073import java.io.InputStreamReader;
074import java.io.OutputStream;
075import java.net.URI;
076import java.net.URISyntaxException;
077import java.nio.charset.StandardCharsets;
078import java.util.ArrayList;
079import java.util.Collections;
080import java.util.HashMap;
081import java.util.HashSet;
082import java.util.List;
083import java.util.Map;
084import java.util.Map.Entry;
085import java.util.Optional;
086import java.util.Properties;
087import java.util.Set;
088import java.util.SortedMap;
089import java.util.TreeMap;
090
091import org.apache.commons.logging.Log;
092
093import com.google.common.base.Supplier;
094import com.vaadin.event.FieldEvents.BlurEvent;
095import com.vaadin.event.FieldEvents.BlurListener;
096import com.vaadin.server.StreamResource;
097import com.vaadin.server.UserError;
098import com.vaadin.ui.Button;
099import com.vaadin.ui.Button.ClickEvent;
100import com.vaadin.ui.Button.ClickListener;
101import com.vaadin.ui.Component;
102import com.vaadin.ui.FormLayout;
103import com.vaadin.ui.Image;
104import com.vaadin.ui.Panel;
105import com.vaadin.ui.TabSheet;
106import com.vaadin.ui.UI;
107import com.vaadin.v7.data.Item;
108import com.vaadin.v7.data.Property.ValueChangeEvent;
109import com.vaadin.v7.data.Property.ValueChangeListener;
110import com.vaadin.v7.data.Validator;
111import com.vaadin.v7.data.Validator.InvalidValueException;
112import com.vaadin.v7.data.util.BeanItemContainer;
113import com.vaadin.v7.data.util.IndexedContainer;
114import com.vaadin.v7.shared.ui.combobox.FilteringMode;
115import com.vaadin.v7.ui.AbstractField;
116import com.vaadin.v7.ui.AbstractSelect.ItemCaptionMode;
117import com.vaadin.v7.ui.CheckBox;
118import com.vaadin.v7.ui.ComboBox;
119import com.vaadin.v7.ui.TextField;
120import com.vaadin.v7.ui.Upload;
121import com.vaadin.v7.ui.Upload.Receiver;
122import com.vaadin.v7.ui.Upload.SucceededEvent;
123import com.vaadin.v7.ui.Upload.SucceededListener;
124import com.vaadin.v7.ui.VerticalLayout;
125
126/**
127 * Class for the Form to edit or add a site.<p>
128 */
129public class CmsEditSiteForm extends CmsBasicDialog {
130
131    /**
132     *  Bean for the ComboBox to edit the position.<p>
133     */
134    public class PositionComboBoxElementBean {
135
136        /**Position of site in List. */
137        private float m_position;
138
139        /**Title of site to show. */
140        private String m_title;
141
142        /**
143         * Constructor. <p>
144         *
145         * @param title of site
146         * @param position of site
147         */
148        public PositionComboBoxElementBean(String title, float position) {
149
150            m_position = position;
151            m_title = title;
152        }
153
154        /**
155         * Getter for position.<p>
156         *
157         * @return float position
158         */
159        public float getPosition() {
160
161            return m_position;
162        }
163
164        /**
165         * Getter for title.<p>
166         *
167         * @return String title
168         */
169        public String getTitle() {
170
171            return m_title;
172        }
173    }
174
175    /**
176     *Validator for server field.<p>
177     */
178    class AliasValidator implements Validator {
179
180        /**vaadin serial id.*/
181        private static final long serialVersionUID = 9014118214418269697L;
182
183        /**
184         * @see com.vaadin.v7.data.Validator#validate(java.lang.Object)
185         */
186        public void validate(Object value) throws InvalidValueException {
187
188            String enteredServer = (String)value;
189            if (enteredServer == null) {
190                return;
191            }
192            if (enteredServer.isEmpty()) {
193                return;
194            }
195            checkUriAuthority(enteredServer);
196            if (m_alreadyUsedURL.contains(new CmsSiteMatcher(enteredServer))) {
197                if (!OpenCms.getSiteManager().getSites().get(new CmsSiteMatcher(enteredServer)).equals(m_site)) {
198                    throw new InvalidValueException(
199                        CmsVaadinUtils.getMessageText(Messages.GUI_SITE_SERVER_ALREADYUSED_1, enteredServer));
200                }
201            }
202            if ((new CmsSiteMatcher(enteredServer)).equals(new CmsSiteMatcher(getFieldServer()))) {
203                throw new InvalidValueException(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_SERVER_EQUAL_ALIAS_0));
204            }
205            if (isDoubleAlias(enteredServer)) {
206                throw new InvalidValueException(
207                    CmsVaadinUtils.getMessageText(Messages.GUI_SITE_SERVER_ALREADYUSED_1, enteredServer));
208            }
209        }
210    }
211
212    /**
213     * Receiver class for upload of favicon.<p>
214     */
215    class FavIconReceiver implements Receiver, SucceededListener {
216
217        /**vaadin serial id. */
218        private static final long serialVersionUID = 688021741970679734L;
219
220        /**
221         * @see com.vaadin.ui.Upload.Receiver#receiveUpload(java.lang.String, java.lang.String)
222         */
223        public OutputStream receiveUpload(String filename, String mimeType) {
224
225            m_os.reset();
226            if (!mimeType.startsWith("image")) {
227                return new ByteArrayOutputStream(0);
228            }
229            return m_os;
230        }
231
232        /**
233         * @see com.vaadin.ui.Upload.SucceededListener#uploadSucceeded(com.vaadin.ui.Upload.SucceededEvent)
234         */
235        public void uploadSucceeded(SucceededEvent event) {
236
237            if (m_os.size() <= 1) {
238                m_imageCounter = 0;
239                m_fieldUploadFavIcon.setComponentError(
240                    new UserError(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_FAVICON_MIME_0)));
241                setFaviconIfExist();
242                return;
243            }
244            if (m_os.size() > 4096) {
245                m_fieldUploadFavIcon.setComponentError(
246                    new UserError(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_FAVICON_SIZE_0)));
247                m_imageCounter = 0;
248                setFaviconIfExist();
249                return;
250            }
251            m_imageCounter++;
252            setCurrentFavIcon(m_os.toByteArray());
253        }
254    }
255
256    /**
257     *Validator for Folder Name field.<p>
258     */
259    class FolderPathValidator implements Validator {
260
261        /**vaadin serial id.*/
262        private static final long serialVersionUID = 2269520781911597613L;
263
264        /**
265         * @see com.vaadin.data.Validator#validate(java.lang.Object)
266         */
267        public void validate(Object value) throws InvalidValueException {
268
269            String enteredName = (String)value;
270            if (FORBIDDEN_FOLDER_NAMES.contains(enteredName)) {
271                throw new InvalidValueException(
272                    CmsVaadinUtils.getMessageText(Messages.GUI_SITE_FOLDERNAME_FORBIDDEN_1, enteredName));
273            }
274
275            //            if (m_alreadyUsedFolderPath.contains(getParentFolder() + enteredName)) {
276            if (OpenCms.getSiteManager().getSiteForRootPath(getParentFolder() + enteredName) != null) {
277                throw new InvalidValueException(
278                    CmsVaadinUtils.getMessageText(Messages.GUI_SITE_FOLDERNAME_ALREADYUSED_1, enteredName));
279            }
280            try {
281                CmsResource.checkResourceName(enteredName);
282            } catch (CmsIllegalArgumentException e) {
283                throw new InvalidValueException(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_FOLDERNAME_EMPTY_0));
284            }
285        }
286    }
287
288    /**
289     * Validator for the parent field.<p>
290     */
291    class ParentFolderValidator implements Validator {
292
293        /**vaadin serial id.*/
294        private static final long serialVersionUID = 5217828150841769662L;
295
296        /**
297         * @see com.vaadin.data.Validator#validate(java.lang.Object)
298         */
299        public void validate(Object value) throws InvalidValueException {
300
301            try {
302                m_clonedCms.getRequestContext().setSiteRoot("");
303                m_clonedCms.readResource(getParentFolder());
304            } catch (CmsException e) {
305                throw new InvalidValueException(
306                    CmsVaadinUtils.getMessageText(Messages.GUI_SITE_PARENTFOLDER_NOT_EXIST_0));
307            }
308            if (OpenCms.getSiteManager().getSiteForRootPath(
309                CmsFileUtil.removeTrailingSeparator(getParentFolder())) != null) {
310                throw new InvalidValueException(
311                    CmsVaadinUtils.getMessageText(
312                        Messages.GUI_SITE_FOLDERNAME_ALREADYUSED_1,
313                        CmsFileUtil.removeTrailingSeparator(getParentFolder())));
314            }
315            if (!(getParentFolder()).startsWith(CmsSiteManager.PATH_SITES)) {
316                throw new InvalidValueException(
317                    CmsVaadinUtils.getMessageText(Messages.GUI_SITE_FOLDERNAME_WRONGPARENT_0));
318            }
319
320            if (!getSiteTemplatePath().isEmpty()) {
321                if (ensureFoldername(getParentFolder()).equals(ensureFoldername(getSiteTemplatePath()))) {
322                    throw new InvalidValueException(
323                        CmsVaadinUtils.getMessageText(Messages.GUI_SITE_FOLDERNAME_EQUAL_SITETEMPLATE_0));
324                }
325            }
326
327        }
328
329    }
330
331    /**
332     * Validator for parent OU.<p>
333     */
334    class SelectOUValidator implements Validator {
335
336        /**vaadin serial id.*/
337        private static final long serialVersionUID = -911831798529729185L;
338
339        /**
340         * @see com.vaadin.data.Validator#validate(java.lang.Object)
341         */
342        public void validate(Object value) throws InvalidValueException {
343
344            String OU = (String)value;
345            if (OU.equals("/")) {
346                return; //ok
347            }
348
349            if (OU.split("/").length < 2) {
350                return; //ou is under root
351            }
352
353            OU = OU.split("/")[0] + "/";
354
355            if (getParentFolder().isEmpty() | getFieldFolder().isEmpty()) {
356                return; //not ok, but gets catched in an other validator
357            }
358
359            String rootPath = "/" + ensureFoldername(getParentFolder()) + ensureFoldername(getFieldFolder());
360
361            boolean ok = false;
362
363            try {
364                List<CmsResource> res = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(m_clonedCms, OU);
365                for (CmsResource resource : res) {
366                    if (rootPath.startsWith(resource.getRootPath())) {
367                        ok = true;
368                    }
369                }
370
371            } catch (CmsException e) {
372                throw new InvalidValueException(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_OU_INVALID_0));
373            }
374            if (!ok) {
375                throw new InvalidValueException(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_OU_INVALID_0));
376            }
377        }
378
379    }
380
381    /**
382     * Validator for parent OU.<p>
383     */
384    class SelectParentOUValidator implements Validator {
385
386        /**vaadin serial id.*/
387        private static final long serialVersionUID = -911831798529729185L;
388
389        /**
390         * @see com.vaadin.v7.data.Validator#validate(java.lang.Object)
391         */
392        public void validate(Object value) throws InvalidValueException {
393
394            String parentOU = (String)value;
395            if (parentOU.equals("/")) {
396                return; //ok
397            }
398
399            if (getParentFolder().isEmpty() | getFieldFolder().isEmpty()) {
400                return; //not ok, but gets catched in an other validator
401            }
402
403            String rootPath = "/" + ensureFoldername(getParentFolder()) + ensureFoldername(getFieldFolder());
404
405            boolean ok = false;
406
407            try {
408                List<CmsResource> res = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(
409                    m_clonedCms,
410                    parentOU);
411                for (CmsResource resource : res) {
412                    if (rootPath.startsWith(resource.getRootPath())) {
413                        ok = true;
414                    }
415                }
416
417            } catch (CmsException e) {
418                throw new InvalidValueException(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_PARENTOU_INVALID_0));
419            }
420            if (!ok) {
421                throw new InvalidValueException(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_PARENTOU_INVALID_0));
422            }
423        }
424
425    }
426
427    /**
428     *Validator for server field.<p>
429     */
430    class ServerValidator implements Validator {
431
432        /**vaadin serial id.*/
433        private static final long serialVersionUID = 9014118214418269697L;
434
435        /**
436         * @see com.vaadin.data.Validator#validate(java.lang.Object)
437         */
438        public void validate(Object value) throws InvalidValueException {
439
440            String enteredServer = (String)value;
441            if (enteredServer.isEmpty()) {
442                throw new InvalidValueException(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_SERVER_EMPTY_0));
443            }
444            checkUriAuthority(enteredServer);
445            if (m_alreadyUsedURL.contains(new CmsSiteMatcher(enteredServer))) {
446                throw new InvalidValueException(
447                    CmsVaadinUtils.getMessageText(Messages.GUI_SITE_SERVER_ALREADYUSED_1, enteredServer));
448            }
449        }
450    }
451
452    /**
453     * Validator for site root (in case of editing a site, fails for broken sites.<p>
454     */
455    class SiteRootValidator implements Validator {
456
457        /**vaadin serial id.*/
458        private static final long serialVersionUID = 7499390905843603642L;
459
460        /**
461         * @see com.vaadin.v7.data.Validator#validate(java.lang.Object)
462         */
463        @Deprecated
464        public void validate(Object value) throws InvalidValueException {
465
466            CmsSite parentSite = m_manager.getElement(CmsFileUtil.removeTrailingSeparator((String)value));
467            if (parentSite != null) {
468                if (!parentSite.equals(m_site)) {
469                    throw new InvalidValueException(
470                        CmsVaadinUtils.getMessageText(
471                            Messages.GUI_SITE_FOLDERNAME_ALREADYUSED_1,
472                            CmsFileUtil.removeTrailingSeparator((String)value)));
473                }
474            }
475
476            CmsProject currentProject = m_clonedCms.getRequestContext().getCurrentProject();
477            try {
478
479                m_clonedCms.getRequestContext().setCurrentProject(
480                    m_clonedCms.readProject(CmsProject.ONLINE_PROJECT_ID));
481                m_clonedCms.readResource((String)value);
482
483            } catch (CmsException e) {
484                m_clonedCms.getRequestContext().setCurrentProject(currentProject);
485                if (!m_clonedCms.existsResource((String)value)) {
486                    throw new InvalidValueException(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_SITEROOT_WRONG_0));
487                }
488            }
489
490            m_clonedCms.getRequestContext().setCurrentProject(currentProject);
491        }
492
493    }
494
495    /**
496     * Validator for Site Template selection field.<p>
497     */
498    class SiteTemplateValidator implements Validator {
499
500        /**vaadin serial id.*/
501        private static final long serialVersionUID = -8730991818750657154L;
502
503        /**
504         * @see com.vaadin.data.Validator#validate(java.lang.Object)
505         */
506        public void validate(Object value) throws InvalidValueException {
507
508            String pathToCheck = (String)value;
509            if (pathToCheck == null) {
510                return;
511            }
512            if (pathToCheck.isEmpty()) { //Empty -> no template chosen, ok
513                return;
514            }
515            if (!getParentFolder().isEmpty() & !getFieldFolder().isEmpty()) {
516                String rootPath = "/" + ensureFoldername(getParentFolder()) + ensureFoldername(getFieldFolder());
517
518                if (m_clonedCms.existsResource(rootPath)) {
519                    throw new InvalidValueException(
520                        CmsVaadinUtils.getMessageText(Messages.GUI_SITE_SITETEMPLATE_OVERWRITE_0));
521                }
522            }
523            try {
524                m_clonedCms.readResource(pathToCheck + CmsADEManager.CONTENT_FOLDER_NAME);
525            } catch (CmsException e) {
526                throw new InvalidValueException(
527                    CmsVaadinUtils.getMessageText(Messages.GUI_SITE_SITETEMPLATE_INVALID_0));
528            }
529        }
530
531    }
532
533    /**
534     * Validator for the title field.<p>
535     */
536    class TitleValidator implements Validator {
537
538        /**vaadin serial id.*/
539        private static final long serialVersionUID = 7878441125879949490L;
540
541        /**
542         * @see com.vaadin.data.Validator#validate(java.lang.Object)
543         */
544        public void validate(Object value) throws InvalidValueException {
545
546            if (CmsStringUtil.isEmptyOrWhitespaceOnly((String)value)) {
547                throw new InvalidValueException(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_TITLE_EMPTY_0));
548            }
549
550        }
551
552    }
553
554    /** The module name constant. */
555    public static final String MODULE_NAME = "org.opencms.ui.apps.sitemanager";
556
557    /** Module parameter constant for the web server script. */
558    public static final String PARAM_OU_DESCRIPTION = "oudescription";
559
560    /**List of all forbidden folder names as new site-roots.*/
561    static final List<String> FORBIDDEN_FOLDER_NAMES = new ArrayList<String>() {
562
563        private static final long serialVersionUID = 8074588073232610426L;
564
565        {
566            add("system");
567            add(OpenCms.getSiteManager().getSharedFolder().replaceAll("/", ""));
568        }
569    };
570
571    /** The logger for this class. */
572    static Log LOG = CmsLog.getLog(CmsEditSiteForm.class.getName());
573
574    /**vaadin serial id.*/
575    private static final long serialVersionUID = -1011525709082939562L;
576
577    protected CmsPathSelectField m_altSiteRoot;
578
579    protected FormLayout m_altSiteRootPathContainer;
580
581    protected TextField m_altSiteRootSuffix;
582
583    /**Flag to block change events. */
584    protected boolean m_blockChange;
585
586    protected Button m_clearAltSiteRoot;
587
588    /**List of all folder names already used for sites. */
589    List<String> m_alreadyUsedFolderPath = new ArrayList<String>();
590
591    /**List of all urls already used for sites.*/
592    Set<CmsSiteMatcher> m_alreadyUsedURL = new HashSet<CmsSiteMatcher>();
593
594    /**cloned cms obejct.*/
595    CmsObject m_clonedCms;
596
597    /**vaadin component.*/
598    ComboBox m_fieldSelectOU;
599
600    /**vaadin coponent.*/
601    ComboBox m_fieldSelectParentOU;
602
603    /**vaadin component. */
604    Upload m_fieldUploadFavIcon;
605
606    /**Needed to check if favicon was changed. */
607    int m_imageCounter;
608
609    /** The site manager instance.*/
610    CmsSiteManager m_manager;
611
612    /**OutputStream to store the uploaded favicon temporarily. */
613    ByteArrayOutputStream m_os = new ByteArrayOutputStream(5500);
614
615    /**current site which is supposed to be edited, null if site should be added.*/
616    CmsSite m_site;
617
618    /**vaadin component.*/
619    TabSheet m_tab;
620
621    /**button to add parameter.*/
622    private Button m_addParameter;
623
624    /**vaadin component.*/
625    private VerticalLayout m_aliases;
626
627    /**Edit group for workplace servers.*/
628    private CmsEditableGroup m_aliasGroup;
629
630    private CmsEditableGroup m_alternativeSiteRootPrefixGroup;
631
632    /**automatic setted folder name.*/
633    private String m_autoSetFolderName;
634
635    /**Map to connect vaadin text fields with bundle keys.*/
636    private Map<TextField, String> m_bundleComponentKeyMap;
637
638    /**vaadin component.*/
639    private FormLayout m_bundleValues;
640
641    /**vaadin component.*/
642    private Button m_cancel;
643
644    /**vaadin component.*/
645    private CheckBox m_fieldCreateOU;
646
647    /**vaadin component.*/
648    private CmsPathSelectField m_fieldErrorPage;
649
650    /**vaadin component.*/
651    private CheckBox m_fieldExclusiveError;
652
653    /**vaadin component.*/
654    private CheckBox m_fieldExclusiveURL;
655
656    /**vaadin component. */
657    private Image m_fieldFavIcon;
658
659    /**vaadin component. */
660    private CheckBox m_fieldKeepTemplate;
661
662    /**vaadin component.*/
663    private CmsPathSelectField m_fieldLoadSiteTemplate;
664
665    /**vaadin component.*/
666    private ComboBox m_fieldPosition;
667
668    /**vaadin component.*/
669    private TextField m_fieldSecureServer;
670
671    /**vaadin component.*/
672    private CheckBox m_fieldWebServer;
673
674    /**vaadin component. */
675    private Panel m_infoSiteRoot;
676
677    /**boolean indicates if folder name was changed by user.*/
678    private boolean m_isFolderNameTouched;
679
680    /**vaadin component.*/
681    private Button m_ok;
682
683    /**Click listener for ok button. */
684    private Button.ClickListener m_okClickListener;
685
686    /**vaadin component.*/
687    private FormLayout m_parameter;
688
689    /**Panel holding the report widget.*/
690    private Panel m_report;
691
692    /**Vaadin component. */
693    private ComboBox m_simpleFieldEncryption;
694
695    /**vaadin component.*/
696    private TextField m_simpleFieldFolderName;
697
698    /**vaadin component.*/
699    private CmsPathSelectField m_simpleFieldParentFolderName;
700
701    /**vaadin component.*/
702    private TextField m_simpleFieldServer;
703
704    /**vaadin component.*/
705    private CmsPathSelectField m_simpleFieldSiteRoot;
706
707    /**vaadin component.*/
708    private ComboBox m_simpleFieldTemplate;
709
710    /**vaadin component.*/
711    private TextField m_simpleFieldTitle;
712
713    private ComboBox m_subsiteSelectionEnabled;
714
715    /**List of templates. */
716    private List<CmsResource> m_templates;
717
718    /**Layout for the report widget. */
719    private FormLayout m_threadReport;
720
721    /**
722     * Constructor.<p>
723     * Use this to create a new site.<p>
724     *
725     * @param manager the site manager instance
726     * @param cms the CmsObject
727     */
728    public CmsEditSiteForm(CmsObject cms, CmsSiteManager manager) {
729
730        m_isFolderNameTouched = false;
731        m_blockChange = true;
732        m_autoSetFolderName = "";
733        m_clonedCms = cms;
734
735        List<CmsSite> allSites = manager.getAllElements();
736        allSites.addAll(manager.getCorruptedSites());
737
738        for (CmsSite site : allSites) {
739            if (site.getSiteMatcher() != null) {
740                m_alreadyUsedFolderPath.add(site.getSiteRoot());
741            }
742        }
743
744        m_alreadyUsedURL.addAll(OpenCms.getSiteManager().getSites().keySet());
745
746        CmsVaadinUtils.readAndLocalizeDesign(this, CmsVaadinUtils.getWpMessagesForCurrentLocale(), null);
747        m_tab.setHeight("400px");
748        m_infoSiteRoot.setVisible(false);
749        m_simpleFieldSiteRoot.setVisible(false);
750
751        if (!OpenCms.getSiteManager().isConfigurableWebServer()) {
752            m_fieldWebServer.setVisible(false);
753            m_fieldWebServer.setValue(Boolean.valueOf(true));
754
755        }
756
757        m_fieldKeepTemplate.setVisible(false);
758        m_fieldKeepTemplate.setValue(Boolean.FALSE);
759
760        m_simpleFieldParentFolderName.setValue(CmsSiteManager.PATH_SITES);
761        m_simpleFieldParentFolderName.setUseRootPaths(true);
762        m_simpleFieldParentFolderName.setCmsObject(m_clonedCms);
763        m_simpleFieldParentFolderName.requireFolder();
764        m_simpleFieldParentFolderName.setResourceFilter(CmsResourceFilter.DEFAULT_FOLDERS);
765        m_simpleFieldParentFolderName.addValueChangeListener(new ValueChangeListener() {
766
767            private static final long serialVersionUID = 4043563040462776139L;
768
769            public void valueChange(ValueChangeEvent event) {
770
771                try {
772                    String folderPath = m_simpleFieldParentFolderName.getValue();
773                    if (CmsResourceTypeFolderSubSitemap.TYPE_SUBSITEMAP.equals(
774                        OpenCms.getResourceManager().getResourceType(
775                            m_clonedCms.readResource(folderPath)).getTypeName())) {
776                        String newFolderName = folderPath.split("/")[folderPath.split("/").length - 1];
777                        m_simpleFieldFolderName.setValue(newFolderName);
778                        m_isFolderNameTouched = true;
779                        if (m_simpleFieldTitle.isEmpty()) {
780                            CmsProperty title = m_clonedCms.readPropertyObject(
781                                m_clonedCms.readResource(folderPath),
782                                "Title",
783                                false);
784                            if (!CmsProperty.getNullProperty().equals(title)) {
785                                m_simpleFieldTitle.setValue(title.getValue());
786                            }
787                        }
788                        setTemplateFieldForSiteroot(folderPath);
789                        m_simpleFieldParentFolderName.setValue(
790                            m_simpleFieldParentFolderName.getValue().substring(
791                                0,
792                                folderPath.length() - 1 - newFolderName.length()));
793                    }
794                } catch (CmsException e) {
795                    // Resource was not found. Not ok, but will be validated later
796                }
797                setUpOUComboBox(m_fieldSelectParentOU);
798                setUpOUComboBox(m_fieldSelectOU);
799            }
800
801        });
802
803        m_manager = manager;
804
805        m_addParameter.addClickListener(new ClickListener() {
806
807            private static final long serialVersionUID = 6814134727761004218L;
808
809            public void buttonClick(ClickEvent event) {
810
811                addParameter(null);
812            }
813        });
814
815        m_okClickListener = new ClickListener() {
816
817            private static final long serialVersionUID = 6814134727761004218L;
818
819            public void buttonClick(ClickEvent event) {
820
821                validateAndSubmit();
822            }
823        };
824
825        m_ok.addClickListener(m_okClickListener);
826
827        m_cancel.addClickListener(new ClickListener() {
828
829            private static final long serialVersionUID = -276802394623141951L;
830
831            public void buttonClick(ClickEvent event) {
832
833                closeDialog(false);
834            }
835        });
836
837        m_fieldCreateOU.addValueChangeListener(new ValueChangeListener() {
838
839            private static final long serialVersionUID = -2837270577662919541L;
840
841            public void valueChange(ValueChangeEvent event) {
842
843                toggleSelectOU();
844
845            }
846        });
847
848        setUpComboBoxPosition();
849        setUpComboBoxTemplate();
850        setUpComboBoxSSL();
851        setupSubsiteSelectionMode();
852        setUpOUComboBox(m_fieldSelectOU);
853        setUpOUComboBox(m_fieldSelectParentOU);
854
855        m_fieldSecureServer.addValueChangeListener(new ValueChangeListener() {
856
857            private static final long serialVersionUID = -2837270577662919541L;
858
859            public void valueChange(ValueChangeEvent event) {
860
861                toggleSecureServer();
862            }
863        });
864        m_fieldExclusiveURL.setEnabled(false);
865        m_fieldExclusiveError.setEnabled(false);
866        Receiver uploadReceiver = new FavIconReceiver();
867
868        m_fieldWebServer.setValue(Boolean.valueOf(true));
869
870        m_fieldUploadFavIcon.setReceiver(uploadReceiver);
871        m_fieldUploadFavIcon.setButtonCaption(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_SELECT_FILE_0));
872        m_fieldUploadFavIcon.setImmediate(true);
873        m_fieldUploadFavIcon.addSucceededListener((SucceededListener)uploadReceiver);
874        m_fieldUploadFavIcon.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_FAVICON_NEW_0));
875        m_fieldFavIcon.setVisible(false);
876
877        m_simpleFieldTitle.addBlurListener(new BlurListener() {
878
879            private static final long serialVersionUID = -4147179568264310325L;
880
881            public void blur(BlurEvent event) {
882
883                if (!getFieldTitle().isEmpty() & !isFolderNameTouched()) {
884                    String niceName = OpenCms.getResourceManager().getNameGenerator().getUniqueFileName(
885                        m_clonedCms,
886                        "/sites",
887                        getFieldTitle().toLowerCase());
888                    setFolderNameState(niceName);
889                    setFieldFolder(niceName);
890                }
891
892            }
893        });
894
895        m_simpleFieldFolderName.addBlurListener(new BlurListener() {
896
897            private static final long serialVersionUID = 2080245499551324408L;
898
899            public void blur(BlurEvent event) {
900
901                checkTemplate();
902                setFolderNameState(null);
903
904            }
905        });
906
907        m_fieldLoadSiteTemplate.addValidator(new SiteTemplateValidator());
908
909        m_fieldLoadSiteTemplate.addValueChangeListener(new ValueChangeListener() {
910
911            private static final long serialVersionUID = -5859547073423161234L;
912
913            public void valueChange(ValueChangeEvent event) {
914
915                resetFields();
916                loadMessageBundle();
917                m_manager.centerWindow();
918
919            }
920        });
921
922        m_fieldLoadSiteTemplate.setUseRootPaths(true);
923        m_fieldLoadSiteTemplate.setCmsObject(m_clonedCms);
924        m_fieldLoadSiteTemplate.requireFolder();
925        m_fieldLoadSiteTemplate.setResourceFilter(CmsResourceFilter.ONLY_VISIBLE_NO_DELETED.addRequireFolder());
926
927        m_fieldSelectParentOU.setEnabled(false);
928
929        m_report.setVisible(false);
930        m_blockChange = false;
931
932        m_aliasGroup = new CmsEditableGroup(m_aliases, new Supplier<Component>() {
933
934            public Component get() {
935
936                return createAliasComponent("", CmsSiteMatcher.RedirectMode.temporary);
937
938            }
939
940        }, CmsVaadinUtils.getMessageText(Messages.GUI_SITE_ADD_ALIAS_0));
941
942        m_alternativeSiteRootPrefixGroup = new CmsEditableGroup(m_altSiteRootPathContainer, () -> {
943            TextField pathField = new TextField();
944            return pathField;
945
946        }, CmsVaadinUtils.getMessageText(Messages.GUI_SITE_ADD_PATH_0));
947        m_clearAltSiteRoot.addClickListener(evt -> {
948            m_alternativeSiteRootPrefixGroup.removeAll();
949            m_altSiteRootSuffix.setValue("");
950            m_altSiteRoot.setValue("");
951        });
952        m_aliasGroup.init();
953        m_alternativeSiteRootPrefixGroup.init();
954
955    }
956
957    /**
958     * Constructor.<p>
959     * Used to edit existing site.<p>
960     *
961     * @param manager the manager instance
962     * @param siteRoot of site to edit
963     * @param cms the CmsObject
964     */
965    public CmsEditSiteForm(CmsObject cms, CmsSiteManager manager, String siteRoot) {
966
967        this(cms, manager);
968        m_site = manager.getElement(siteRoot);
969        setFieldsForSite(true);
970
971    }
972
973    /**
974     * Creates an IndexedContaienr for use in SSL mode selection widgets.<p>
975     *
976     * @param captionProp the name of the property to use for captions
977     * @param includeOldStyle true if the old-style secure server mode should be included
978     * @param currentValue the current value of the mode (may be null)
979     *
980     * @return the container with the SSL mode items
981     */
982    protected static IndexedContainer getSSLModeContainer(
983        String captionProp,
984        boolean includeOldStyle,
985        CmsSSLMode currentValue) {
986
987        IndexedContainer res = new IndexedContainer();
988        res.addContainerProperty(captionProp, String.class, "");
989        boolean isLetsEncrypt = currentValue == CmsSSLMode.LETS_ENCRYPT;
990        boolean letsEncryptConfigured = (OpenCms.getLetsEncryptConfig() != null)
991            && OpenCms.getLetsEncryptConfig().isValidAndEnabled();
992        boolean skipLetsEncrypt = !letsEncryptConfigured && !isLetsEncrypt;
993
994        for (CmsSSLMode mode : CmsSSLMode.availableModes(includeOldStyle, !skipLetsEncrypt)) {
995            Item item = res.addItem(mode);
996            item.getItemProperty(captionProp).setValue(mode.getLocalizedMessage());
997        }
998        return res;
999    }
1000
1001    /**
1002     * Returns a Folder Name for a given site-root.<p>
1003     *
1004     * @param siteRoot site root of a site
1005     * @return Folder Name
1006     */
1007    static String getFolderNameFromSiteRoot(String siteRoot) {
1008
1009        return siteRoot.split("/")[siteRoot.split("/").length - 1];
1010    }
1011
1012    /**
1013     * Validates a site URI is syntactically correct
1014     * .
1015     * @param enteredServer the site URI to check
1016     * @throws InvalidValueException if the site URI is invalid
1017     */
1018    public void checkUriAuthority(String enteredServer) throws InvalidValueException {
1019
1020        boolean invalid = false;
1021        try {
1022            URI uri = new URI(enteredServer);
1023            if (uri.getAuthority() == null) {
1024                LOG.debug("missing authority: " + enteredServer);
1025                invalid = true;
1026            }
1027        } catch (URISyntaxException e) {
1028            invalid = true;
1029        }
1030        if (invalid) {
1031            throw new InvalidValueException(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_INVALID_URI_0));
1032        }
1033
1034    }
1035
1036    /**
1037     * Checks if site root exists in on and offline repository.<p>
1038     */
1039    protected void checkOnOfflineSiteRoot() {
1040
1041        try {
1042            CmsObject cmsOnline = OpenCms.initCmsObject(m_clonedCms);
1043            cmsOnline.getRequestContext().setCurrentProject(m_clonedCms.readProject(CmsProject.ONLINE_PROJECT_ID));
1044
1045            String rootPath = m_simpleFieldSiteRoot.getValue();
1046            if (cmsOnline.existsResource(rootPath) & !m_clonedCms.existsResource(rootPath)) {
1047                m_ok.setEnabled(false);
1048                m_infoSiteRoot.setVisible(true);
1049                return;
1050            }
1051
1052            if (!m_site.getSiteRootUUID().isNullUUID()) {
1053                if (m_clonedCms.existsResource(m_site.getSiteRootUUID()) & !m_clonedCms.existsResource(rootPath)) {
1054                    m_ok.setEnabled(false);
1055                    m_infoSiteRoot.setVisible(true);
1056                    return;
1057                }
1058            }
1059
1060        } catch (CmsException e) {
1061            LOG.error("Can not initialize CmsObject", e);
1062        }
1063        m_ok.setEnabled(true);
1064        m_infoSiteRoot.setVisible(false);
1065    }
1066
1067    /**
1068     * Checks the Template Property of the site root and fills the form field.<p>
1069     */
1070    protected void checkTemplate() {
1071
1072        if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_simpleFieldFolderName.getValue())) {
1073            return;
1074        }
1075        if (!m_clonedCms.existsResource(getSiteRoot())) {
1076            return;
1077        }
1078        try {
1079            String templateValue = m_clonedCms.readPropertyObject(
1080                getSiteRoot(),
1081                CmsPropertyDefinition.PROPERTY_TEMPLATE,
1082                false).getValue();
1083            m_simpleFieldTemplate.addItem(templateValue);
1084            m_simpleFieldTemplate.setValue(templateValue);
1085        } catch (CmsException e) {
1086            //
1087        }
1088    }
1089
1090    /**
1091     * Creates field for aliases.<p>
1092     *
1093     * @param alias url
1094     * @param red redirect
1095     * @return component
1096     */
1097    protected FormLayout createAliasComponent(String alias, CmsSiteMatcher.RedirectMode redirectMode) {
1098
1099        FormLayout layout = new FormLayout();
1100        TextField field = new TextField(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_ALIAS_0));
1101        field.setWidth("100%");
1102        field.setValue(alias);
1103        field.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_ALIAS_HELP_0));
1104        ComboBox redirectSelection = new ComboBox();
1105        redirectSelection.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_ALIAS_REDIRECT_0));
1106        redirectSelection.setWidth("100%");
1107        redirectSelection.addItem(RedirectMode.none);
1108        redirectSelection.addItem(RedirectMode.temporary);
1109        redirectSelection.addItem(RedirectMode.permanent);
1110        redirectSelection.setItemCaptionMode(ItemCaptionMode.EXPLICIT);
1111        redirectSelection.setItemCaption(
1112            RedirectMode.none,
1113            CmsVaadinUtils.getMessageText(Messages.GUI_SITE_REDIRECT_MODE_NONE_0));
1114        redirectSelection.setItemCaption(
1115            RedirectMode.temporary,
1116            CmsVaadinUtils.getMessageText(Messages.GUI_SITE_REDIRECT_MODE_TEMPORARY_0));
1117        redirectSelection.setItemCaption(
1118            RedirectMode.permanent,
1119            CmsVaadinUtils.getMessageText(Messages.GUI_SITE_REDIRECT_MODE_PERMANENT_0));
1120        redirectSelection.setNullSelectionAllowed(false);
1121        redirectSelection.setNewItemsAllowed(false);
1122        redirectSelection.setTextInputAllowed(false);
1123        redirectSelection.setValue(redirectMode);
1124        // CheckBox redirect = new CheckBox(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_ALIAS_REDIRECT_0), red);
1125        redirectSelection.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_ALIAS_REDIRECT_HELP_0));
1126        layout.addComponent(field);
1127        layout.addComponent(redirectSelection);
1128        return layout;
1129    }
1130
1131    /**
1132     * Reads server field.<p>
1133     *
1134     * @return server as string
1135     */
1136    protected String getFieldServer() {
1137
1138        return m_simpleFieldServer.getValue();
1139    }
1140
1141    /**
1142     * Handles SSL changes.<p>
1143     */
1144    protected void handleSSLChange() {
1145
1146        String toBeReplaced = "http:";
1147        String newString = "https:";
1148        CmsSSLMode mode = (CmsSSLMode)m_simpleFieldEncryption.getValue();
1149        if (mode == null) {
1150            // mode is null if this is triggered by setContainerDataSource
1151            return;
1152        }
1153        if (mode.equals(CmsSSLMode.NO) | mode.equals(CmsSSLMode.SECURE_SERVER)) {
1154            toBeReplaced = "https:";
1155            newString = "http:";
1156        }
1157        m_simpleFieldServer.setValue(m_simpleFieldServer.getValue().replaceAll(toBeReplaced, newString));
1158        m_fieldSecureServer.setVisible(mode.equals(CmsSSLMode.SECURE_SERVER));
1159        m_fieldExclusiveError.setVisible(mode.equals(CmsSSLMode.SECURE_SERVER));
1160        m_fieldExclusiveURL.setVisible(mode.equals(CmsSSLMode.SECURE_SERVER));
1161
1162    }
1163
1164    /**
1165     * Sets the template field depending on current set site root field(s).<p>
1166     */
1167    protected void setTemplateField() {
1168
1169        setTemplateFieldForSiteroot(getSiteRoot());
1170    }
1171
1172    /**
1173     * Add a given parameter to the form layout.<p>
1174     *
1175     * @param parameter parameter to add to form
1176     */
1177    void addParameter(String parameter) {
1178
1179        TextField textField = new TextField();
1180        if (parameter != null) {
1181            textField.setValue(parameter);
1182        }
1183        CmsRemovableFormRow<TextField> row = new CmsRemovableFormRow<TextField>(
1184            textField,
1185            CmsVaadinUtils.getMessageText(Messages.GUI_SITE_REMOVE_PARAMETER_0));
1186        row.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_PARAMETER_0));
1187        row.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_PARAMETER_HELP_0));
1188        m_parameter.addComponent(row);
1189    }
1190
1191    /**
1192     * Closes the dialog.<p>
1193     *
1194     * @param updateTable <code>true</code> to update the site table
1195     */
1196    void closeDialog(boolean updateTable) {
1197
1198        m_manager.closeDialogWindow(updateTable);
1199    }
1200
1201    /**
1202     * Checks if there are at least one character in the folder name,
1203     * also ensures that it ends with a '/' and doesn't start with '/'.<p>
1204     *
1205     * @param resourcename folder name to check (complete path)
1206     * @return the validated folder name
1207     * @throws CmsIllegalArgumentException if the folder name is empty or <code>null</code>
1208     */
1209    String ensureFoldername(String resourcename) {
1210
1211        if (CmsStringUtil.isEmpty(resourcename)) {
1212            return "";
1213        }
1214        if (!CmsResource.isFolder(resourcename)) {
1215            resourcename = resourcename.concat("/");
1216        }
1217        if (resourcename.charAt(0) == '/') {
1218            resourcename = resourcename.substring(1);
1219        }
1220        return resourcename;
1221    }
1222
1223    /**
1224     * Returns the value of the site-folder.<p>
1225     *
1226     * @return String of folder path.
1227     */
1228    String getFieldFolder() {
1229
1230        return m_simpleFieldFolderName.getValue();
1231    }
1232
1233    /**
1234     * Reads title field.<p>
1235     *
1236     * @return title as string.
1237     */
1238    String getFieldTitle() {
1239
1240        return m_simpleFieldTitle.getValue();
1241    }
1242
1243    /**
1244     * Returns parent folder.<p>
1245     *
1246     * @return parent folder as string
1247     */
1248    String getParentFolder() {
1249
1250        return m_simpleFieldParentFolderName.getValue();
1251    }
1252
1253    /**
1254     * Returns the value of the site template field.<p>
1255     *
1256     * @return string root path
1257     */
1258    String getSiteTemplatePath() {
1259
1260        return m_fieldLoadSiteTemplate.getValue();
1261    }
1262
1263    /**
1264     * Checks if an alias was entered twice.<p>
1265     *
1266     * @param aliasName to check
1267     * @return true if it was defined double
1268     */
1269    boolean isDoubleAlias(String aliasName) {
1270
1271        CmsSiteMatcher testAlias = new CmsSiteMatcher(aliasName);
1272        int count = 0;
1273        for (Component c : m_aliases) {
1274            if (c instanceof I_CmsEditableGroupRow) {
1275                TextField field = getTextFieldForAliasRow((I_CmsEditableGroupRow)c);
1276                String alName = field.getValue();
1277                if (testAlias.equals(new CmsSiteMatcher(alName))) {
1278                    count++;
1279                }
1280            }
1281        }
1282        return count > 1;
1283    }
1284
1285    /**
1286     * Checks if folder name was touched.<p>
1287     *
1288     * Considered as touched if side is edited or value of foldername was changed by user.<p>
1289     *
1290     * @return boolean true means Folder value was set by user or existing site and should not be changed by title-listener
1291     */
1292    boolean isFolderNameTouched() {
1293
1294        if (m_site != null) {
1295            return true;
1296        }
1297        if (m_autoSetFolderName.equals(getFieldFolder())) {
1298            return false;
1299        }
1300        return m_isFolderNameTouched;
1301    }
1302
1303    /**
1304     * Are the aliase valid?<p>
1305     *
1306     * @return true if ok
1307     */
1308    boolean isValidAliase() {
1309
1310        boolean ret = true;
1311
1312        for (I_CmsEditableGroupRow row : m_aliasGroup.getRows()) {
1313
1314            TextField field = getTextFieldForAliasRow(row);
1315            ret = ret & field.isValid();
1316        }
1317        return ret;
1318    }
1319
1320    boolean isValidAltSiteRootSettings() {
1321
1322        return m_altSiteRoot.isValid();
1323    }
1324
1325    /**
1326     * Checks if all required fields are set correctly at first Tab.<p>
1327     *
1328     * @return true if all inputs are valid.
1329     */
1330    boolean isValidInputSimple() {
1331
1332        return (m_simpleFieldFolderName.isValid()
1333            & m_simpleFieldServer.isValid()
1334            & m_simpleFieldSiteRoot.isValid()
1335            & m_simpleFieldTitle.isValid()
1336            & m_simpleFieldParentFolderName.isValid()
1337            & m_fieldSelectOU.isValid()
1338            & m_simpleFieldSiteRoot.isValid());
1339    }
1340
1341    /**
1342     * Checks if all required fields are set correctly at site template tab.<p>
1343     *
1344     * @return true if all inputs are valid.
1345     */
1346    boolean isValidInputSiteTemplate() {
1347
1348        return (m_fieldLoadSiteTemplate.isValid() & m_fieldSelectParentOU.isValid());
1349    }
1350
1351    /**
1352     * Checks if manual secure server is valid.<p>
1353     *
1354     * @return boolean
1355     */
1356    boolean isValidSecureServer() {
1357
1358        if (m_fieldSecureServer.isVisible()) {
1359            return m_fieldSecureServer.isValid();
1360        }
1361        return true;
1362    }
1363
1364    /**
1365     * Loads message bundle from bundle defined inside the site-template which is used to create new site.<p>
1366     */
1367    void loadMessageBundle() {
1368
1369        //Check if chosen site template is valid and not empty
1370        if (!m_fieldLoadSiteTemplate.isValid()
1371            | m_fieldLoadSiteTemplate.isEmpty()
1372            | !CmsSiteManager.isFolderWithMacros(m_clonedCms, m_fieldLoadSiteTemplate.getValue())) {
1373            return;
1374        }
1375        try {
1376            m_bundleComponentKeyMap = new HashMap<TextField, String>();
1377
1378            //Get resource of the descriptor.
1379            CmsResource descriptor = m_clonedCms.readResource(
1380                m_fieldLoadSiteTemplate.getValue()
1381                    + CmsSiteManager.MACRO_FOLDER
1382                    + "/"
1383                    + CmsSiteManager.BUNDLE_NAME
1384                    + "_desc");
1385            //Read related bundle
1386
1387            Properties resourceBundle = getLocalizedBundle();
1388            Map<String, String[]> bundleKeyDescriptorMap = CmsMacroResolver.getBundleMapFromResources(
1389                resourceBundle,
1390                descriptor,
1391                m_clonedCms);
1392
1393            for (String key : bundleKeyDescriptorMap.keySet()) {
1394
1395                //Create TextField
1396                TextField field = new TextField();
1397                field.setCaption(bundleKeyDescriptorMap.get(key)[0]);
1398                field.setValue(bundleKeyDescriptorMap.get(key)[1]);
1399                field.setWidth("100%");
1400
1401                //Add vaadin component to UI and keep related key in HashMap
1402                m_bundleValues.addComponent(field);
1403                m_bundleComponentKeyMap.put(field, key);
1404            }
1405        } catch (CmsException | IOException e) {
1406            LOG.error("Error reading bundle", e);
1407        }
1408    }
1409
1410    /**
1411     * Clears the message bundle and removes related text fields from UI.<p>
1412     */
1413    void resetFields() {
1414
1415        if (m_bundleComponentKeyMap != null) {
1416            Set<TextField> setBundles = m_bundleComponentKeyMap.keySet();
1417
1418            for (TextField field : setBundles) {
1419                m_bundleValues.removeComponent(field);
1420            }
1421            m_bundleComponentKeyMap.clear();
1422        }
1423        m_fieldKeepTemplate.setVisible(!CmsStringUtil.isEmptyOrWhitespaceOnly(m_fieldLoadSiteTemplate.getValue()));
1424        m_fieldKeepTemplate.setValue(
1425            Boolean.valueOf(!CmsStringUtil.isEmptyOrWhitespaceOnly(m_fieldLoadSiteTemplate.getValue())));
1426    }
1427
1428    /**
1429     * Sets a new uploaded favicon and changes the caption of the upload button.<p>
1430     *
1431     * @param imageData holdings byte array of favicon
1432     */
1433    void setCurrentFavIcon(final byte[] imageData) {
1434
1435        m_fieldFavIcon.setVisible(true);
1436        m_fieldUploadFavIcon.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_FAVICON_CHANGE_0));
1437        m_fieldFavIcon.setSource(new StreamResource(new StreamResource.StreamSource() {
1438
1439            private static final long serialVersionUID = -8868657402793427460L;
1440
1441            public InputStream getStream() {
1442
1443                return new ByteArrayInputStream(imageData);
1444            }
1445        }, ""));
1446    }
1447
1448    /**
1449     * Tries to read and show the favicon of the site.<p>
1450     */
1451    void setFaviconIfExist() {
1452
1453        try {
1454            CmsResource favicon = m_clonedCms.readResource(m_site.getSiteRoot() + "/" + CmsSiteManager.FAVICON);
1455            setCurrentFavIcon(m_clonedCms.readFile(favicon).getContents()); //FavIcon was found -> give it to the UI
1456        } catch (CmsException e) {
1457            //no favicon, do nothing
1458        }
1459    }
1460
1461    /**
1462     * Sets the folder field.<p>
1463     *
1464     * @param newValue value of the field
1465     */
1466    void setFieldFolder(String newValue) {
1467
1468        m_simpleFieldFolderName.setValue(newValue);
1469    }
1470
1471    /**
1472     * Sets the folder Name state to recognize if folder field was touched.<p>
1473     *
1474     * @param setFolderName name of folder set by listener from title.
1475     */
1476    void setFolderNameState(String setFolderName) {
1477
1478        if (setFolderName == null) {
1479            if (m_simpleFieldFolderName.getValue().isEmpty()) {
1480                m_isFolderNameTouched = false;
1481                return;
1482            }
1483            m_isFolderNameTouched = true;
1484        } else {
1485            m_autoSetFolderName = setFolderName;
1486        }
1487    }
1488
1489    /**
1490     * Enables the ok button after finishing report thread.<p>
1491     */
1492    void setOkButtonEnabled() {
1493
1494        m_ok.setEnabled(true);
1495        m_ok.setCaption(CmsVaadinUtils.getMessageText(org.opencms.workplace.Messages.GUI_DIALOG_BUTTON_CLOSE_0));
1496        m_ok.removeClickListener(m_okClickListener);
1497        m_ok.addClickListener(new ClickListener() {
1498
1499            private static final long serialVersionUID = 5637556711524961424L;
1500
1501            public void buttonClick(ClickEvent event) {
1502
1503                closeDialog(true);
1504            }
1505        });
1506    }
1507
1508    /**
1509     * Fill ComboBox for OU selection.<p>
1510     * @param combo combo box
1511     */
1512    void setUpOUComboBox(ComboBox combo) {
1513
1514        combo.removeAllItems();
1515        try {
1516            if (m_site != null) {
1517                String siteOu = getSiteOU();
1518                combo.addItem(siteOu);
1519                combo.select(siteOu);
1520                combo.setEnabled(false);
1521            } else {
1522                combo.addItem("/");
1523
1524                m_clonedCms.getRequestContext().setSiteRoot("");
1525                List<CmsOrganizationalUnit> ous = OpenCms.getOrgUnitManager().getOrganizationalUnits(
1526                    m_clonedCms,
1527                    "/",
1528                    true);
1529
1530                for (CmsOrganizationalUnit ou : ous) {
1531
1532                    if (ouIsOK(ou)) {
1533                        combo.addItem(ou.getName());
1534                    }
1535
1536                }
1537                combo.select("/");
1538            }
1539
1540        } catch (CmsException e) {
1541            LOG.error("Error on reading OUs", e);
1542        }
1543        combo.setNullSelectionAllowed(false);
1544        combo.setTextInputAllowed(true);
1545        combo.setFilteringMode(FilteringMode.CONTAINS);
1546        combo.setNewItemsAllowed(false);
1547
1548    }
1549
1550    /**
1551     * Setup for the aliase validator.<p>
1552     */
1553    void setupValidatorAliase() {
1554
1555        for (I_CmsEditableGroupRow row : m_aliasGroup.getRows()) {
1556            FormLayout layout = (FormLayout)(row.getComponent());
1557            TextField field = (TextField)layout.getComponent(0);
1558            field.removeAllValidators();
1559            field.addValidator(new AliasValidator());
1560        }
1561    }
1562
1563    /**
1564     * Setup validators which get called on click.<p>
1565     * Site-template gets validated separately.<p>
1566     */
1567    void setupValidators() {
1568
1569        if (m_simpleFieldServer.getValidators().size() == 0) {
1570            if (m_site == null) {
1571                m_simpleFieldFolderName.addValidator(new FolderPathValidator());
1572                m_simpleFieldParentFolderName.addValidator(new ParentFolderValidator());
1573            }
1574            if ((m_simpleFieldSiteRoot != null) && m_simpleFieldSiteRoot.isVisible()) {
1575                m_simpleFieldSiteRoot.addValidator(value -> {
1576                    String siteRoot = (String)value;
1577                    try {
1578                        OpenCms.getSiteManager().validateSiteRoot(siteRoot);
1579                    } catch (Exception e) {
1580                        LOG.warn(e.getLocalizedMessage(), e);
1581                        throw new InvalidValueException(e.getMessage());
1582                    }
1583                });
1584            }
1585            m_simpleFieldServer.addValidator(new ServerValidator());
1586            if (m_fieldSecureServer.isVisible()) {
1587                m_fieldSecureServer.addValidator(new AliasValidator());
1588            }
1589            m_simpleFieldTitle.addValidator(new TitleValidator());
1590            if (m_site == null) {
1591                m_fieldSelectOU.addValidator(new SelectOUValidator());
1592            }
1593            if (m_fieldCreateOU.getValue().booleanValue()) {
1594                m_fieldSelectParentOU.addValidator(new SelectParentOUValidator());
1595            }
1596
1597            m_altSiteRoot.addValidator(fieldValue -> {
1598                String path = (String)fieldValue;
1599                if (path == null) {
1600                    return;
1601                }
1602                path = path.trim();
1603                CmsSite site = OpenCms.getSiteManager().getSiteForRootPath(path);
1604                if (site != null) {
1605                    if (site.isGenerated()) {
1606                        if (!m_site.getSiteMatcher().equals(site.getSiteMatcher())) {
1607                            throw new InvalidValueException(
1608                                CmsVaadinUtils.getMessageText(Messages.GUI_SITE_FOLDERNAME_ALREADYUSED_1, path));
1609                        }
1610                    } else {
1611                        throw new InvalidValueException(
1612                            CmsVaadinUtils.getMessageText(Messages.GUI_SITE_FOLDERNAME_ALREADYUSED_1, path));
1613                    }
1614                }
1615
1616                for (String forbiddenPrefix : new String[] {OpenCms.getSiteManager().getSharedFolder(), "/system"}) {
1617                    if (CmsStringUtil.isPrefixPath(forbiddenPrefix, path)) {
1618                        throw new InvalidValueException("Forbidden path for alternative site root rule.");
1619                    }
1620                }
1621
1622                try {
1623                    CmsObject cms = OpenCms.initCmsObject(A_CmsUI.getCmsObject());
1624                    cms.getRequestContext().setSiteRoot("");
1625                    cms.readResource(path);
1626                } catch (CmsException e) {
1627                    throw new InvalidValueException(e.getLocalizedMessage(A_CmsUI.get().getLocale()));
1628                }
1629            });
1630        }
1631    }
1632
1633    /**
1634     * Saves the entered site-data as a CmsSite object.<p>
1635     */
1636    void submit() {
1637
1638        // switch to root site
1639        m_clonedCms.getRequestContext().setSiteRoot("");
1640
1641        CmsSite site = getSiteFromForm();
1642
1643        if (m_site == null) {
1644
1645            //Show report field and hide form fields
1646            m_report.setVisible(true);
1647            m_tab.setVisible(false);
1648            m_ok.setEnabled(false);
1649            m_ok.setVisible(true);
1650            //Change cancel caption to close (will not interrupt site creation anymore)
1651            m_cancel.setVisible(false);
1652            setOkButtonEnabled();
1653            m_cancel.setCaption(
1654                CmsVaadinUtils.getMessageText(org.opencms.workplace.Messages.GUI_DIALOG_BUTTON_CLOSE_0));
1655
1656            Map<String, String> bundle = getBundleMap();
1657
1658            boolean createOU = m_fieldCreateOU.isEnabled() & m_fieldCreateOU.getValue().booleanValue();
1659            CmsCreateSiteThread createThread = new CmsCreateSiteThread(
1660                m_clonedCms,
1661                m_manager,
1662                site,
1663                m_site,
1664                m_fieldLoadSiteTemplate.getValue(),
1665                getFieldTemplate(),
1666                createOU,
1667                (String)m_fieldSelectParentOU.getValue(),
1668                (String)m_fieldSelectOU.getValue(),
1669                m_os,
1670                bundle,
1671                new Runnable() {
1672
1673                    public void run() {
1674
1675                    }
1676
1677                });
1678
1679            CmsReportWidget report = new CmsReportWidget(createThread);
1680
1681            report.setWidth("100%");
1682            report.setHeight("350px");
1683
1684            m_threadReport.addComponent(report);
1685            createThread.start();
1686        } else {
1687            if (!site.getSiteRoot().equals(m_site.getSiteRoot())) {
1688                m_manager.deleteElements(Collections.singletonList(m_site.getSiteRoot()));
1689            }
1690            m_manager.writeElement(site);
1691            m_manager.closeDialogWindow(true);
1692        }
1693
1694    }
1695
1696    /**
1697     * Toogles secure server options.<p>
1698     */
1699    void toggleSecureServer() {
1700
1701        if (m_fieldSecureServer.isEmpty()) {
1702            m_fieldExclusiveURL.setEnabled(false);
1703            m_fieldExclusiveError.setEnabled(false);
1704            return;
1705        }
1706        m_fieldExclusiveURL.setEnabled(true);
1707        m_fieldExclusiveError.setEnabled(true);
1708    }
1709
1710    /**
1711     * Toogles the select OU combo box depending on create ou check box.<p>
1712     */
1713    void toggleSelectOU() {
1714
1715        boolean create = m_fieldCreateOU.getValue().booleanValue();
1716
1717        m_fieldSelectOU.setEnabled(!create);
1718        m_fieldSelectParentOU.setEnabled(create);
1719        m_fieldSelectOU.select("/");
1720    }
1721
1722    private void fillAlternativeSiteRootTab(CmsAlternativeSiteRootMapping alternativeSiteRootMapping) {
1723
1724        if (alternativeSiteRootMapping != null) {
1725            m_altSiteRoot.setValue(alternativeSiteRootMapping.getSiteRoot().asString());
1726            m_altSiteRootSuffix.setValue(alternativeSiteRootMapping.getTitleSuffix());
1727            for (CmsPath prefix : alternativeSiteRootMapping.getPrefixes()) {
1728                TextField prefixField = new TextField();
1729                prefixField.setValue(prefix.asString());
1730                m_alternativeSiteRootPrefixGroup.addRow(prefixField);
1731            }
1732        }
1733    }
1734
1735    /**
1736     * Reads out all aliases from the form.<p>
1737     *
1738     * @return a List of CmsSiteMatcher
1739     */
1740    private List<CmsSiteMatcher> getAliases() {
1741
1742        List<CmsSiteMatcher> ret = new ArrayList<CmsSiteMatcher>();
1743        for (I_CmsEditableGroupRow row : m_aliasGroup.getRows()) {
1744            FormLayout layout = (FormLayout)(row.getComponent());
1745            ComboBox box = (ComboBox)(layout.getComponent(1));
1746            TextField field = (TextField)layout.getComponent(0);
1747            String value = field.getValue();
1748            if (CmsStringUtil.isEmptyOrWhitespaceOnly(value)) {
1749                continue;
1750            }
1751            CmsSiteMatcher matcher = new CmsSiteMatcher(value);
1752            matcher.setRedirectMode((RedirectMode)(box.getValue()));
1753            ret.add(matcher);
1754        }
1755        return ret;
1756    }
1757
1758    /**
1759     * Returns the correct varaint of a resource name accoreding to locale.<p>
1760     *
1761     * @param path where the considered resource is.
1762     * @param baseName of the resource
1763     * @return localized name of resource
1764     */
1765    private String getAvailableLocalVariant(String path, String baseName) {
1766
1767        //First look for a bundle with the locale of the folder..
1768        try {
1769            CmsProperty propLoc = m_clonedCms.readPropertyObject(path, CmsPropertyDefinition.PROPERTY_LOCALE, true);
1770            if (!propLoc.isNullProperty()) {
1771                if (m_clonedCms.existsResource(path + baseName + "_" + propLoc.getValue())) {
1772                    return baseName + "_" + propLoc.getValue();
1773                }
1774            }
1775        } catch (CmsException e) {
1776            LOG.error("Can not read locale property", e);
1777        }
1778
1779        //If no bundle was found with the locale of the folder, or the property was not set, search for other locales
1780        A_CmsUI.get();
1781        List<String> localVariations = CmsLocaleManager.getLocaleVariants(
1782            baseName,
1783            UI.getCurrent().getLocale(),
1784            false,
1785            true);
1786
1787        for (String name : localVariations) {
1788            if (m_clonedCms.existsResource(path + name)) {
1789                return name;
1790            }
1791        }
1792
1793        return null;
1794    }
1795
1796    /**
1797     * Reads out bundle values from UI and stores keys with values in HashMap.<p>
1798     *
1799     * @return hash map
1800     */
1801    private Map<String, String> getBundleMap() {
1802
1803        Map<String, String> bundles = new HashMap<String, String>();
1804
1805        if (m_bundleComponentKeyMap != null) {
1806            Set<TextField> fields = m_bundleComponentKeyMap.keySet();
1807
1808            for (TextField field : fields) {
1809                bundles.put(m_bundleComponentKeyMap.get(field), field.getValue());
1810            }
1811        }
1812        return bundles;
1813    }
1814
1815    /**
1816     * Reads ComboBox with Template information.<p>
1817     *
1818     * @return string of chosen template path.
1819     */
1820    private String getFieldTemplate() {
1821
1822        if (m_fieldKeepTemplate.getValue().booleanValue()) {
1823            return ""; //No template property will be changed
1824        }
1825        Object value = m_simpleFieldTemplate.getValue();
1826        if (value != null) {
1827            return (String)value;
1828        }
1829        return "";
1830    }
1831
1832    /**
1833     * Gets localized property object.<p>
1834     *
1835     * @return Properties object
1836     * @throws CmsException exception
1837     * @throws IOException exception
1838     */
1839    private Properties getLocalizedBundle() throws CmsException, IOException {
1840
1841        CmsResource bundleResource = m_clonedCms.readResource(
1842            m_fieldLoadSiteTemplate.getValue()
1843                + CmsSiteManager.MACRO_FOLDER
1844                + "/"
1845                + getAvailableLocalVariant(
1846                    m_fieldLoadSiteTemplate.getValue() + CmsSiteManager.MACRO_FOLDER + "/",
1847                    CmsSiteManager.BUNDLE_NAME));
1848
1849        Properties ret = new Properties();
1850        InputStreamReader reader = new InputStreamReader(
1851            new ByteArrayInputStream(m_clonedCms.readFile(bundleResource).getContents()),
1852            StandardCharsets.UTF_8);
1853        ret.load(reader);
1854
1855        return ret;
1856    }
1857
1858    /**
1859     * Reads parameter from form.<p>
1860     *
1861     * @return a Map with Parameter information.
1862     */
1863    private Map<String, String> getParameter() {
1864
1865        Map<String, String> ret = new TreeMap<String, String>();
1866        for (Component c : m_parameter) {
1867            if (c instanceof CmsRemovableFormRow<?>) {
1868                String[] parameterStringArray = ((String)((CmsRemovableFormRow<? extends AbstractField<?>>)c).getInput().getValue()).split(
1869                    "=");
1870                ret.put(parameterStringArray[0], parameterStringArray[1]);
1871            }
1872        }
1873        return ret;
1874    }
1875
1876    /**
1877     * Map entry of parameter to String representation.<p>
1878     *
1879     * @param parameter Entry holding parameter info.
1880     * @return the parameter formatted as string
1881     */
1882    private String getParameterString(Entry<String, String> parameter) {
1883
1884        return parameter.getKey() + "=" + parameter.getValue();
1885    }
1886
1887    /**
1888     * Reads out all forms and creates a site object.<p>
1889     *
1890     * @return the site object.
1891     */
1892    private CmsSite getSiteFromForm() {
1893
1894        String siteRoot = getSiteRoot();
1895        CmsSiteMatcher matcher = (CmsStringUtil.isNotEmpty(m_fieldSecureServer.getValue())
1896            & m_simpleFieldEncryption.getValue().equals(CmsSSLMode.SECURE_SERVER))
1897            ? new CmsSiteMatcher(m_fieldSecureServer.getValue())
1898            : null;
1899        CmsSite site = OpenCms.getSiteManager().getSiteForSiteRoot(siteRoot);
1900        CmsUUID uuid = new CmsUUID();
1901        if ((site != null) && (site.getSiteMatcher() != null)) {
1902            uuid = (CmsUUID)site.getSiteRootUUID().clone();
1903        }
1904        String errorPage = CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_fieldErrorPage.getValue())
1905        ? m_fieldErrorPage.getValue()
1906        : null;
1907        List<CmsSiteMatcher> aliases = getAliases();
1908        CmsSite ret = new CmsSite(
1909            siteRoot,
1910            uuid,
1911            getFieldTitle(),
1912            new CmsSiteMatcher(getFieldServer()),
1913            ((PositionComboBoxElementBean)m_fieldPosition.getValue()).getPosition() == -1
1914            ? String.valueOf(m_site.getPosition())
1915            : String.valueOf(((PositionComboBoxElementBean)m_fieldPosition.getValue()).getPosition()),
1916            errorPage,
1917            matcher,
1918            m_fieldExclusiveURL.getValue().booleanValue(),
1919            m_fieldExclusiveError.getValue().booleanValue(),
1920            m_fieldWebServer.getValue().booleanValue(),
1921            aliases,
1922            ((Boolean)m_subsiteSelectionEnabled.getValue()).booleanValue());
1923        ret.setParameters((SortedMap<String, String>)getParameter());
1924        ret.setSSLMode((CmsSSLMode)m_simpleFieldEncryption.getValue());
1925        String alternativeSiteRoot = m_altSiteRoot.getValue();
1926        if (!CmsStringUtil.isEmptyOrWhitespaceOnly(alternativeSiteRoot)) {
1927            String suffix = m_altSiteRootSuffix.getValue();
1928            List<String> prefixPaths = new ArrayList<>();
1929            for (I_CmsEditableGroupRow prefixRow : m_alternativeSiteRootPrefixGroup.getRows()) {
1930                TextField prefixField = (TextField)(prefixRow.getComponent());
1931                prefixPaths.add(prefixField.getValue());
1932            }
1933            ret.setAlternativeSiteRootMapping(
1934                Optional.of(new CmsAlternativeSiteRootMapping(alternativeSiteRoot, prefixPaths, suffix)));
1935        }
1936
1937        return ret;
1938    }
1939
1940    /**
1941     * Get ou name for current site.<p>
1942     *
1943     * @return Full ou name
1944     */
1945    private String getSiteOU() {
1946
1947        try {
1948            m_clonedCms.getRequestContext().setSiteRoot("");
1949            CmsResource resource = m_clonedCms.readResource(m_site.getSiteRoot());
1950            List<CmsRelation> relations = m_clonedCms.getRelationsForResource(resource, CmsRelationFilter.SOURCES);
1951            for (CmsRelation relation : relations) {
1952                if (relation.getSourcePath().startsWith("/system/orgunits/")) {
1953                    return (relation.getSourcePath().substring("/system/orgunits/".length()));
1954                }
1955            }
1956        } catch (CmsException e) {
1957            LOG.error("Error on reading OUs", e);
1958        }
1959        return "/";
1960    }
1961
1962    /**
1963     * Gets the site root.<p>
1964     * Usable for new sites and for existing sites.
1965     *
1966     * @return site root string
1967     */
1968    private String getSiteRoot() {
1969
1970        String res;
1971
1972        if (m_simpleFieldSiteRoot.isVisible()) {
1973            res = m_simpleFieldSiteRoot.getValue();
1974        } else {
1975            res = "/" + ensureFoldername(getParentFolder()) + ensureFoldername(getFieldFolder());
1976            res = res.endsWith("/") ? res.substring(0, res.length() - 1) : res;
1977        }
1978        return res;
1979    }
1980
1981    /**
1982     * Gets the text field for the given alias row.
1983     *
1984     * @param row the alias row
1985     * @return the text field in that row
1986     */
1987    private TextField getTextFieldForAliasRow(I_CmsEditableGroupRow row) {
1988
1989        FormLayout layout = (FormLayout)(row.getComponent());
1990        TextField field = (TextField)layout.getComponent(0);
1991        return field;
1992    }
1993
1994    /**
1995     * Checks if given Ou has resources matching to currently set parent folder.<p>
1996     *
1997     * @param ou to check
1998     * @return true if ou is ok for parent folder
1999     */
2000    private boolean ouIsOK(CmsOrganizationalUnit ou) {
2001
2002        try {
2003            for (CmsResource res : OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(
2004                m_clonedCms,
2005                ou.getName())) {
2006
2007                if (m_simpleFieldParentFolderName.getValue().startsWith(res.getRootPath())) {
2008                    return true;
2009                }
2010
2011            }
2012        } catch (CmsException e) {
2013            LOG.error("Unable to read Resources for Org Unit", e);
2014        }
2015        return false;
2016    }
2017
2018    /**
2019     * Sets the server field.<p>
2020     *
2021     * @param newValue value of the field.
2022     */
2023    private void setFieldServer(String newValue) {
2024
2025        m_simpleFieldServer.setValue(newValue);
2026    }
2027
2028    /**
2029     * Sets the fields for a given site (m_site).<p>
2030     *
2031     * @param enableAll if true, the site is editable
2032     */
2033    private void setFieldsForSite(boolean enableAll) {
2034
2035        if (!CmsStringUtil.isEmptyOrWhitespaceOnly(m_site.getSiteRoot())) {
2036            setTemplateFieldForSiteroot(m_site.getSiteRoot());
2037            m_simpleFieldTemplate.setEnabled(false);
2038        }
2039
2040        m_simpleFieldSiteRoot.setVisible(true);
2041        m_simpleFieldSiteRoot.setValue(m_site.getSiteRoot());
2042        m_simpleFieldSiteRoot.setCmsObject(m_clonedCms);
2043        m_simpleFieldSiteRoot.addValidator(new SiteRootValidator());
2044        m_simpleFieldSiteRoot.setEnabled(enableAll);
2045        m_simpleFieldSiteRoot.addValueChangeListener(new ValueChangeListener() {
2046
2047            /**vaadin serial id. */
2048            private static final long serialVersionUID = 4680456758446195524L;
2049
2050            public void valueChange(ValueChangeEvent event) {
2051
2052                setTemplateField();
2053                checkOnOfflineSiteRoot();
2054            }
2055
2056        });
2057        m_simpleFieldParentFolderName.setVisible(false);
2058        m_simpleFieldFolderName.setVisible(false);
2059        String title = m_site.getTitle();
2060        if (title == null) {
2061            title = "";
2062        }
2063        CmsResourceInfo resourceInfo = new CmsResourceInfo(
2064            title,
2065            m_site.getSiteRoot(),
2066            m_manager.getFavIcon(m_site.getSiteRoot()));
2067        resourceInfo.addStyleName("o-res-site-info");
2068        displayResourceInfoDirectly(Collections.singletonList(resourceInfo));
2069
2070        m_tab.removeTab(m_tab.getTab(5));
2071
2072        m_simpleFieldTitle.removeTextChangeListener(null);
2073        m_simpleFieldTitle.setEnabled(enableAll);
2074        m_simpleFieldParentFolderName.setEnabled(false);
2075        m_simpleFieldParentFolderName.setValue(
2076            m_site.getSiteRoot().substring(
2077                0,
2078                m_site.getSiteRoot().length()
2079                    - m_site.getSiteRoot().split("/")[m_site.getSiteRoot().split("/").length - 1].length()));
2080
2081        m_simpleFieldFolderName.removeAllValidators(); //can not be changed
2082        m_fieldCreateOU.setVisible(false);
2083
2084        m_alreadyUsedURL.remove(m_site.getSiteMatcher().forDifferentScheme("https")); //Remove current url to avoid validation problem
2085        m_alreadyUsedURL.remove(m_site.getSiteMatcher().forDifferentScheme("http"));
2086
2087        setFieldTitle(title);
2088        setFieldFolder(getFolderNameFromSiteRoot(m_site.getSiteRoot()));
2089        m_subsiteSelectionEnabled.setValue(Boolean.valueOf(m_site.isSubsiteSelectionEnabled()));
2090        m_simpleFieldFolderName.setEnabled(false);
2091        m_simpleFieldTitle.setEnabled(enableAll);
2092
2093        setFieldServer(m_site.getUrl());
2094        m_simpleFieldServer.setEnabled(enableAll);
2095        if (m_site.hasSecureServer()) {
2096            m_fieldSecureServer.setValue(m_site.getSecureUrl());
2097        }
2098        if (m_site.getErrorPage() != null) {
2099            m_fieldErrorPage.setValue(m_site.getErrorPage());
2100        }
2101        m_fieldWebServer.setValue(Boolean.valueOf(m_site.isWebserver()));
2102        m_fieldWebServer.setEnabled(enableAll);
2103        m_fieldExclusiveURL.setValue(Boolean.valueOf(m_site.isExclusiveUrl()));
2104        m_fieldExclusiveURL.setEnabled(enableAll);
2105        m_fieldExclusiveError.setValue(Boolean.valueOf(m_site.isExclusiveError()));
2106        m_fieldExclusiveError.setEnabled(enableAll);
2107
2108        Map<String, String> siteParameters = m_site.getParameters();
2109        for (Entry<String, String> parameter : siteParameters.entrySet()) {
2110            addParameter(getParameterString(parameter));
2111        }
2112
2113        List<CmsSiteMatcher> siteAliases = m_site.getAliases();
2114
2115        for (CmsSiteMatcher siteMatcher : siteAliases) {
2116            if (enableAll) {
2117                m_aliasGroup.addRow(createAliasComponent(siteMatcher.getUrl(), siteMatcher.getRedirectMode()));
2118            } else {
2119                Component c = createAliasComponent(siteMatcher.getUrl(), siteMatcher.getRedirectMode());
2120                c.setEnabled(false);
2121                m_aliases.addComponent(c);
2122            }
2123        }
2124
2125        setTemplateField();
2126
2127        setUpComboBoxPosition();
2128
2129        if (!m_fieldSecureServer.isEmpty()) {
2130            m_fieldExclusiveURL.setEnabled(true && enableAll);
2131            m_fieldExclusiveError.setEnabled(true && enableAll);
2132        }
2133        setFaviconIfExist();
2134        checkOnOfflineSiteRoot();
2135        m_fieldUploadFavIcon.setVisible(false);
2136        m_simpleFieldEncryption.setContainerDataSource(getSSLModeContainer("caption", true, m_site.getSSLMode()));
2137        m_simpleFieldEncryption.select(m_site.getSSLMode());
2138        m_simpleFieldEncryption.setEnabled(enableAll);
2139
2140        m_fieldErrorPage.setEnabled(enableAll);
2141        m_addParameter.setVisible(enableAll);
2142        m_fieldPosition.setEnabled(enableAll);
2143
2144        fillAlternativeSiteRootTab(m_site.getAlternativeSiteRootMapping().orElse(null));
2145    }
2146
2147    /**
2148     * Sets the title field.<p>
2149     *
2150     * @param newValue value of the field.
2151     */
2152    private void setFieldTitle(String newValue) {
2153
2154        m_simpleFieldTitle.setValue(newValue);
2155    }
2156
2157    private void setTemplateFieldForSiteroot(String siteroot) {
2158
2159        try {
2160            CmsProperty prop = m_clonedCms.readPropertyObject(siteroot, CmsPropertyDefinition.PROPERTY_TEMPLATE, false);
2161            if (!prop.isNullProperty()) {
2162                if (!m_templates.contains(prop.getValue())) {
2163                    m_simpleFieldTemplate.addItem(prop.getValue());
2164                }
2165                m_simpleFieldTemplate.select(prop.getValue());
2166            } else {
2167                if (!m_templates.isEmpty()) {
2168                    m_simpleFieldTemplate.setValue(m_templates.get(0).getRootPath());
2169                }
2170            }
2171        } catch (CmsException e) {
2172            LOG.error("Unable to read template property.", e);
2173            m_simpleFieldTemplate.setValue(null);
2174        }
2175    }
2176
2177    /**
2178     * Set the combo box for the position.<p>
2179     * Copied from workplace tool.<p>
2180     */
2181    private void setUpComboBoxPosition() {
2182
2183        m_fieldPosition.removeAllItems();
2184
2185        List<CmsSite> sites = new ArrayList<CmsSite>();
2186        List<PositionComboBoxElementBean> beanList = new ArrayList<PositionComboBoxElementBean>();
2187        for (CmsSite site : OpenCms.getSiteManager().getAvailableSites(m_clonedCms, true)) {
2188            if (site.getSiteMatcher() != null) {
2189                sites.add(site);
2190            }
2191        }
2192
2193        float maxValue = 0;
2194        float nextPos = 0;
2195
2196        // calculate value for the first navigation position
2197        float firstValue = 1;
2198        if (sites.size() > 0) {
2199            try {
2200                maxValue = sites.get(0).getPosition();
2201            } catch (Exception e) {
2202                // should usually never happen
2203            }
2204        }
2205
2206        if (maxValue != 0) {
2207            firstValue = maxValue / 2;
2208        }
2209
2210        // add the first entry: before first element
2211        beanList.add(
2212            new PositionComboBoxElementBean(
2213                CmsVaadinUtils.getMessageText(Messages.GUI_SITE_CHNAV_POS_FIRST_0),
2214                firstValue));
2215
2216        // show all present navigation elements in box
2217        for (int i = 0; i < sites.size(); i++) {
2218
2219            float navPos = sites.get(i).getPosition();
2220            String siteRoot = sites.get(i).getSiteRoot();
2221            // get position of next nav element
2222            nextPos = navPos + 2;
2223            if ((i + 1) < sites.size()) {
2224                nextPos = sites.get(i + 1).getPosition();
2225            }
2226            // calculate new position of current nav element
2227            float newPos;
2228            if ((nextPos - navPos) > 1) {
2229                newPos = navPos + 1;
2230            } else {
2231                newPos = (navPos + nextPos) / 2;
2232            }
2233            // check new maxValue of positions and increase it
2234            if (navPos > maxValue) {
2235                maxValue = navPos;
2236            }
2237            // if the element is the current file, mark it in select box
2238            if ((m_site != null) && (m_site.getSiteRoot() != null) && m_site.getSiteRoot().equals(siteRoot)) {
2239                beanList.add(
2240                    new PositionComboBoxElementBean(
2241                        CmsVaadinUtils.getMessageText(Messages.GUI_SITE_CHNAV_POS_CURRENT_1, m_site.getTitle()),
2242                        -1));
2243            } else {
2244                beanList.add(new PositionComboBoxElementBean(sites.get(i).getTitle(), newPos));
2245            }
2246        }
2247
2248        // add the entry: at the last position
2249        PositionComboBoxElementBean lastEntry = new PositionComboBoxElementBean(
2250            CmsVaadinUtils.getMessageText(Messages.GUI_SITE_CHNAV_POS_LAST_0),
2251            maxValue + 1);
2252        beanList.add(lastEntry);
2253
2254        // add the entry: no change
2255        beanList.add(
2256            new PositionComboBoxElementBean(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_CHNAV_POS_NOCHANGE_0), -1));
2257
2258        BeanItemContainer<PositionComboBoxElementBean> objects = new BeanItemContainer<PositionComboBoxElementBean>(
2259            PositionComboBoxElementBean.class,
2260            beanList);
2261
2262        m_fieldPosition.setContainerDataSource(objects);
2263        m_fieldPosition.setItemCaptionPropertyId("title");
2264        m_fieldPosition.setValue(beanList.get(beanList.size() - 1));
2265        if (m_site == null) {
2266            m_fieldPosition.setValue(lastEntry);
2267        }
2268    }
2269
2270    /**
2271     * Sets up the ComboBox for the SSL Mode.<p>
2272     */
2273    private void setUpComboBoxSSL() {
2274
2275        IndexedContainer container = getSSLModeContainer("caption", true, null);
2276
2277        m_simpleFieldEncryption.setContainerDataSource(container);
2278        m_simpleFieldEncryption.setItemCaptionPropertyId("caption");
2279        m_simpleFieldEncryption.setNullSelectionAllowed(false);
2280        m_simpleFieldEncryption.setNewItemsAllowed(false);
2281        m_simpleFieldEncryption.select(CmsSSLMode.getDefault());
2282
2283        m_simpleFieldEncryption.addValueChangeListener(new ValueChangeListener() {
2284
2285            private static final long serialVersionUID = 3267990233897064320L;
2286
2287            public void valueChange(ValueChangeEvent event) {
2288
2289                if (m_blockChange) {
2290                    return;
2291                }
2292                handleSSLChange();
2293            }
2294        });
2295
2296        m_fieldSecureServer.setVisible(CmsSSLMode.getDefault().equals(CmsSSLMode.SECURE_SERVER));
2297        m_fieldExclusiveError.setVisible(CmsSSLMode.getDefault().equals(CmsSSLMode.SECURE_SERVER));
2298        m_fieldExclusiveURL.setVisible(CmsSSLMode.getDefault().equals(CmsSSLMode.SECURE_SERVER));
2299
2300    }
2301
2302    /**
2303     * Sets the combobox for the template.<p>
2304     */
2305    private void setUpComboBoxTemplate() {
2306
2307        try {
2308            I_CmsResourceType templateType = OpenCms.getResourceManager().getResourceType(
2309                CmsResourceTypeJsp.getContainerPageTemplateTypeName());
2310            m_templates = m_clonedCms.readResources("/system/", CmsResourceFilter.DEFAULT.addRequireType(templateType));
2311            for (CmsResource res : m_templates) {
2312                m_simpleFieldTemplate.addItem(res.getRootPath());
2313            }
2314
2315            if (!m_templates.isEmpty()) {
2316                m_simpleFieldTemplate.setValue(m_templates.get(0).getRootPath());
2317            }
2318
2319            m_simpleFieldTemplate.setNewItemsAllowed(true);
2320            m_simpleFieldTemplate.setNullSelectionAllowed(true);
2321
2322        } catch (CmsException e) {
2323            // should not happen
2324        }
2325    }
2326
2327    /**
2328     * Sets up the select box for the subsite selection mode.
2329     */
2330    private void setupSubsiteSelectionMode() {
2331
2332        m_subsiteSelectionEnabled.addItem(Boolean.FALSE);
2333        m_subsiteSelectionEnabled.addItem(Boolean.TRUE);
2334        m_subsiteSelectionEnabled.setValue(Boolean.FALSE);
2335        m_subsiteSelectionEnabled.setItemCaptionMode(ItemCaptionMode.EXPLICIT);
2336        m_subsiteSelectionEnabled.setNullSelectionAllowed(false);
2337        m_subsiteSelectionEnabled.setItemCaption(
2338            Boolean.FALSE,
2339            CmsVaadinUtils.getMessageText(Messages.GUI_SITE_SUBSITE_SELECTION_DISABLED_0));
2340        m_subsiteSelectionEnabled.setItemCaption(
2341            Boolean.TRUE,
2342            CmsVaadinUtils.getMessageText(Messages.GUI_SITE_SUBSITE_SELECTION_ENABLED_0));
2343    }
2344
2345    private void validateAndSubmit() {
2346
2347        setupValidators();
2348        setupValidatorAliase();
2349        if (isValidInputSimple()
2350            & isValidInputSiteTemplate()
2351            & isValidAliase()
2352            & isValidSecureServer()
2353            & isValidAltSiteRootSettings()) {
2354            submit();
2355            return;
2356        }
2357        if (!isValidInputSimple()) {
2358            m_tab.setSelectedTab(0);
2359        }
2360
2361        if (!isValidSecureServer()) {
2362            m_tab.setSelectedTab(1);
2363        }
2364
2365        if (!isValidAliase()) {
2366            m_tab.setSelectedTab(3);
2367        }
2368        if (!isValidAltSiteRootSettings()) {
2369            m_tab.setSelectedTab(4);
2370        }
2371
2372        if (!isValidInputSiteTemplate()) {
2373            m_tab.setSelectedTab(5);
2374        }
2375    }
2376}