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.dialogs; 029 030import org.opencms.ade.configuration.CmsElementView; 031import org.opencms.ade.configuration.CmsResourceTypeConfig; 032import org.opencms.ade.containerpage.CmsAddDialogTypeHelper; 033import org.opencms.ade.galleries.shared.CmsResourceTypeBean; 034import org.opencms.ade.galleries.shared.CmsResourceTypeBean.Origin; 035import org.opencms.configuration.preferences.CmsElementViewPreference; 036import org.opencms.db.CmsUserSettings; 037import org.opencms.file.CmsObject; 038import org.opencms.file.CmsResource; 039import org.opencms.main.CmsLog; 040import org.opencms.main.OpenCms; 041import org.opencms.ui.A_CmsUI; 042import org.opencms.ui.CmsVaadinUtils; 043import org.opencms.ui.I_CmsDialogContext; 044import org.opencms.ui.Messages; 045import org.opencms.ui.components.CmsBasicDialog; 046import org.opencms.ui.components.CmsOkCancelActionHandler; 047import org.opencms.ui.components.CmsResourceInfo; 048import org.opencms.util.CmsUUID; 049import org.opencms.workplace.explorer.CmsExplorerTypeSettings; 050import org.opencms.workplace.explorer.CmsResourceUtil; 051 052import java.util.ArrayList; 053import java.util.Collections; 054import java.util.Comparator; 055import java.util.HashMap; 056import java.util.LinkedHashMap; 057import java.util.List; 058import java.util.Locale; 059import java.util.Map; 060 061import org.apache.commons.logging.Log; 062 063import com.google.common.base.Predicate; 064import com.google.common.collect.ComparisonChain; 065import com.google.common.collect.Lists; 066import com.google.common.collect.Maps; 067import com.vaadin.event.LayoutEvents.LayoutClickEvent; 068import com.vaadin.event.LayoutEvents.LayoutClickListener; 069import com.vaadin.server.VaadinService; 070import com.vaadin.ui.AbstractComponent; 071import com.vaadin.ui.Button; 072import com.vaadin.ui.Button.ClickEvent; 073import com.vaadin.ui.Button.ClickListener; 074import com.vaadin.ui.Component; 075import com.vaadin.ui.declarative.Design; 076import com.vaadin.v7.data.Property.ValueChangeEvent; 077import com.vaadin.v7.data.Property.ValueChangeListener; 078import com.vaadin.v7.ui.AbstractSelect.ItemCaptionMode; 079import com.vaadin.v7.ui.ComboBox; 080import com.vaadin.v7.ui.VerticalLayout; 081 082public abstract class A_CmsSelectResourceTypeDialog extends CmsBasicDialog { 083 084 /** Default value for the 'default location' check box. */ 085 public static final Boolean DEFAULT_LOCATION_DEFAULT = Boolean.TRUE; 086 087 /** Id for the 'All' pseudo-view. */ 088 public static final CmsUUID ID_VIEW_ALL = CmsUUID.getConstantUUID("view-all"); 089 090 /** Setting name for the standard view. */ 091 public static final String SETTING_STANDARD_VIEW = "newDialogStandardView"; 092 093 /** The 'All' pseudo-view. */ 094 public static final CmsElementView VIEW_ALL = new CmsElementView(ID_VIEW_ALL); 095 096 /** Logger instance for this class. */ 097 private static final Log LOG = CmsLog.getLog(CmsNewDialog.class); 098 099 /** Serial version id. */ 100 private static final long serialVersionUID = 1L; 101 102 private Map<CmsResourceTypeBean, CmsResourceInfo> m_resourceInfoMap = new HashMap<CmsResourceTypeBean, CmsResourceInfo>(); 103 104 /** The created resource. */ 105 protected CmsResource m_createdResource; 106 107 /** The current view id. */ 108 protected CmsElementView m_currentView; 109 110 /** The dialog context. */ 111 protected I_CmsDialogContext m_dialogContext; 112 113 /** The current folder. */ 114 protected CmsResource m_folderResource; 115 116 /** The selected type. */ 117 protected CmsResourceTypeBean m_selectedType; 118 119 /** The type helper. */ 120 protected CmsAddDialogTypeHelper m_typeHelper; 121 122 private Runnable m_selectedRunnable; 123 124 /** List of all types. */ 125 private List<CmsResourceTypeBean> m_allTypes; 126 127 /** 128 * Creates a new instance.<p> 129 * 130 * @param folderResource the folder resource 131 * @param context the context 132 */ 133 public A_CmsSelectResourceTypeDialog(CmsResource folderResource, I_CmsDialogContext context) { 134 135 m_folderResource = folderResource; 136 m_dialogContext = context; 137 138 Design.read(this); 139 CmsVaadinUtils.visitDescendants(this, new Predicate<Component>() { 140 141 public boolean apply(Component component) { 142 143 component.setCaption(CmsVaadinUtils.localizeString(component.getCaption())); 144 return true; 145 } 146 }); 147 CmsUUID initViewId = (CmsUUID)VaadinService.getCurrentRequest().getWrappedSession().getAttribute( 148 SETTING_STANDARD_VIEW); 149 if (initViewId == null) { 150 try { 151 CmsUserSettings settings = new CmsUserSettings(A_CmsUI.getCmsObject()); 152 String viewSettingStr = settings.getAdditionalPreference( 153 CmsElementViewPreference.EXPLORER_PREFERENCE_NAME, 154 true); 155 if ((viewSettingStr != null) && CmsUUID.isValidUUID(viewSettingStr)) { 156 initViewId = new CmsUUID(viewSettingStr); 157 } 158 } catch (Exception e) { 159 LOG.error(e.getLocalizedMessage(), e); 160 } 161 } 162 if (initViewId == null) { 163 initViewId = CmsUUID.getNullUUID(); 164 } 165 CmsElementView initView = initViews(initViewId); 166 167 getCancelButton().addClickListener(new ClickListener() { 168 169 private static final long serialVersionUID = 1L; 170 171 public void buttonClick(ClickEvent event) { 172 173 finish(new ArrayList<CmsUUID>()); 174 } 175 }); 176 177 getViewSelector().setNullSelectionAllowed(false); 178 getViewSelector().setTextInputAllowed(false); 179 getVerticalLayout().addLayoutClickListener(new LayoutClickListener() { 180 181 private static final long serialVersionUID = 1L; 182 183 public void layoutClick(LayoutClickEvent event) { 184 185 CmsResourceTypeBean clickedType = (CmsResourceTypeBean)(((AbstractComponent)(event.getChildComponent())).getData()); 186 handleSelection(clickedType); 187 } 188 }); 189 setActionHandler(new CmsOkCancelActionHandler() { 190 191 private static final long serialVersionUID = 1L; 192 193 @Override 194 protected void cancel() { 195 196 finish(new ArrayList<CmsUUID>()); 197 } 198 199 @Override 200 protected void ok() { 201 202 // nothing to do 203 } 204 }); 205 init(initView, true); 206 } 207 208 /** 209 * Notifies the context that the given ids have changed.<p> 210 * 211 * @param ids the ids 212 */ 213 public void finish(List<CmsUUID> ids) { 214 215 if (m_selectedRunnable == null) { 216 m_dialogContext.finish(ids); 217 if (ids.size() == 1) { 218 m_dialogContext.focus(ids.get(0)); 219 220 } 221 } else { 222 m_selectedRunnable.run(); 223 } 224 } 225 226 public abstract Button getCancelButton(); 227 228 public CmsResourceInfo getTypeInfoLayout() { 229 230 return m_selectedType != null ? m_resourceInfoMap.get(m_selectedType) : null; 231 } 232 233 public abstract VerticalLayout getVerticalLayout(); 234 235 public abstract ComboBox getViewSelector(); 236 237 /** 238 * Handles selection of a type.<p> 239 * 240 * @param selectedType the selected type 241 */ 242 public abstract void handleSelection(final CmsResourceTypeBean selectedType); 243 244 /** 245 * Initializes and displays the type list for the given view.<p> 246 * 247 * @param view the element view 248 * @param useDefault true if we should use the default location for resource creation 249 */ 250 public void init(CmsElementView view, boolean useDefault) { 251 252 m_currentView = view; 253 if (!view.getId().equals(getViewSelector().getValue())) { 254 getViewSelector().setValue(view.getId()); 255 } 256 getVerticalLayout().removeAllComponents(); 257 258 List<CmsResourceTypeBean> typeBeans = m_typeHelper.getPrecomputedTypes(view); 259 if (view.getId().equals(ID_VIEW_ALL)) { 260 typeBeans = m_allTypes; 261 } 262 263 if (typeBeans == null) { 264 265 LOG.warn("precomputed type list is null: " + view.getTitle(A_CmsUI.getCmsObject(), Locale.ENGLISH)); 266 return; 267 } 268 for (CmsResourceTypeBean type : typeBeans) { 269 final String typeName = type.getType(); 270 String title = typeName; 271 String subtitle = getSubtitle(type, useDefault); 272 CmsExplorerTypeSettings explorerType = OpenCms.getWorkplaceManager().getExplorerTypeSetting(typeName); 273 274 title = CmsVaadinUtils.getMessageText(explorerType.getKey()); 275 CmsResourceInfo info = new CmsResourceInfo( 276 title, 277 subtitle, 278 CmsResourceUtil.getBigIconResource(explorerType, null)); 279 info.setData(type); 280 m_resourceInfoMap.put(type, info); 281 getVerticalLayout().addComponent(info); 282 } 283 } 284 285 public void setSelectedRunnable(Runnable run) { 286 287 m_selectedRunnable = run; 288 } 289 290 public abstract boolean useDefault(); 291 292 /** 293 * Creates type helper which is responsible for generating the type list.<p> 294 * 295 * @return the type helper 296 */ 297 protected CmsAddDialogTypeHelper createTypeHelper() { 298 299 return new CmsAddDialogTypeHelper(CmsResourceTypeConfig.AddMenuType.workplace) { 300 301 @Override 302 protected boolean exclude(CmsResourceTypeBean type) { 303 304 String typeName = type.getType(); 305 CmsExplorerTypeSettings explorerType = OpenCms.getWorkplaceManager().getExplorerTypeSetting(typeName); 306 boolean noCreate = !(type.isCreatableType() && !type.isDeactivated()); 307 return noCreate || (explorerType == null) || !explorerType.isCreatable(); 308 } 309 }; 310 311 } 312 313 /** 314 * Gets the subtitle for the type info widget.<p> 315 * 316 * @param type the type 317 * @param useDefault true if we are in 'use default' mode 318 * 319 * @return the subtitle 320 */ 321 protected String getSubtitle(CmsResourceTypeBean type, boolean useDefault) { 322 323 String subtitle = ""; 324 CmsExplorerTypeSettings explorerType = OpenCms.getWorkplaceManager().getExplorerTypeSetting(type.getType()); 325 if ((explorerType != null) && (explorerType.getInfo() != null)) { 326 subtitle = CmsVaadinUtils.getMessageText(explorerType.getInfo()); 327 } 328 if (useDefault && (type.getOrigin() == Origin.config) && (type.getCreatePath() != null)) { 329 String path = type.getCreatePath(); 330 CmsObject cms = A_CmsUI.getCmsObject(); 331 path = cms.getRequestContext().removeSiteRoot(path); 332 subtitle = CmsVaadinUtils.getMessageText(Messages.GUI_NEW_CREATE_IN_PATH_1, path); 333 } 334 return subtitle; 335 } 336 337 /** 338 * Initializes the view selector, using the given view id as an initial value.<p> 339 * 340 * @param startId the start view 341 * 342 * @return the start view 343 */ 344 private CmsElementView initViews(CmsUUID startId) { 345 346 Map<CmsUUID, CmsElementView> viewMap = OpenCms.getADEManager().getElementViews(A_CmsUI.getCmsObject()); 347 List<CmsElementView> viewList = new ArrayList<CmsElementView>(viewMap.values()); 348 Collections.sort(viewList, new Comparator<CmsElementView>() { 349 350 public int compare(CmsElementView arg0, CmsElementView arg1) { 351 352 return ComparisonChain.start().compare(arg0.getOrder(), arg1.getOrder()).result(); 353 } 354 355 }); 356 getViewSelector().setItemCaptionMode(ItemCaptionMode.EXPLICIT); 357 m_typeHelper = createTypeHelper(); 358 m_typeHelper.precomputeTypeLists( 359 A_CmsUI.getCmsObject(), 360 m_folderResource.getRootPath(), 361 A_CmsUI.getCmsObject().getRequestContext().removeSiteRoot(m_folderResource.getRootPath()), 362 viewList, 363 null); 364 365 // also collect types in LinkedHashMap to preserve order and ensure uniqueness 366 LinkedHashMap<String, CmsResourceTypeBean> allTypes = Maps.newLinkedHashMap(); 367 368 for (CmsElementView view : viewList) { 369 370 if (view.hasPermission(A_CmsUI.getCmsObject(), m_folderResource)) { 371 372 List<CmsResourceTypeBean> typeBeans = m_typeHelper.getPrecomputedTypes(view); 373 374 if (typeBeans.isEmpty()) { 375 continue; 376 } 377 for (CmsResourceTypeBean typeBean : typeBeans) { 378 allTypes.put(typeBean.getType(), typeBean); 379 } 380 getViewSelector().addItem(view.getId()); 381 getViewSelector().setItemCaption( 382 view.getId(), 383 view.getTitle(A_CmsUI.getCmsObject(), A_CmsUI.get().getLocale())); 384 } 385 } 386 getViewSelector().addItem(VIEW_ALL.getId()); 387 getViewSelector().setItemCaption(VIEW_ALL.getId(), CmsVaadinUtils.getMessageText(Messages.GUI_VIEW_ALL_0)); 388 m_allTypes = Lists.newArrayList(allTypes.values()); 389 if (allTypes.size() <= 8) { 390 startId = ID_VIEW_ALL; 391 } 392 if (getViewSelector().getItem(startId) == null) { 393 startId = (CmsUUID)(getViewSelector().getItemIds().iterator().next()); 394 } 395 396 getViewSelector().addValueChangeListener(new ValueChangeListener() { 397 398 private static final long serialVersionUID = 1L; 399 400 public void valueChange(ValueChangeEvent event) { 401 402 CmsUUID viewId = (CmsUUID)(event.getProperty().getValue()); 403 CmsElementView selectedView; 404 if (viewId.equals(ID_VIEW_ALL)) { 405 selectedView = VIEW_ALL; 406 } else { 407 selectedView = OpenCms.getADEManager().getElementViews(A_CmsUI.getCmsObject()).get( 408 event.getProperty().getValue()); 409 } 410 init(selectedView, useDefault()); 411 if (selectedView != VIEW_ALL) { 412 VaadinService.getCurrentRequest().getWrappedSession().setAttribute( 413 SETTING_STANDARD_VIEW, 414 (event.getProperty().getValue())); 415 } 416 } 417 }); 418 if (startId.equals(ID_VIEW_ALL)) { 419 return VIEW_ALL; 420 } else { 421 return OpenCms.getADEManager().getElementViews(A_CmsUI.getCmsObject()).get(startId); 422 } 423 } 424 425}