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 GmbH & Co. KG, 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.workplace; 029 030import org.opencms.i18n.A_CmsMessageBundle; 031import org.opencms.i18n.CmsMessages; 032import org.opencms.i18n.CmsMultiMessages; 033import org.opencms.i18n.I_CmsMessageBundle; 034import org.opencms.main.CmsLog; 035import org.opencms.main.OpenCms; 036import org.opencms.util.CmsStringUtil; 037import org.opencms.workplace.explorer.CmsExplorerTypeSettings; 038 039import java.util.ArrayList; 040import java.util.HashSet; 041import java.util.Iterator; 042import java.util.List; 043import java.util.Locale; 044import java.util.ServiceLoader; 045import java.util.Set; 046 047import org.apache.commons.logging.Log; 048 049/** 050 * Provides access to the localized messages for the OpenCms workplace.<p> 051 * 052 * The workplace messages are collected from the workplace resource bundles of all installed modules, 053 * plus all the OpenCms core packages.<p> 054 * 055 * To be recognized as a workplace module resource bundle, 056 * the workplace property file must follow the naming convention <code>${module_package_name}.workplace${locale}.properties</code>, 057 * or <code>${module_package_name}.messages${locale}.properties</code> 058 * for example like <code>com.mycompany.module.workplace_en.properties</code> or 059 * <code>com.mycompany.module.messages_en.properties</code>.<p> 060 * 061 * Workplace messages are cached for faster lookup. If a localized key is contained in more then one module, 062 * it will be used only from the module where it was first found in. The module order is undefined. It is therefore 063 * recommended to ensure the uniqueness of all module keys by placing a special prefix in front of all keys of a module.<p> 064 * 065 * @since 6.0.0 066 */ 067public class CmsWorkplaceMessages extends CmsMultiMessages { 068 069 /** The title key prefix used for the "new resource" dialog. */ 070 public static final String GUI_NEW_RESOURCE_TITLE_PREFIX = "title.new"; 071 072 /** Constant for the <code>".messages"</code> prefix. */ 073 public static final String PREFIX_BUNDLE_MESSAGES = ".messages"; 074 075 /** Constant for the <code>".workplace"</code> prefix. */ 076 public static final String PREFIX_BUNDLE_WORKPLACE = ".workplace"; 077 078 /** Constant for the multi bundle name. */ 079 public static final String WORKPLACE_BUNDLE_NAME = CmsWorkplaceMessages.class.getName(); 080 081 /** The logger for this class. */ 082 private static Log LOG = CmsLog.getLog(CmsWorkplaceMessages.class.getName()); 083 084 /** 085 * Constructor for creating a new messages object 086 * initialized with the provided locale.<p> 087 * 088 * @param locale the locale to initialize 089 */ 090 public CmsWorkplaceMessages(Locale locale) { 091 092 super(locale); 093 setBundleName(WORKPLACE_BUNDLE_NAME); 094 addMessages(collectModuleMessages(locale)); 095 } 096 097 /** 098 * Returns the title for the "new resource" dialog.<p> 099 * 100 * It will look up a key with the prefix {@link #GUI_NEW_RESOURCE_TITLE_PREFIX} 101 * and the given name appended (converted to lower case).<p> 102 * 103 * If this key is not found, the value of 104 * {@link org.opencms.workplace.explorer.Messages#GUI_TITLE_NEWFILEOTHER_0} will be returned.<p> 105 * 106 * @param wp an instance of a {@link CmsWorkplace} to resolve the key name with 107 * @param name the type to generate the title for 108 * 109 * @return the title for the "new resource" dialog 110 */ 111 public static String getNewResourceTitle(CmsWorkplace wp, String name) { 112 113 // try to find the localized key 114 String title = wp.key(GUI_NEW_RESOURCE_TITLE_PREFIX + name.toLowerCase()); 115 if (CmsMessages.isUnknownKey(title)) { 116 // still unknown - use default title 117 title = wp.key(org.opencms.workplace.explorer.Messages.GUI_TITLE_NEWFILEOTHER_0); 118 } 119 return title; 120 } 121 122 /** 123 * Returns the description of the given resource type name.<p> 124 * 125 * If this key is not found, the value of the name input will be returned.<p> 126 * 127 * @param wp an instance of a {@link CmsWorkplace} to resolve the key name with 128 * @param name the resource type name to generate the nice name for 129 * 130 * @return the description of the given resource type name 131 */ 132 public static String getResourceTypeDescription(CmsWorkplace wp, String name) { 133 134 // try to find the localized key 135 String key = OpenCms.getWorkplaceManager().getExplorerTypeSetting(name).getInfo(); 136 return wp.keyDefault(key, name); 137 } 138 139 /** 140 * Returns the description of the given resource type name.<p> 141 * 142 * If this key is not found, the value of the name input will be returned.<p> 143 * 144 * @param locale the right locale to use 145 * @param name the resource type name to generate the nice name for 146 * 147 * @return the description of the given resource type name 148 */ 149 public static String getResourceTypeDescription(Locale locale, String name) { 150 151 CmsExplorerTypeSettings settings = OpenCms.getWorkplaceManager().getExplorerTypeSetting(name); 152 if (settings != null) { 153 // try to find the localized key 154 String key = settings.getInfo(); 155 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(key)) { 156 return OpenCms.getWorkplaceManager().getMessages(locale).keyDefault(key, name); 157 } 158 } 159 return ""; 160 } 161 162 /** 163 * Returns the localized name of the given resource type name.<p> 164 * 165 * If this key is not found, the value of the name input will be returned.<p> 166 * 167 * @param wp an instance of a {@link CmsWorkplace} to resolve the key name with 168 * @param name the resource type name to generate the nice name for 169 * 170 * @return the localized name of the given resource type name 171 */ 172 public static String getResourceTypeName(CmsWorkplace wp, String name) { 173 174 // try to find the localized key 175 CmsExplorerTypeSettings typeSettings = OpenCms.getWorkplaceManager().getExplorerTypeSetting(name); 176 if (typeSettings == null) { 177 return name; 178 } 179 String key = typeSettings.getKey(); 180 return wp.keyDefault(key, name); 181 } 182 183 /** 184 * Returns the localized name of the given resource type name.<p> 185 * 186 * If this key is not found, the value of the name input will be returned.<p> 187 * 188 * @param locale the right locale to use 189 * @param name the resource type name to generate the nice name for 190 * 191 * @return the localized name of the given resource type name 192 */ 193 public static String getResourceTypeName(Locale locale, String name) { 194 195 // try to find the localized key 196 CmsExplorerTypeSettings typeSettings = OpenCms.getWorkplaceManager().getExplorerTypeSetting(name); 197 if (typeSettings == null) { 198 return name; 199 } 200 String key = typeSettings.getKey(); 201 return OpenCms.getWorkplaceManager().getMessages(locale).keyDefault(key, name); 202 } 203 204 /** 205 * Gathers all localization files for the workplace from the different modules.<p> 206 * 207 * For a module named "my.module.name" the locale file must be named 208 * "my.module.name.workplace" or "my.module.name.messages" and 209 * be located in the classpath so that the resource loader can find it.<p> 210 * 211 * @param locale the selected locale 212 * 213 * @return an initialized set of module messages 214 */ 215 private static List<CmsMessages> collectModuleMessages(Locale locale) { 216 217 // create a new list and add the base bundle 218 ArrayList<CmsMessages> result = new ArrayList<CmsMessages>(); 219 220 //////////// iterate over all registered modules //////////////// 221 Set<String> names = new HashSet<String>(); 222 Set<String> modules = OpenCms.getModuleManager().getModuleNames(); 223 if (modules != null) { 224 names.addAll(modules); 225 } 226 // use service loader to get additional bundle names 227 Iterator<I_CmsWorkplaceMessageBundleProvider> providers = ServiceLoader.load( 228 I_CmsWorkplaceMessageBundleProvider.class).iterator(); 229 while (providers.hasNext()) { 230 try { 231 I_CmsWorkplaceMessageBundleProvider provider = providers.next(); 232 names.addAll(provider.getMessageBundleNames()); 233 } catch (Throwable t) { 234 LOG.error("Error loading workplace messages bundle names from classpath.", t); 235 } 236 } 237 238 // iterate all module names 239 for (String baseName : names) { 240 //////////// collect the workplace.properties //////////////// 241 // this should result in a name like "my.module.name.workplace" 242 String bundleName = baseName + PREFIX_BUNDLE_WORKPLACE; 243 // try to load a bundle with the module names 244 CmsMessages msg = new CmsMessages(bundleName, locale); 245 // bundle was loaded, add to list of bundles 246 if (msg.isInitialized()) { 247 result.add(msg); 248 } 249 //////////// collect the messages.properties //////////////// 250 // this should result in a name like "my.module.name.messages" 251 bundleName = baseName + PREFIX_BUNDLE_MESSAGES; 252 // try to load a bundle with the module names 253 msg = new CmsMessages(bundleName, locale); 254 // bundle was loaded, add to list of bundles 255 if (msg.isInitialized()) { 256 result.add(msg); 257 } 258 } 259 260 //////////// collect additional core packages //////////////// 261 I_CmsMessageBundle[] coreMsgs = A_CmsMessageBundle.getOpenCmsMessageBundles(); 262 for (int i = 0; i < coreMsgs.length; i++) { 263 I_CmsMessageBundle bundle = coreMsgs[i]; 264 result.add(bundle.getBundle(locale)); 265 } 266 267 /////////// collect bundles configured in module configurations //////// 268 if (OpenCms.getADEManager().isInitialized()) { 269 Set<String> bundleNames = OpenCms.getADEManager().getConfiguredWorkplaceBundles(); 270 for (String bundleName : bundleNames) { 271 CmsMessages msg = new CmsMessages(bundleName, locale); 272 if (msg.isInitialized()) { 273 result.add(msg); 274 } 275 } 276 } 277 return result; 278 } 279 280 /** 281 * @see java.lang.Object#equals(java.lang.Object) 282 */ 283 @Override 284 public boolean equals(Object obj) { 285 286 if (obj == this) { 287 return true; 288 } 289 if (obj instanceof CmsWorkplaceMessages) { 290 // workplace messages are equal if the locale is equal (since all bundles are the same) 291 CmsMessages other = (CmsMessages)obj; 292 return other.getLocale().equals(getLocale()); 293 } 294 return false; 295 } 296 297 /** 298 * @see org.opencms.i18n.CmsMessages#hashCode() 299 */ 300 @Override 301 public int hashCode() { 302 303 return getLocale().hashCode(); 304 } 305}