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