001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.ui.apps.dbmanager; 029 030import org.opencms.db.CmsUserSettings; 031import org.opencms.file.CmsObject; 032import org.opencms.main.CmsException; 033import org.opencms.main.CmsLog; 034import org.opencms.main.OpenCms; 035import org.opencms.synchronize.CmsSynchronizeSettings; 036import org.opencms.ui.A_CmsUI; 037import org.opencms.ui.CmsVaadinUtils; 038import org.opencms.ui.apps.Messages; 039import org.opencms.ui.components.CmsRemovableFormRow; 040import org.opencms.ui.components.fileselect.CmsPathSelectField; 041 042import java.util.ArrayList; 043import java.util.HashSet; 044import java.util.List; 045import java.util.Set; 046 047import org.apache.commons.logging.Log; 048 049import com.vaadin.ui.Button; 050import com.vaadin.ui.Button.ClickEvent; 051import com.vaadin.ui.Component; 052import com.vaadin.ui.FormLayout; 053import com.vaadin.v7.data.Property.ValueChangeEvent; 054import com.vaadin.v7.data.Property.ValueChangeListener; 055import com.vaadin.v7.data.Validator; 056import com.vaadin.v7.ui.AbstractField; 057import com.vaadin.v7.ui.CheckBox; 058import com.vaadin.v7.ui.TextField; 059import com.vaadin.v7.ui.VerticalLayout; 060 061/** 062 * Synchronization layout class.<p> 063 */ 064public class CmsDbSynchronizationView extends VerticalLayout { 065 066 /** 067 * Validator for the resource fields.<p> 068 */ 069 class ResourceValidator implements Validator { 070 071 /**vaadin serial id.*/ 072 private static final long serialVersionUID = -1513193444185009615L; 073 074 /** 075 * @see com.vaadin.data.Validator#validate(java.lang.Object) 076 */ 077 public void validate(Object value) throws InvalidValueException { 078 079 String resourceName = (String)value; 080 if (synchroEnabled() & (resourceName == null)) { 081 throw new InvalidValueException( 082 CmsVaadinUtils.getMessageText(Messages.GUI_DATABASEAPP_SYNC_VALIDATION_EMPTY_RESOURCES_0)); 083 } 084 085 try { 086 m_cms.readResource(resourceName); 087 } catch (CmsException e) { 088 throw new InvalidValueException( 089 CmsVaadinUtils.getMessageText( 090 Messages.GUI_DATABASEAPP_SYNC_VALIDATION_RESOURCE_NOT_FOUND_1, 091 resourceName)); 092 } 093 } 094 } 095 096 /** 097 * Validator for the target.<p> 098 */ 099 class TargetValidator implements Validator { 100 101 /**vaadin serial id.*/ 102 private static final long serialVersionUID = 4404089964412111711L; 103 104 /** 105 * @see com.vaadin.data.Validator#validate(java.lang.Object) 106 */ 107 public void validate(Object value) throws InvalidValueException { 108 109 String val = (String)value; 110 if (synchroEnabled() & val.isEmpty()) { 111 throw new InvalidValueException( 112 CmsVaadinUtils.getMessageText(Messages.GUI_DATABASEAPP_SYNC_VALIDATION_EMPTY_TARGET_0)); 113 } 114 if (synchroEnabled()) { 115 try { 116 m_synchronizeSettings.setDestinationPathInRfs(val); 117 } catch (Throwable t) { 118 throw new InvalidValueException( 119 CmsVaadinUtils.getMessageText(Messages.GUI_DATABASEAPP_SYNC_VALIDATION_EMPTY_TARGET_0)); 120 } 121 } 122 } 123 124 } 125 126 /**vaadin serial id.*/ 127 private static final long serialVersionUID = -794938118093564562L; 128 129 /** The logger for this class. */ 130 static Log LOG = CmsLog.getLog(CmsDbSynchronizationView.class.getName()); 131 132 /** The synchronize settings which are edited on this dialog. */ 133 CmsSynchronizeSettings m_synchronizeSettings; 134 135 /**Vaadin component.*/ 136 private Button m_addResource; 137 138 /**Vaadin component.*/ 139 private Button m_ok; 140 141 /**Vaadin component.*/ 142 private FormLayout m_resources; 143 144 /**Root CmsObject. */ 145 protected CmsObject m_cms; 146 147 /**Vaadin component.*/ 148 private TextField m_target; 149 150 /**Vaadin component.*/ 151 private CheckBox m_enabled; 152 153 /**Instance of calling app.*/ 154 private CmsDbSynchronizationApp m_app; 155 156 /**Components which have to be validated.*/ 157 private Set<AbstractField<String>> m_componentsToValidate = new HashSet<AbstractField<String>>(); 158 159 /** 160 * Public constructor.<p> 161 * @param app instance of calling app 162 */ 163 public CmsDbSynchronizationView(CmsDbSynchronizationApp app) { 164 165 CmsVaadinUtils.readAndLocalizeDesign(this, CmsVaadinUtils.getWpMessagesForCurrentLocale(), null); 166 m_app = app; 167 m_componentsToValidate.add(m_target); 168 m_cms = initCms(A_CmsUI.getCmsObject()); 169 CmsUserSettings userSettings = new CmsUserSettings(m_cms); 170 171 m_synchronizeSettings = userSettings.getSynchronizeSettings(); 172 if (m_synchronizeSettings == null) { 173 m_synchronizeSettings = new CmsSynchronizeSettings(); 174 m_synchronizeSettings.setEnabled(false); 175 } 176 177 m_app.setRefreshButton(m_synchronizeSettings.isEnabled()); 178 179 initUI(); 180 181 m_target.addValueChangeListener(new ValueChangeListener() { 182 183 private static final long serialVersionUID = 5508413459469395463L; 184 185 public void valueChange(ValueChangeEvent event) { 186 187 setOkButtonEnabled(true); 188 189 } 190 }); 191 192 m_enabled.addValueChangeListener(new ValueChangeListener() { 193 194 private static final long serialVersionUID = -5921001488632416603L; 195 196 public void valueChange(ValueChangeEvent event) { 197 198 setOkButtonEnabled(true); 199 200 } 201 }); 202 203 m_addResource.addClickListener(new Button.ClickListener() { 204 205 private static final long serialVersionUID = 2169629308804189534L; 206 207 public void buttonClick(ClickEvent event) { 208 209 addResource(""); 210 } 211 }); 212 213 m_ok.addClickListener(new Button.ClickListener() { 214 215 private static final long serialVersionUID = -5083450266085163340L; 216 217 public void buttonClick(ClickEvent event) { 218 219 removeEmptyResourceFields(); 220 addValidators(); 221 if (isValid()) { 222 submit(); 223 setOkButtonEnabled(false); 224 } 225 } 226 }); 227 } 228 229 /** 230 * Adds a resource to form.<p> 231 * 232 * @param path of resource to add 233 */ 234 protected void addResource(String path) { 235 236 CmsPathSelectField field = new CmsPathSelectField(); 237 field.setCmsObject(m_cms); 238 field.setUseRootPaths(true); 239 field.setValue(path); 240 field.addValueChangeListener(new ValueChangeListener() { 241 242 private static final long serialVersionUID = 8646438704383992571L; 243 244 public void valueChange(ValueChangeEvent event) { 245 246 setOkButtonEnabled(true); 247 248 } 249 }); 250 m_componentsToValidate.add(field); 251 CmsRemovableFormRow<CmsPathSelectField> row = new CmsRemovableFormRow<CmsPathSelectField>( 252 field, 253 CmsVaadinUtils.getMessageText(Messages.GUI_DATABASEAPP_SYNC_REMOVE_RESOURCE_0)); 254 row.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_DATABASEAPP_SYNC_RESOURCE_0)); 255 row.setRemoveRunnable(new Runnable() { 256 257 public void run() { 258 259 setOkButtonEnabled(true); 260 } 261 }); 262 m_resources.addComponent(row); 263 } 264 265 /** 266 * Adds validators to the input fields.<p> 267 */ 268 protected void addValidators() { 269 270 m_target.removeAllValidators(); 271 m_target.addValidator(new TargetValidator()); 272 273 for (Component c : m_componentsToValidate) { 274 if (c instanceof CmsPathSelectField) { 275 ((CmsPathSelectField)c).removeAllValidators(); 276 ((CmsPathSelectField)c).addValidator(new ResourceValidator()); 277 } 278 } 279 } 280 281 /** 282 * Checks if synchronization is enabled.<p> 283 * 284 * @return true if synchronization is enabled, false otherwise 285 */ 286 protected boolean isEnabledSych() { 287 288 return m_synchronizeSettings.isEnabled(); 289 } 290 291 /** 292 * Checks if all fields are valid.<p> 293 * 294 * @return true if fields are valid 295 */ 296 protected boolean isValid() { 297 298 for (AbstractField<String> component : m_componentsToValidate) { 299 if (!component.isValid()) { 300 return false; 301 } 302 } 303 return true; 304 } 305 306 /** 307 * Removes empty resource fields.<p> 308 */ 309 protected void removeEmptyResourceFields() { 310 311 Set<Component> componentsToRemove = new HashSet<Component>(); 312 int count = 0; 313 Component lastElement = null; 314 315 for (Component c : m_resources) { 316 if (c instanceof CmsRemovableFormRow<?>) { 317 count++; 318 AbstractField<?> field = (AbstractField<?>)((CmsRemovableFormRow)c).getInput(); 319 String value = (String)(field.getValue()); 320 if (value.isEmpty()) { 321 componentsToRemove.add(c); 322 lastElement = c; 323 } 324 } 325 } 326 327 //if all fields are empty -> keep one of them to attach validator to 328 if (componentsToRemove.size() == count) { 329 componentsToRemove.remove(lastElement); 330 } 331 332 if (count == 0) { 333 addResource(""); 334 } 335 336 for (Component c : componentsToRemove) { 337 m_resources.removeComponent(c); 338 m_componentsToValidate.remove(c); 339 } 340 } 341 342 /** 343 * En/ Disables the ok button.<p> 344 * 345 * @param enable boolean indicates if button should be enabled 346 */ 347 protected void setOkButtonEnabled(boolean enable) { 348 349 m_ok.setEnabled(enable); 350 } 351 352 /** 353 * Submits the form.<p> 354 */ 355 protected void submit() { 356 357 m_synchronizeSettings.setEnabled(m_enabled.getValue().booleanValue()); 358 m_synchronizeSettings.setSourceListInVfs(getResourcePaths()); 359 try { 360 // set the synchronize settings 361 CmsUserSettings userSettings = new CmsUserSettings(A_CmsUI.getCmsObject()); 362 userSettings.setSynchronizeSettings(m_synchronizeSettings); 363 userSettings.save(A_CmsUI.getCmsObject()); 364 } catch (CmsException e) { 365 LOG.error("Unable to set synchro settings", e); 366 } 367 CmsUserSettings userSettings = new CmsUserSettings(A_CmsUI.getCmsObject()); 368 m_synchronizeSettings = userSettings.getSynchronizeSettings(); 369 m_app.setRefreshButton(m_synchronizeSettings.isEnabled()); 370 } 371 372 /** 373 * Is the enabled button clicked.<p> 374 * 375 * @return true, if synchro should be enabled 376 */ 377 protected boolean synchroEnabled() { 378 379 return m_enabled.getValue().booleanValue(); 380 } 381 382 /** 383 * Reads entered resources from form.<p> 384 * 385 * @return List of resource paths 386 */ 387 private List<String> getResourcePaths() { 388 389 List<String> res = new ArrayList<String>(); 390 for (Component c : m_resources) { 391 if (c instanceof CmsRemovableFormRow<?>) { 392 AbstractField<?> field = (AbstractField<?>)(((CmsRemovableFormRow)c).getInput()); 393 res.add((String)(field.getValue())); 394 } 395 } 396 return res; 397 } 398 399 /** 400 * Clones given CmsObject and switches to root site.<p> 401 * 402 * @param cms given CmsObject 403 * @return cloned CmsObject 404 */ 405 private CmsObject initCms(CmsObject cms) { 406 407 try { 408 cms = OpenCms.initCmsObject(cms); 409 } catch (CmsException e) { 410 LOG.error("Unable to init CmsObject"); 411 } 412 cms.getRequestContext().setSiteRoot(""); 413 return cms; 414 } 415 416 /** 417 * Initializes UI.<p> 418 */ 419 private void initUI() { 420 421 m_enabled.setValue(Boolean.valueOf(m_synchronizeSettings.isEnabled())); 422 if (m_synchronizeSettings.getDestinationPathInRfs() != null) { 423 m_target.setValue(m_synchronizeSettings.getDestinationPathInRfs()); 424 } 425 List<String> resources = m_synchronizeSettings.getSourceListInVfs(); 426 for (String resource : resources) { 427 addResource(resource); 428 } 429 setOkButtonEnabled(false); 430 } 431}