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