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.user; 029 030import org.opencms.file.CmsObject; 031import org.opencms.file.CmsResource; 032import org.opencms.main.CmsException; 033import org.opencms.main.CmsIllegalArgumentException; 034import org.opencms.main.CmsLog; 035import org.opencms.main.OpenCms; 036import org.opencms.security.CmsDefaultValidationHandler; 037import org.opencms.security.CmsOrganizationalUnit; 038import org.opencms.ui.A_CmsUI; 039import org.opencms.ui.CmsVaadinUtils; 040import org.opencms.ui.apps.Messages; 041import org.opencms.ui.components.CmsBasicDialog; 042import org.opencms.ui.components.editablegroup.CmsEditableGroup; 043import org.opencms.ui.components.editablegroup.I_CmsEditableGroupRow; 044import org.opencms.ui.components.fileselect.CmsPathSelectField; 045import org.opencms.util.CmsFileUtil; 046 047import java.util.ArrayList; 048import java.util.Collections; 049import java.util.Iterator; 050import java.util.List; 051 052import org.apache.commons.logging.Log; 053 054import com.google.common.base.Supplier; 055import com.vaadin.ui.Button; 056import com.vaadin.ui.Button.ClickEvent; 057import com.vaadin.ui.Button.ClickListener; 058import com.vaadin.ui.Component; 059import com.vaadin.ui.FormLayout; 060import com.vaadin.ui.Window; 061import com.vaadin.v7.data.Property.ValueChangeEvent; 062import com.vaadin.v7.data.Property.ValueChangeListener; 063import com.vaadin.v7.data.Validator; 064import com.vaadin.v7.ui.AbstractField; 065import com.vaadin.v7.ui.CheckBox; 066import com.vaadin.v7.ui.Label; 067import com.vaadin.v7.ui.TextArea; 068import com.vaadin.v7.ui.TextField; 069 070/** 071 * Class for the ou edit and new dialog.<p> 072 */ 073public class CmsOUEditDialog extends CmsBasicDialog { 074 075 /** 076 * Validator for ou name.<p> 077 */ 078 protected class NameValidator implements Validator { 079 080 /**vaadin serial id. */ 081 private static final long serialVersionUID = 6830449175508751039L; 082 083 /** 084 * @see com.vaadin.data.Validator#validate(java.lang.Object) 085 */ 086 public void validate(Object value) throws InvalidValueException { 087 088 try { 089 CmsDefaultValidationHandler handler = new CmsDefaultValidationHandler(); 090 handler.checkUserName((String)value); 091 } catch (CmsIllegalArgumentException e) { 092 throw new InvalidValueException( 093 CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_USER_VALIDATION_LOGINNAME_INVALID_0)); 094 } 095 096 } 097 098 } 099 100 /** 101 * Validator for resource names.<p> 102 */ 103 protected class ResourceValidator implements Validator { 104 105 /**vaadin serial id. */ 106 private static final long serialVersionUID = -2325058988240648143L; 107 108 /** 109 * @see com.vaadin.data.Validator#validate(java.lang.Object) 110 */ 111 public void validate(Object value) throws InvalidValueException { 112 113 if (isInvalidResourceName((String)value)) { 114 throw new InvalidValueException( 115 CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_OU_RESOURCE_NOT_VALID_0)); 116 } 117 118 if (isOutOfOu((String)value)) { 119 throw new InvalidValueException( 120 CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_OU_RESOURCE_OUT_OF_OU_0)); 121 } 122 123 } 124 } 125 126 /**vaadim serial id. */ 127 private static final long serialVersionUID = -1462196157732607548L; 128 129 /** The logger for this class. */ 130 static Log LOG = CmsLog.getLog(CmsOUEditDialog.class.getName()); 131 132 /**CmsObject. */ 133 protected CmsObject m_cms; 134 135 /**OU to be edited, null if new one should be created. */ 136 private CmsOrganizationalUnit m_ou; 137 138 /**vaadin component.*/ 139 Button m_ok; 140 141 /**vaadin component.*/ 142 private TextField m_name; 143 144 /**vaadin component.*/ 145 private Button m_cancel; 146 147 /**vaadin component.*/ 148 private TextArea m_description; 149 150 /**vaadin component.*/ 151 Label m_parentOu; 152 153 /**vaadin component.*/ 154 private CheckBox m_hideLogin; 155 156 /**vaadin component.*/ 157 private CheckBox m_webuser; 158 159 /**vaadin component.*/ 160 private FormLayout m_resLayout; 161 162 /** The group for the module resource fields. */ 163 private CmsEditableGroup m_ouResources; 164 165 /** 166 * public constructor.<p> 167 * 168 * @param cms CmsObject 169 * @param ou id of group edit, null if ou should be created 170 * @param window window holding the dialog 171 * @param app 172 */ 173 public CmsOUEditDialog(CmsObject cms, String ou, final Window window, final CmsAccountsApp app) { 174 175 CmsVaadinUtils.readAndLocalizeDesign(this, CmsVaadinUtils.getWpMessagesForCurrentLocale(), null); 176 177 if (ou != null) { 178 try { 179 displayResourceInfoDirectly( 180 Collections.singletonList( 181 CmsAccountsApp.getOUInfo( 182 OpenCms.getOrgUnitManager().readOrganizationalUnit(A_CmsUI.getCmsObject(), ou)))); 183 } catch (CmsException e1) { 184 LOG.error("Unable to read OU", e1); 185 } 186 } 187 188 m_cms = cms; 189 Supplier<Component> fieldFactory = new Supplier<Component>() { 190 191 public Component get() { 192 193 CmsPathSelectField field = new CmsPathSelectField(); 194 field.setUseRootPaths(true); 195 field.setCmsObject(m_cms); 196 try { 197 field.setValue( 198 OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(m_cms, m_parentOu.getValue()).get( 199 0).getRootPath()); 200 } catch (CmsException e) { 201 // 202 } 203 return field; 204 } 205 }; 206 m_ouResources = new CmsEditableGroup( 207 m_resLayout, 208 fieldFactory, 209 CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_OU_ADD_RESOURCE_0)); 210 m_ouResources.init(); 211 212 try { 213 if (ou != null) { 214 m_ou = OpenCms.getOrgUnitManager().readOrganizationalUnit(m_cms, ou); 215 m_name.setEnabled(false); 216 m_name.setValue(m_ou.getName()); 217 m_description.setValue(m_ou.getDescription()); 218 m_parentOu.setValue(m_ou.getParentFqn().equals("") ? "/" : m_ou.getParentFqn()); 219 m_hideLogin.setValue(Boolean.valueOf(m_ou.hasFlagHideLogin())); 220 m_webuser.setValue(Boolean.valueOf(m_ou.hasFlagWebuser())); 221 m_webuser.setEnabled(false); 222 for (CmsResource resource : OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit( 223 m_cms, 224 m_ou.getName())) { 225 CmsPathSelectField field = new CmsPathSelectField(); 226 field.setValue(resource.getRootPath()); 227 field.setUseRootPaths(true); 228 field.setCmsObject(m_cms); 229 m_ouResources.addRow(field); 230 } 231 } 232 233 } catch (CmsException e) { 234 LOG.error("unable to read group", e); 235 } 236 m_ok.setEnabled(m_ou != null); 237 m_ok.addClickListener(new ClickListener() { 238 239 private static final long serialVersionUID = 2337532424806798793L; 240 241 public void buttonClick(ClickEvent event) { 242 243 validate(); 244 if (isValid()) { 245 saveOU(); 246 window.close(); 247 app.reload(); 248 } 249 } 250 }); 251 252 m_cancel.addClickListener(new ClickListener() { 253 254 private static final long serialVersionUID = -6389260624197980323L; 255 256 public void buttonClick(ClickEvent event) { 257 258 window.close(); 259 } 260 }); 261 262 ValueChangeListener listener = new ValueChangeListener() { 263 264 private static final long serialVersionUID = -7480617292190495288L; 265 266 public void valueChange(ValueChangeEvent event) { 267 268 m_ok.setEnabled(true); 269 } 270 }; 271 272 m_description.addValueChangeListener(listener); 273 m_name.addValueChangeListener(listener); 274 } 275 276 /** 277 * public constructor.<p> 278 * 279 * @param cms CmsObject 280 * @param window window holding dialog 281 * @param ou to create group in 282 */ 283 public CmsOUEditDialog(CmsObject cms, Window window, String ou, CmsAccountsApp app) { 284 285 this(cms, null, window, app); 286 m_parentOu.setValue(ou.equals("") ? "/" : ou); 287 try { 288 displayResourceInfoDirectly( 289 Collections.singletonList( 290 CmsAccountsApp.getOUInfo( 291 OpenCms.getOrgUnitManager().readOrganizationalUnit( 292 A_CmsUI.getCmsObject(), 293 m_parentOu.getValue())))); 294 } catch (CmsException e1) { 295 LOG.error("Unable to read OU", e1); 296 } 297 298 CmsPathSelectField field = new CmsPathSelectField(); 299 field.setUseRootPaths(true); 300 field.setCmsObject(m_cms); 301 try { 302 field.setValue(OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou).get(0).getRootPath()); 303 } catch (Throwable e) { 304 // We simply do not set the field's value if something goes wrong. 305 } 306 m_ouResources.addRow(field); 307 } 308 309 /** 310 * Checks if given resource is invalid.<p> 311 * 312 * @param resourceName name of resource 313 * @return true if resourceName is invalid 314 */ 315 protected boolean isInvalidResourceName(String resourceName) { 316 317 if (resourceName == null) { 318 return true; 319 } 320 try { 321 322 m_cms.readResource(resourceName); 323 return false; 324 } catch (CmsException e) { 325 //Ok, resource not valid.. 326 } 327 return true; 328 } 329 330 /** 331 * Check if resource is in parent OU.<p> 332 * 333 * @param resourceName to check 334 * @return boolean 335 */ 336 protected boolean isOutOfOu(String resourceName) { 337 338 if (resourceName == null) { 339 return true; 340 } 341 try { 342 boolean notOk = true; 343 for (CmsResource res : OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit( 344 m_cms, 345 m_parentOu.getValue())) { 346 if (resourceName.startsWith(res.getRootPath())) { 347 notOk = false; 348 } 349 } 350 return notOk; 351 } catch (CmsException e) { 352 // 353 } 354 return true; 355 } 356 357 /** 358 * Checks if all fields are valid.<p> 359 * 360 * @return true, if all data are ok. 361 */ 362 @SuppressWarnings("unchecked") 363 protected boolean isValid() { 364 365 boolean res = true; 366 367 res = res & m_description.isValid(); 368 res = res & m_name.isValid(); 369 if (!res) { 370 return res; 371 } 372 for (I_CmsEditableGroupRow row : m_ouResources.getRows()) { 373 if (!((AbstractField<String>)row.getComponent()).isValid()) { 374 return false; 375 } 376 } 377 return true; 378 } 379 380 /** 381 * Adds validators to fields.<p> 382 */ 383 @SuppressWarnings("unchecked") 384 protected void validate() { 385 386 if (m_ou == null) { 387 m_name.removeAllValidators(); 388 m_name.addValidator(new NameValidator()); 389 } 390 m_description.setRequired(true); 391 m_description.setRequiredError("Required"); 392 393 if (m_ouResources.getRows().isEmpty() & !m_webuser.getValue().booleanValue()) { 394 CmsPathSelectField field = new CmsPathSelectField(); 395 field.setUseRootPaths(true); 396 field.setCmsObject(m_cms); 397 m_ouResources.addRow(field); 398 } 399 for (I_CmsEditableGroupRow row : m_ouResources.getRows()) { 400 ((AbstractField<String>)row.getComponent()).removeAllValidators(); 401 ((AbstractField<String>)row.getComponent()).addValidator(new ResourceValidator()); 402 } 403 } 404 405 /** 406 * Saves the OU.<p> 407 */ 408 void saveOU() { 409 410 try { 411 List<String> resources = new ArrayList<String>(); 412 for (I_CmsEditableGroupRow row : m_ouResources.getRows()) { 413 resources.add(((CmsPathSelectField)row.getComponent()).getValue()); 414 } 415 if (m_ou == null) { 416 String parentOu = m_parentOu.getValue(); 417 if (!parentOu.endsWith("/")) { 418 parentOu += "/"; 419 } 420 if (resources.contains("null")) { 421 resources.remove("null"); 422 } 423 List<String> resourceNames = CmsFileUtil.removeRedundancies(resources); 424 m_ou = OpenCms.getOrgUnitManager().createOrganizationalUnit( 425 m_cms, 426 parentOu + m_name.getValue(), 427 m_description.getValue(), 428 getFlags(), 429 resourceNames.isEmpty() ? null : resourceNames.get(0)); 430 431 if (!resourceNames.isEmpty()) { 432 resourceNames.remove(0); 433 Iterator<String> itResourceNames = CmsFileUtil.removeRedundancies(resourceNames).iterator(); 434 while (itResourceNames.hasNext()) { 435 OpenCms.getOrgUnitManager().addResourceToOrgUnit(m_cms, m_ou.getName(), itResourceNames.next()); 436 } 437 } 438 } else { 439 m_ou.setDescription(m_description.getValue()); 440 m_ou.setFlags(getFlags()); 441 List<String> resourceNamesNew = CmsFileUtil.removeRedundancies(resources); 442 List<CmsResource> resourcesOld = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit( 443 m_cms, 444 m_ou.getName()); 445 List<String> resourceNamesOld = new ArrayList<String>(); 446 Iterator<CmsResource> itResourcesOld = resourcesOld.iterator(); 447 while (itResourcesOld.hasNext()) { 448 CmsResource resourceOld = itResourcesOld.next(); 449 resourceNamesOld.add(m_cms.getSitePath(resourceOld)); 450 } 451 Iterator<String> itResourceNamesNew = resourceNamesNew.iterator(); 452 // add new resources to ou 453 while (itResourceNamesNew.hasNext()) { 454 String resourceNameNew = itResourceNamesNew.next(); 455 if (!resourceNamesOld.contains(resourceNameNew)) { 456 OpenCms.getOrgUnitManager().addResourceToOrgUnit(m_cms, m_ou.getName(), resourceNameNew); 457 } 458 } 459 Iterator<String> itResourceNamesOld = resourceNamesOld.iterator(); 460 // delete old resources from ou 461 while (itResourceNamesOld.hasNext()) { 462 String resourceNameOld = itResourceNamesOld.next(); 463 if (!resourceNamesNew.contains(resourceNameOld)) { 464 OpenCms.getOrgUnitManager().removeResourceFromOrgUnit(m_cms, m_ou.getName(), resourceNameOld); 465 } 466 } 467 // write the edited organizational unit 468 OpenCms.getOrgUnitManager().writeOrganizationalUnit(m_cms, m_ou); 469 } 470 } catch (CmsException e) { 471 LOG.error("Unable to save OU", e); 472 } 473 } 474 475 /** 476 * Get OU-flags.<p> 477 * 478 * @return the flag int-value 479 */ 480 private int getFlags() { 481 482 int flags = 0; 483 if (m_hideLogin.getValue().booleanValue()) { 484 flags += CmsOrganizationalUnit.FLAG_HIDE_LOGIN; 485 } 486 if (m_webuser.getValue().booleanValue()) { 487 flags += CmsOrganizationalUnit.FLAG_WEBUSERS; 488 } 489 return flags; 490 } 491}