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.i18n; 029 030import org.opencms.file.CmsObject; 031import org.opencms.file.CmsResource; 032import org.opencms.file.CmsResourceFilter; 033import org.opencms.file.types.I_CmsResourceType; 034import org.opencms.main.CmsException; 035import org.opencms.main.CmsLog; 036import org.opencms.main.OpenCms; 037 038import java.util.ArrayList; 039import java.util.Arrays; 040import java.util.Collection; 041import java.util.List; 042import java.util.Locale; 043import java.util.MissingResourceException; 044import java.util.ResourceBundle; 045import java.util.Set; 046import java.util.stream.Collectors; 047 048import org.apache.commons.logging.Log; 049 050import com.google.common.collect.HashMultimap; 051import com.google.common.collect.Multimap; 052 053/** 054 * A lookup table used to find out which VFS based message bundles (XML/property bundles) contain a given key. 055 */ 056public class CmsMessageToBundleIndex { 057 058 /** The logger instance for this class. */ 059 private static final Log LOG = CmsLog.getLog(CmsMessageToBundleIndex.class); 060 061 /** The internal map used to store the bundle information for each key. */ 062 private Multimap<String, CmsVfsBundleParameters> m_map = HashMultimap.create(); 063 064 /** 065 * Creates a new instance that will read its data from a given set of bundles. 066 * 067 * @param bundleNames the set of bundle names from which to read the information 068 * @param locale the locale to use 069 */ 070 public CmsMessageToBundleIndex(Collection<String> bundleNames, Locale locale) { 071 072 for (String bundleName : bundleNames) { 073 try { 074 ResourceBundle bundle = CmsResourceBundleLoader.getBundle(bundleName, locale); 075 if (bundle instanceof CmsVfsResourceBundle) { 076 CmsVfsResourceBundle vfsBundle = (CmsVfsResourceBundle)bundle; 077 CmsVfsBundleParameters parameters = vfsBundle.getParameters(); 078 for (String key : bundle.keySet()) { 079 m_map.put(key, parameters); 080 } 081 } 082 } catch (MissingResourceException e) { 083 LOG.debug("missing resource for " + bundleName + ":" + e.getMessage(), e); 084 } 085 } 086 } 087 088 /** 089 * Reads the bundle information for the whole system. 090 * 091 * <p>This uses the request context locale of the CmsObject passed as an argument. 092 * 093 * @param cms the CMS context to use 094 * @return the bundle information 095 * @throws CmsException if something goes wrong 096 */ 097 public static CmsMessageToBundleIndex read(CmsObject cms) throws CmsException { 098 099 cms = OpenCms.initCmsObject(cms); 100 cms.getRequestContext().setSiteRoot(""); 101 List<CmsResource> resources = new ArrayList<>(); 102 for (String typeName : Arrays.asList( 103 CmsVfsBundleManager.TYPE_XML_BUNDLE, 104 CmsVfsBundleManager.TYPE_PROPERTIES_BUNDLE)) { 105 try { 106 I_CmsResourceType xmlType = OpenCms.getResourceManager().getResourceType(typeName); 107 resources.addAll(cms.readResources("/", CmsResourceFilter.ALL.addRequireType(xmlType), true)); 108 } catch (Exception e) { 109 LOG.error(e.getLocalizedMessage(), e); 110 } 111 } 112 Set<String> bundleNames = resources.stream().map( 113 res -> CmsVfsBundleManager.getNameAndLocale(res).getName()).collect(Collectors.toSet()); 114 CmsMessageToBundleIndex result = new CmsMessageToBundleIndex(bundleNames, cms.getRequestContext().getLocale()); 115 return result; 116 } 117 118 /** 119 * Gets the root path of the bundle file for the given message key. 120 * 121 * <p>If no bundle is found, null is returned. 122 * 123 * @param key the message key 124 * @return the bundle root path 125 */ 126 public Collection<String> getBundlesPathForKey(String key) { 127 128 Collection<CmsVfsBundleParameters> params = m_map.get(key); 129 return params.stream().map(CmsVfsBundleParameters::getBasePath).collect(Collectors.toSet()); 130 } 131 132}