View Javadoc
1   /*
2    * Copyright (C) 2003-2011 eXo Platform SAS.
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Affero General Public License
6    * as published by the Free Software Foundation; either version 3
7    * of the License, or (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, see<http://www.gnu.org/licenses/>.
16   */
17  package org.exoplatform.wcm.webui.seo;
18  
19  import java.util.ArrayList;
20  import java.util.Collections;
21  import java.util.Comparator;
22  import java.util.Iterator;
23  import java.util.List;
24  import java.util.Locale;
25  import java.util.MissingResourceException;
26  import java.util.ResourceBundle;
27  
28  import javax.jcr.Node;
29  import javax.jcr.RepositoryException;
30  
31  import org.apache.commons.lang.StringUtils;
32  import org.exoplatform.container.ExoContainer;
33  import org.exoplatform.container.ExoContainerContext;
34  import org.exoplatform.portal.application.PortalRequestContext;
35  import org.exoplatform.portal.webui.util.Util;
36  import org.exoplatform.portal.webui.workspace.UIPortalApplication;
37  import org.exoplatform.services.log.ExoLogger;
38  import org.exoplatform.services.log.Log;
39  import org.exoplatform.services.resources.LocaleConfig;
40  import org.exoplatform.services.resources.LocaleConfigService;
41  import org.exoplatform.services.seo.PageMetadataModel;
42  import org.exoplatform.services.seo.SEOService;
43  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
44  import org.exoplatform.wcm.webui.validator.FloatNumberValidator;
45  import org.exoplatform.web.application.ApplicationMessage;
46  import org.exoplatform.web.url.navigation.NavigationResource;
47  import org.exoplatform.web.url.navigation.NodeURL;
48  import org.exoplatform.webui.application.WebuiRequestContext;
49  import org.exoplatform.webui.config.annotation.ComponentConfig;
50  import org.exoplatform.webui.config.annotation.EventConfig;
51  import org.exoplatform.webui.core.UIApplication;
52  import org.exoplatform.webui.core.UIPopupContainer;
53  import org.exoplatform.webui.core.lifecycle.UIFormLifecycle;
54  import org.exoplatform.webui.core.model.SelectItemOption;
55  import org.exoplatform.webui.event.Event;
56  import org.exoplatform.webui.event.Event.Phase;
57  import org.exoplatform.webui.event.EventListener;
58  import org.exoplatform.webui.form.UIForm;
59  import org.exoplatform.webui.form.UIFormSelectBox;
60  import org.exoplatform.webui.form.UIFormStringInput;
61  import org.exoplatform.webui.form.UIFormTextAreaInput;
62  import org.exoplatform.webui.form.input.UICheckBoxInput;
63  
64  
65  /**
66   * Created by The eXo Platform SAS
67   * Author : eXoPlatform
68   *          exo@exoplatform.com
69   * Jun 17, 2011
70   */
71  @ComponentConfig(lifecycle = UIFormLifecycle.class,
72  template = "classpath:groovy/webui/seo/UISEOForm.gtmpl",
73  events = {
74    @EventConfig(listeners = UISEOForm.SaveActionListener.class),
75    @EventConfig(phase=Phase.DECODE, listeners = UISEOForm.RefreshActionListener.class),
76    @EventConfig(phase=Phase.DECODE, listeners = UISEOForm.UpdateActionListener.class),
77    @EventConfig(listeners = UISEOForm.RemoveActionListener.class, confirm = "UISEOForm.msg.confirm-delete"),
78    @EventConfig(phase=Phase.DECODE, listeners = UISEOForm.CancelActionListener.class) })
79  
80  public class UISEOForm extends UIForm{
81  
82    public static final String TITLE                   = "title";
83    public static final String DESCRIPTION             = "description";
84    public static final String KEYWORDS                = "keywords";
85    final static public String LANGUAGE_TYPE           = "language" ;
86    public static final String ROBOTS                  = "robots";
87    public static final String SITEMAP                 = "sitemap";
88    public static final String ISINHERITED             = "isInherited";
89    public static final String SITEMAP_VISIBLE         = "sitemapvisible";
90    public static final String PRIORITY                = "priority";
91    public static final String FREQUENCY               = "frequency";
92    public static final String ROBOTS_INDEX            = "INDEX";
93    public static final String ROBOTS_FOLLOW           = "FOLLOW";
94    public static final String FREQUENCY_DEFAULT_VALUE = "Always";
95  
96    String title = "";
97    String description = "";
98    String keywords = "";
99    String priority = "";
100   String frequency = "";
101   String index = "";
102   String follow = "";
103   boolean sitemap = true;
104   boolean inherited = false;
105 
106   private static String contentPath = null;
107   private static String contentURI = null;
108   private boolean onContent = false;
109   private boolean isInherited = false;
110   private ArrayList<String> paramsArray = null;
111   public List<Locale> seoLocales;
112   public List<String> seoLanguages;
113   private String selectedLanguage;
114   private String defaultLanguage;
115   private boolean isAddNew = true;
116 
117   private static final Log LOG  = ExoLogger.getLogger(UISEOForm.class.getName());
118 
119   public String getContentPath() {
120     return this.contentPath;
121   }
122 
123   public void setContentPath(String contentPath) {
124     this.contentPath = contentPath;
125   }
126 
127   public String getContentURI() {
128     return this.contentURI;
129   }
130   public void setContentURI(String contentURI) {
131     this.contentURI = contentURI;
132   }
133 
134   public boolean getOnContent() {
135     return this.onContent;
136   }
137 
138   public void setOnContent(boolean onContent) {
139     this.onContent = onContent;
140   }
141 
142   public boolean getIsInherited() {
143     return this.isInherited;
144   }
145 
146   public void setIsInherited(boolean isInherited) {
147     this.isInherited = isInherited;
148   }
149 
150   public ArrayList<String> getParamsArray() {
151     return this.paramsArray;
152   }
153 
154   public void setSEOLocales(List<Locale> seoLocales) {
155     this.seoLocales = seoLocales;
156   }
157 
158   public List<Locale> getSEOLocales() {
159     return this.seoLocales;
160   }
161 
162   public List<String> getSeoLanguages() {
163     return seoLanguages;
164   }
165 
166   public void setSeoLanguages(List<String> seoLanguages) {
167     this.seoLanguages = seoLanguages;
168   }
169 
170   public void setParamsArray(ArrayList<String> params) {
171     this.paramsArray = params;
172   }
173 
174   public String getSelectedLanguage() {
175     return selectedLanguage;
176   }
177 
178   public void setSelectedLanguage(String selectedLanguage) {
179     this.selectedLanguage = selectedLanguage;
180   }
181 
182   public void setIsAddNew(boolean isAddNew) {
183     this.isAddNew = isAddNew;
184   }
185 
186   public boolean getIsAddNew() {
187     return this.isAddNew;
188   }
189 
190   public UISEOForm() throws Exception {
191     PortalRequestContext portalRequestContext = Util.getPortalRequestContext();
192     ExoContainer container = ExoContainerContext.getCurrentContainer() ;
193     SEOService seoService = container.getComponentInstanceOfType(SEOService.class);
194 
195     UIFormTextAreaInput uiTitle = new UIFormTextAreaInput(TITLE, TITLE, null);
196     uiTitle.setValue(title);
197     addUIFormInput(uiTitle);
198     UIFormTextAreaInput uiDescription = new UIFormTextAreaInput(DESCRIPTION, DESCRIPTION, null);
199     uiDescription.setValue(description);
200     addUIFormInput(uiDescription);
201 
202     UIFormTextAreaInput uiKeywords = new UIFormTextAreaInput(KEYWORDS, KEYWORDS, null);
203     uiKeywords.setValue(keywords);
204     addUIFormInput(uiKeywords);
205     seoLocales = seoService.getSEOLanguages(portalRequestContext.getPortalOwner(), contentPath, onContent);
206     seoLanguages = new ArrayList<>();
207     if(seoLocales != null && seoLocales.size() > 0) {
208       for (Locale locale : seoLocales) {
209         StringBuffer sb = new StringBuffer();
210         sb.append(locale.getLanguage());
211         String country = locale.getCountry();
212         if(StringUtils.isNotEmpty(country)) sb.append("_").append(country);
213         seoLanguages.add(sb.toString());
214       }
215     }
216 
217     if(seoLanguages != null) Collections.sort(seoLanguages);
218     UIFormSelectBox uiSelectForm = new UIFormSelectBox(LANGUAGE_TYPE, LANGUAGE_TYPE, getLanguages()) ;
219     uiSelectForm.setOnChange("Refresh");
220     defaultLanguage = portalRequestContext.getLocale().getLanguage();
221     if(StringUtils.isNotEmpty(portalRequestContext.getLocale().getCountry()))
222       defaultLanguage += "_" + portalRequestContext.getLocale().getCountry();
223     selectedLanguage = defaultLanguage;
224     if(seoLanguages == null || !seoLanguages.contains(defaultLanguage))
225       uiSelectForm.setValue(defaultLanguage);
226 
227     addUIFormInput(uiSelectForm) ;
228 
229     if(!onContent) {
230       List<SelectItemOption<String>> robotIndexItemOptions = new ArrayList<>();
231       List<String> robotsindexOptions = seoService.getRobotsIndexOptions();
232       List<String> robotsfollowOptions = seoService.getRobotsFollowOptions();
233       List<String> frequencyOptions = seoService.getFrequencyOptions();
234 
235       if(robotsindexOptions != null && robotsindexOptions.size() > 0) {
236         for(int i = 0; i < robotsindexOptions.size(); i++) {
237           robotIndexItemOptions.add(new SelectItemOption<>((robotsindexOptions.get(i).toString())));
238         }
239       }
240       UIFormSelectBox robots_index = new UIFormSelectBox(ROBOTS_INDEX, null, robotIndexItemOptions);
241       if(index != null && index.length() > 0)
242         robots_index.setValue(index);
243       else
244         robots_index.setValue(ROBOTS_INDEX);
245       addUIFormInput(robots_index);
246 
247 
248       List<SelectItemOption<String>> robotFollowItemOptions = new ArrayList<>();
249       if(robotsfollowOptions != null && robotsfollowOptions.size() > 0) {
250         for(int i = 0; i < robotsfollowOptions.size(); i++) {
251           robotFollowItemOptions.add(new SelectItemOption<>((robotsfollowOptions.get(i).toString())));
252         }
253       }
254       UIFormSelectBox robots_follow = new UIFormSelectBox(ROBOTS_FOLLOW, null, robotFollowItemOptions);
255       if(follow != null && follow.length() > 0)
256         robots_follow.setValue(follow);
257       else
258         robots_follow.setValue(ROBOTS_FOLLOW);
259       addUIFormInput(robots_follow);
260 
261       UICheckBoxInput visibleSitemapCheckbox = new UICheckBoxInput(SITEMAP, SITEMAP, sitemap);
262       addUIFormInput(visibleSitemapCheckbox);
263 
264       UIFormStringInput uiPrority = new UIFormStringInput(PRIORITY, null);
265       if(!StringUtils.isEmpty(priority)) uiPrority.setValue(priority);
266       addUIFormInput(uiPrority.addValidator(FloatNumberValidator.class));
267 
268       List<SelectItemOption<String>> frequencyItemOptions = new ArrayList<>();
269       if (frequencyOptions != null && frequencyOptions.size() > 0) {
270         for (int i = 0; i < frequencyOptions.size(); i++) {
271           frequencyItemOptions.add(new SelectItemOption<>(frequencyOptions.get(i).toString(),
272               (frequencyOptions.get(i).toString())));
273         }
274       }
275       UIFormSelectBox frequencySelectbox = new UIFormSelectBox(FREQUENCY, null, frequencyItemOptions);
276       if(frequency != null && frequency.length() > 0)
277         frequencySelectbox.setValue(frequency);
278       else
279         frequencySelectbox.setValue(FREQUENCY_DEFAULT_VALUE);
280       addUIFormInput(frequencySelectbox);
281     }
282 
283 
284     setActions(new String[]{"Save", "Cancel"});
285   }
286 
287   public void initSEOForm(PageMetadataModel pageModel) throws Exception{
288     PortalRequestContext portalRequestContext = Util.getPortalRequestContext();
289     if(pageModel != null) {
290       title = pageModel.getTitle();
291       description = pageModel.getDescription();
292       keywords = pageModel.getKeywords();
293       frequency = pageModel.getFrequency();
294       if(pageModel.getPriority() >= 0)
295         priority = String.valueOf(pageModel.getPriority());
296       else priority = null;
297       if(pageModel.getRobotsContent() != null && pageModel.getRobotsContent().length() > 0) {
298         index = pageModel.getRobotsContent().split(",")[0].trim();
299         follow = pageModel.getRobotsContent().split(",")[1].trim();
300       }
301       sitemap = pageModel.getSitemap();
302     } else {
303       if(!onContent)
304         title = portalRequestContext.getTitle();
305       else title = "";
306       description = "";
307       keywords = "";
308       priority = "";
309       frequency = "";
310       index = "";
311       follow = "";
312       sitemap = true;
313     }
314 
315     ExoContainer container = ExoContainerContext.getCurrentContainer() ;
316     SEOService seoService = (SEOService)container.getComponentInstanceOfType(SEOService.class);
317 
318     UIFormTextAreaInput uiTitle = this.getUIFormTextAreaInput(TITLE);
319     if(uiTitle != null) uiTitle.setValue(title);
320 
321     UIFormTextAreaInput uiDescription = this.getUIFormTextAreaInput(DESCRIPTION);
322     if(uiDescription != null) uiDescription.setValue(description);
323 
324     UIFormTextAreaInput uiKeywords = this.getUIFormTextAreaInput(KEYWORDS);
325     if(uiKeywords != null) uiKeywords.setValue(keywords);
326 
327     UIFormSelectBox uiSelectForm = this.getUIFormSelectBox(LANGUAGE_TYPE);
328     uiSelectForm.setSelectedValues(new String[] {"language"});
329     if(uiSelectForm != null) {
330       seoLocales = seoService.getSEOLanguages(portalRequestContext.getPortalOwner(), contentPath, onContent);
331       seoLanguages = new ArrayList<>();
332       if(seoLocales != null && seoLocales.size() > 0) {
333         for (Locale locale : seoLocales) {
334           StringBuffer sb = new StringBuffer();
335           sb.append(locale.getLanguage());
336           String country = locale.getCountry();
337           if(StringUtils.isNotEmpty(country)) sb.append("_").append(country);
338           seoLanguages.add(sb.toString());
339         }
340       }
341       if(seoLanguages.size() <= 0) setSelectedLanguage(null);
342       List<SelectItemOption<String>> languages = getLanguages();
343       if(languages.size() == 1) this.setIsAddNew(false);
344       else this.setIsAddNew(true);
345       uiSelectForm.setOptions(languages);
346       uiSelectForm.setValue(selectedLanguage);
347     }
348 
349     if(!onContent) {
350       List<SelectItemOption<String>> robotIndexItemOptions = new ArrayList<>();
351       List<String> robotsindexOptions = seoService.getRobotsIndexOptions();
352       List<String> robotsfollowOptions = seoService.getRobotsFollowOptions();
353       List<String> frequencyOptions = seoService.getFrequencyOptions();
354 
355       if(robotsindexOptions != null && robotsindexOptions.size() > 0) {
356         for(int i = 0; i < robotsindexOptions.size(); i++) {
357           robotIndexItemOptions.add(new SelectItemOption<>((robotsindexOptions.get(i).toString())));
358         }
359       }
360       UIFormSelectBox robots_index = this.getUIFormSelectBox(ROBOTS_INDEX);
361       if(robots_index != null) {
362         if(index != null && index.length() > 0)
363           robots_index.setValue(index);
364         else
365           robots_index.setValue(ROBOTS_INDEX);
366       }
367 
368       List<SelectItemOption<String>> robotFollowItemOptions = new ArrayList<>();
369       if(robotsfollowOptions != null && robotsfollowOptions.size() > 0) {
370         for(int i = 0; i < robotsfollowOptions.size(); i++) {
371           robotFollowItemOptions.add(new SelectItemOption<>((robotsfollowOptions.get(i).toString())));
372         }
373       }
374       UIFormSelectBox robots_follow = this.getUIFormSelectBox(ROBOTS_FOLLOW);
375       if(robots_follow != null) {
376         if(follow != null && follow.length() > 0)
377           robots_follow.setValue(follow);
378         else
379           robots_follow.setValue(ROBOTS_FOLLOW);
380       }
381 
382       UICheckBoxInput visibleSitemapCheckbox = this.getUICheckBoxInput(SITEMAP);
383       if(visibleSitemapCheckbox != null) visibleSitemapCheckbox.setChecked(sitemap);
384 
385 
386       UIFormStringInput uiPrority = this.getUIStringInput(PRIORITY);
387       if(uiPrority != null) {
388         if(!StringUtils.isEmpty(priority)) uiPrority.setValue(priority);
389         else uiPrority.setValue("");
390       }
391 
392 
393       List<SelectItemOption<String>> frequencyItemOptions = new ArrayList<>();
394       if (frequencyOptions != null && frequencyOptions.size() > 0) {
395         for (int i = 0; i < frequencyOptions.size(); i++) {
396           frequencyItemOptions.add(new SelectItemOption<>(frequencyOptions.get(i).toString(),
397               (frequencyOptions.get(i).toString())));
398         }
399       }
400       UIFormSelectBox frequencySelectbox = this.getUIFormSelectBox(FREQUENCY);
401       if(frequencySelectbox != null) {
402         if(frequency != null && frequency.length() > 0)
403           frequencySelectbox.setValue(frequency);
404         else
405           frequencySelectbox.setValue(FREQUENCY_DEFAULT_VALUE);
406       }
407     }
408   }
409 
410 
411   public static class SaveActionListener extends EventListener<UISEOForm> {
412 
413     public void execute(Event<UISEOForm> event) throws Exception {
414       UISEOForm uiForm = event.getSource();
415       UIApplication uiApp = uiForm.getAncestorOfType(UIApplication.class) ;
416       String description = uiForm.getUIFormTextAreaInput(DESCRIPTION).getValue();
417       String keywords = uiForm.getUIFormTextAreaInput(KEYWORDS).getValue() ;
418       PortalRequestContext portalRequestContext = Util.getPortalRequestContext();
419       String lang = null;
420       if(uiForm.getSelectedLanguage() != null) lang = uiForm.getSelectedLanguage();
421       else {
422         lang = uiForm.getUIFormSelectBox(LANGUAGE_TYPE).getValue() ;
423         StringBuffer sb = new StringBuffer();        
424         if(lang == null || lang.equals(LANGUAGE_TYPE)) {
425           lang = portalRequestContext.getLocale().getLanguage();
426           sb.append(portalRequestContext.getLocale().getLanguage());
427           if(StringUtils.isNotEmpty(portalRequestContext.getLocale().getCountry()))
428             sb.append("_").append(portalRequestContext.getLocale().getCountry());
429           lang = sb.toString();
430         }
431       }
432       uiForm.setSelectedLanguage(lang);
433       String portalName = portalRequestContext.getPortalOwner();
434       String uri = portalRequestContext.createURL(NodeURL.TYPE, new NavigationResource(Util.getUIPortal().getSelectedUserNode())).toString();
435       String fullStatus = null;
436       String pageReference = Util.getUIPortal().getSelectedUserNode().getPageRef().format();
437 
438       if(!uiForm.onContent) {
439         String title = uiForm.getUIFormTextAreaInput(TITLE).getValue();
440         String robots_index = uiForm.getUIFormSelectBox(ROBOTS_INDEX).getValue() ;
441         String robots_follow = uiForm.getUIFormSelectBox(ROBOTS_FOLLOW).getValue() ;
442         String rebots_content = robots_index + ", " + robots_follow;
443         boolean isVisibleSitemap = uiForm.getUICheckBoxInput(SITEMAP).isChecked();
444         float priority = -1;
445         if(uiForm.getUIStringInput(PRIORITY).getValue() != null && uiForm.getUIStringInput(PRIORITY).getValue().length() > 0) {
446           priority = Float.parseFloat(uiForm.getUIStringInput(PRIORITY).getValue()) ;
447           if(priority < 0.0 || priority > 1.0) {
448             uiApp.addMessage(new ApplicationMessage("FloatNumberValidator.msg.Invalid-number", null, ApplicationMessage.WARNING));
449             return;
450           }
451         }
452         String frequency = uiForm.getUIFormSelectBox(FREQUENCY).getValue() ;
453         try {
454           PageMetadataModel metaModel = new PageMetadataModel();
455           metaModel.setTitle(title);
456           metaModel.setDescription(description);
457           metaModel.setFrequency(frequency);
458           metaModel.setKeywords(keywords);
459           metaModel.setPriority(priority);
460           metaModel.setRobotsContent(rebots_content);
461           metaModel.setSiteMap(isVisibleSitemap);
462           metaModel.setUri(uri);
463           metaModel.setPageReference(pageReference);
464           if(description!= null && keywords != null && priority != -1)
465             fullStatus = "Full";
466           else fullStatus = "Partial";
467           metaModel.setFullStatus(fullStatus);
468 
469           SEOService seoService = uiForm.getApplicationComponent(SEOService.class);
470           seoService.storeMetadata(metaModel, portalName, uiForm.onContent, uiForm.getSelectedLanguage());
471           uiForm.initSEOForm(metaModel);
472           if(uiForm.getAncestorOfType(UISEOToolbarPortlet.class) != null)
473             event.getRequestContext().addUIComponentToUpdateByAjax(uiForm.getAncestorOfType(UISEOToolbarPortlet.class)) ;
474           else {
475             event.getRequestContext().addUIComponentToUpdateByAjax(uiForm);
476             event.getRequestContext().addUIComponentToUpdateByAjax(uiForm.getAncestorOfType(UIPopupContainer.class).getParent());
477           }
478         } catch (Exception ex) {
479           if (LOG.isErrorEnabled()) {
480             LOG.error("Unexpected error ", ex);
481           }
482           uiApp.addMessage(new ApplicationMessage("UISEOForm.msg.repository-exception",
483                                                   null,
484                                                   ApplicationMessage.ERROR));
485           return;
486         }
487       } else {
488         try {
489           PageMetadataModel metaModel = new PageMetadataModel();
490           metaModel.setDescription(description);
491           metaModel.setKeywords(keywords);
492           metaModel.setUri(uri);
493           metaModel.setPageReference(pageReference);
494           if(description != null && keywords != null)
495             fullStatus = "Full";
496           else fullStatus = "Partial";
497           metaModel.setFullStatus(fullStatus);
498           SEOService seoService = uiForm.getApplicationComponent(SEOService.class);
499           Node contentNode = null;
500           for(int i=0;i<uiForm.paramsArray.size(); i++) {
501             String contentPath = uiForm.paramsArray.get(i).toString();
502             contentNode = seoService.getContentNode(contentPath);
503             if(contentNode != null) break;
504           }
505           metaModel.setUri(contentNode.getUUID());
506           seoService.storeMetadata(metaModel, portalName, uiForm.onContent, uiForm.getSelectedLanguage());
507           uiForm.initSEOForm(metaModel);
508           if(uiForm.getAncestorOfType(UISEOToolbarPortlet.class) != null)
509             event.getRequestContext().addUIComponentToUpdateByAjax(uiForm.getAncestorOfType(UISEOToolbarPortlet.class)) ;
510           else {
511             event.getRequestContext().addUIComponentToUpdateByAjax(uiForm);
512             event.getRequestContext().addUIComponentToUpdateByAjax(uiForm.getAncestorOfType(UIPopupContainer.class).getParent());
513           }
514         } catch (RepositoryException ex) {
515           if (LOG.isErrorEnabled()) {
516             LOG.error("Unexpected error ", ex);
517           }
518           uiApp.addMessage(new ApplicationMessage("UISEOForm.msg.repository-exception",
519                                                   null,
520                                                   ApplicationMessage.ERROR));
521           return;
522         }
523       }
524     }
525   }
526 
527   public static class CancelActionListener extends EventListener<UISEOForm> {
528     public void execute(Event<UISEOForm> event) throws Exception {
529       UISEOForm uiSEO = event.getSource();
530       UIPopupContainer uiSEOToolbar = uiSEO.getAncestorOfType(UIPopupContainer.class);
531       if(uiSEOToolbar != null)
532         uiSEOToolbar.removeChildById(UISEOToolbarForm.SEO_POPUP_WINDOW);
533     }
534   }
535 
536   public static class RefreshActionListener extends EventListener<UISEOForm> {
537     public void execute(Event<UISEOForm> event) throws Exception {
538       PortalRequestContext portalRequestContext = Util.getPortalRequestContext();
539       UISEOForm uiForm = event.getSource();
540       String portalName = portalRequestContext.getPortalOwner();
541       String lang = uiForm.getUIFormSelectBox(LANGUAGE_TYPE).getValue();
542       if(lang.equals("language")) return;
543       uiForm.setSelectedLanguage(lang);
544       String pageReference = Util.getUIPortal().getSelectedUserNode().getPageRef().format();
545       SEOService seoService = uiForm.getApplicationComponent(SEOService.class);
546       PageMetadataModel seoData = new PageMetadataModel();
547       PageMetadataModel metaModel = seoService.getMetadata(uiForm.paramsArray, pageReference, uiForm.defaultLanguage);
548       if(metaModel == null) metaModel = new PageMetadataModel();
549 
550       if(uiForm.onContent) {
551         seoData.setUri(uiForm.getContentURI());
552         metaModel.setUri(uiForm.getContentURI());
553       } else {
554         seoData.setPageReference(pageReference);
555         seoData.setTitle(portalRequestContext.getTitle());
556         metaModel.setTitle(portalRequestContext.getTitle());
557       }
558 
559       seoData.setFullStatus("Empty");
560       seoService.storeMetadata(seoData, portalName, uiForm.onContent, lang);
561       uiForm.initSEOForm(metaModel);
562       event.getRequestContext().addUIComponentToUpdateByAjax(uiForm) ;
563     }
564   }
565 
566   public static class UpdateActionListener extends EventListener<UISEOForm> {
567     public void execute(Event<UISEOForm> event) throws Exception {
568       UISEOForm uiForm = event.getSource();
569       String lang = event.getRequestContext().getRequestParameter(OBJECTID) ;
570       uiForm.setSelectedLanguage(lang);
571       SEOService seoService = uiForm.getApplicationComponent(SEOService.class);
572       String pageReference = Util.getUIPortal().getSelectedUserNode().getPageRef().format();
573       PageMetadataModel metaModel = seoService.getMetadata(uiForm.paramsArray, pageReference, lang);
574       if(metaModel == null || (metaModel != null && metaModel.getFullStatus().equals("Empty"))) {
575         metaModel = seoService.getMetadata(uiForm.paramsArray, pageReference, uiForm.defaultLanguage);
576       }
577       uiForm.initSEOForm(metaModel);
578       event.getRequestContext().addUIComponentToUpdateByAjax(uiForm) ;
579     }
580   }
581 
582 
583   public static class RemoveActionListener extends EventListener<UISEOForm> {
584     public void execute(Event<UISEOForm> event) throws Exception {
585       UISEOForm uiForm = event.getSource();
586       PortalRequestContext portalRequestContext = Util.getPortalRequestContext();
587       String lang = event.getRequestContext().getRequestParameter(OBJECTID) ;
588       SEOService seoService = uiForm.getApplicationComponent(SEOService.class);
589       PageMetadataModel metaModel = new PageMetadataModel();
590       String pageReference = Util.getUIPortal().getSelectedUserNode().getPageRef().format();
591       metaModel.setPageReference(pageReference);
592       if(uiForm.onContent) {
593         Node contentNode = null;
594         for(int i=0;i<uiForm.paramsArray.size(); i++) {
595           String contentPath = uiForm.paramsArray.get(i).toString();
596           contentNode = seoService.getContentNode(contentPath);
597           if(contentNode != null) break;
598         }
599         if(contentNode != null) metaModel.setUri(contentNode.getUUID());
600       }
601       String portalName = portalRequestContext.getPortalOwner();
602       seoService.removePageMetadata(metaModel, portalName, uiForm.onContent, lang);
603       uiForm.setSEOLocales(seoService.getSEOLanguages(portalRequestContext.getPortalOwner(), contentPath, uiForm.onContent));
604       List<String> seoLanguages = new ArrayList<>();
605       for (Locale locale : uiForm.getSEOLocales()) {
606         StringBuffer sb = new StringBuffer();
607         sb.append(locale.getLanguage());
608         String country = locale.getCountry();
609         if(StringUtils.isNotEmpty(country)) sb.append("_").append(country);
610         seoLanguages.add(sb.toString());
611       }
612       uiForm.setSeoLanguages(seoLanguages);
613       String laguageFocus = uiForm.defaultLanguage;
614       if(seoLanguages.size()> 0 && !seoLanguages.contains(uiForm.defaultLanguage))
615         laguageFocus = seoLanguages.get(0);
616       metaModel = seoService.getMetadata(uiForm.paramsArray, pageReference, laguageFocus);
617       if(metaModel != null) uiForm.setSelectedLanguage(laguageFocus);
618       else uiForm.getUIFormSelectBox(LANGUAGE_TYPE).setValue(uiForm.defaultLanguage);
619       uiForm.initSEOForm(metaModel);
620 
621       if(uiForm.getAncestorOfType(UISEOToolbarPortlet.class) != null)
622         event.getRequestContext().addUIComponentToUpdateByAjax(uiForm.getAncestorOfType(UISEOToolbarPortlet.class)) ;
623       else {
624         event.getRequestContext().addUIComponentToUpdateByAjax(uiForm);
625         event.getRequestContext().addUIComponentToUpdateByAjax(uiForm.getAncestorOfType(UIPopupContainer.class).getParent());
626       }
627     }
628   }
629   public List<SelectItemOption<String>> getLanguages() throws Exception {
630     WebuiRequestContext rc = WebuiRequestContext.getCurrentInstance();
631     Locale inLocale = WebuiRequestContext.getCurrentInstance().getLocale();
632     // Get default locale
633     Locale defaultLocale = Locale.getDefault();
634     // set default locale to current user selected language
635     Locale.setDefault(Util.getUIPortal().getAncestorOfType(UIPortalApplication.class).getLocale());
636 
637     LocaleConfigService localService = WCMCoreUtils.getService(LocaleConfigService.class) ;
638     List<SelectItemOption<String>> languages = new ArrayList<>() ;
639     Iterator<LocaleConfig> iter = localService.getLocalConfigs().iterator() ;
640     ResourceBundle resourceBundle = rc.getApplicationResourceBundle();
641     while (iter.hasNext()) {
642       LocaleConfig localConfig = iter.next() ;
643       Locale locale = localConfig.getLocale();
644       StringBuffer sb = new StringBuffer();
645       sb.append(locale.getLanguage());
646       String country = locale.getCountry();
647       if(StringUtils.isNotEmpty(country)) sb.append("_").append(country);
648       String lang = sb.toString();
649       if(seoLanguages == null || !seoLanguages.contains(lang)) {
650         try {
651           languages.add(new SelectItemOption<>(CapitalFirstLetters(locale.getDisplayName(inLocale)), lang)) ;
652         } catch(MissingResourceException mre) {
653           languages.add(new SelectItemOption<>(lang, lang)) ;
654         }
655       }
656     }
657 
658     // Set back to the default locale
659     Locale.setDefault(defaultLocale);
660     Collections.sort(languages, new ItemOptionComparator());
661     languages.add(0,new SelectItemOption<>(getLabel(resourceBundle, "select-language"), "language")) ;
662     return languages ;
663   }
664 
665   public String CapitalFirstLetters(String str) {
666     str = Character.toString(str.charAt(0)).toUpperCase()+str.substring(1);
667     return str;
668   }
669 
670   class ItemOptionComparator implements Comparator<SelectItemOption<String>> {
671     @Override
672     public int compare(SelectItemOption<String> o1, SelectItemOption<String> o2) {
673       return o1.getLabel().compareTo(o2.getLabel());
674     }
675   }
676   class SEOItemComparator implements Comparator<Locale> {
677     @Override
678     public int compare(Locale locale1, Locale locale2) {
679       return locale1.getDisplayLanguage().compareTo(locale2.getDisplayLanguage());
680     }
681   }
682 }