001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (C) Alkacon Software (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.gwt.client.property.definition; 029 030import org.opencms.gwt.client.CmsCoreProvider; 031import org.opencms.gwt.client.rpc.CmsRpcAction; 032import org.opencms.gwt.client.ui.CmsPopup; 033import org.opencms.gwt.client.ui.CmsPushButton; 034import org.opencms.gwt.client.ui.css.I_CmsInputLayoutBundle; 035import org.opencms.gwt.client.ui.input.CmsTextBox; 036import org.opencms.util.CmsStringUtil; 037 038import java.util.Collection; 039import java.util.HashSet; 040import java.util.Set; 041 042import com.google.gwt.core.client.GWT; 043import com.google.gwt.event.dom.client.ClickEvent; 044import com.google.gwt.event.dom.client.KeyPressEvent; 045import com.google.gwt.event.dom.client.KeyPressHandler; 046import com.google.gwt.uibinder.client.UiBinder; 047import com.google.gwt.uibinder.client.UiField; 048import com.google.gwt.uibinder.client.UiHandler; 049import com.google.gwt.user.client.ui.Composite; 050import com.google.gwt.user.client.ui.Label; 051import com.google.gwt.user.client.ui.Panel; 052import com.google.gwt.user.client.ui.Widget; 053 054/** 055 * Widget for defining new properties.<p> 056 */ 057public class CmsPropertyDefinitionView extends Composite { 058 059 /** The UiBinder interface for this class. */ 060 interface I_CmsPropertyDefinitionViewUiBinder extends UiBinder<Widget, CmsPropertyDefinitionView> { 061 // empty 062 } 063 064 /** The max allowed property name length. */ 065 private static final int MAX_PROPERTY_NAME_LENGTH = 128; 066 067 /** The UiBinder instance for this widget. */ 068 private static I_CmsPropertyDefinitionViewUiBinder uiBinder = GWT.create(I_CmsPropertyDefinitionViewUiBinder.class); 069 070 /** The Cancel button. */ 071 @UiField 072 CmsPushButton m_cancelButton; 073 074 /** The panel displaying the existing properties.<p> */ 075 @UiField 076 Panel m_existingProperties; 077 078 /** The set of existing properties. */ 079 Set<String> m_existingPropertyNames = new HashSet<String>(); 080 081 /** The OK button. */ 082 @UiField 083 CmsPushButton m_okButton; 084 085 /** The popup containing this widget. */ 086 CmsPopup m_popup; 087 088 /** The input field for the property name. */ 089 @UiField 090 CmsTextBox m_propertyNameField; 091 092 /** 093 * Creates a new instance.<p> 094 * 095 * @param existingProperties the names of already existing properties 096 */ 097 public CmsPropertyDefinitionView(Collection<String> existingProperties) { 098 099 initWidget(uiBinder.createAndBindUi(this)); 100 addStyleName(I_CmsInputLayoutBundle.INSTANCE.inputCss().highTextBoxes()); 101 for (String existingProperty : existingProperties) { 102 m_existingProperties.add(new Label(existingProperty)); 103 m_existingPropertyNames.add(existingProperty); 104 } 105 m_propertyNameField.addKeyPressHandler(new KeyPressHandler() { 106 107 public void onKeyPress(KeyPressEvent event) { 108 109 int code = event.getNativeEvent().getKeyCode(); 110 if (code == 13) { 111 onClickOk(null); 112 } 113 } 114 }); 115 m_propertyNameField.getTextBox().setMaxLength(MAX_PROPERTY_NAME_LENGTH); 116 } 117 118 /** 119 * Closes the popup if possible.<p> 120 */ 121 public void closePopup() { 122 123 if (m_popup != null) { 124 m_popup.hide(); 125 m_popup = null; 126 } 127 } 128 129 /** 130 * Gets the cancel button.<p> 131 * 132 * @return the cancel button 133 */ 134 public CmsPushButton getCancelButton() { 135 136 return m_cancelButton; 137 138 } 139 140 /** 141 * Gets the OK button.<p> 142 * 143 * @return the OK button 144 */ 145 public CmsPushButton getOkButton() { 146 147 return m_okButton; 148 } 149 150 /** 151 * Sets the popup which contains this widget.<p> 152 * 153 * @param popup the popup 154 */ 155 public void setPopup(CmsPopup popup) { 156 157 m_popup = popup; 158 } 159 160 /** 161 * Button handler for the cancel button.<p> 162 * 163 * @param e the click event 164 */ 165 @UiHandler("m_cancelButton") 166 void onClickCancel(ClickEvent e) { 167 168 closePopup(); 169 } 170 171 /** 172 * Button handler for the OK button.<p> 173 * 174 * @param e the click event 175 */ 176 @UiHandler("m_okButton") 177 void onClickOk(ClickEvent e) { 178 179 String propName = m_propertyNameField.getFormValueAsString(); 180 if (CmsStringUtil.isEmptyOrWhitespaceOnly(propName)) { 181 m_propertyNameField.setErrorMessage(CmsPropertyDefinitionMessages.messageEmpty()); 182 return; 183 } 184 String normalizedName = propName.trim(); 185 if (!isValidName(normalizedName)) { 186 m_propertyNameField.setErrorMessage(CmsPropertyDefinitionMessages.messageInvalidName()); 187 return; 188 } 189 if (m_existingPropertyNames.contains(normalizedName)) { 190 m_propertyNameField.setErrorMessage(CmsPropertyDefinitionMessages.alreadyExists()); 191 return; 192 } 193 savePropertyDefinitionAndQuit(normalizedName); 194 } 195 196 /** 197 * Checks whether the property name is valid.<p> 198 * 199 * @param normalizedName the property name to check 200 * 201 * @return true if the name is valid 202 */ 203 private boolean isValidName(String normalizedName) { 204 205 return normalizedName.matches("^[a-zA-Z0-9_\\-\\.~\\$]+$"); 206 } 207 208 /** 209 * Saves the property definition and closes the dialog.<p> 210 * 211 * @param normalizedName the property name 212 */ 213 private void savePropertyDefinitionAndQuit(final String normalizedName) { 214 215 CmsRpcAction<Void> action = new CmsRpcAction<Void>() { 216 217 @Override 218 public void execute() { 219 220 start(200, true); 221 CmsCoreProvider.getVfsService().createPropertyDefinition(normalizedName, this); 222 } 223 224 @Override 225 protected void onResponse(Void result) { 226 227 stop(false); 228 closePopup(); 229 } 230 231 }; 232 action.execute(); 233 } 234}