/* * This library is part of OpenCms - * the Open Source Content Management System * * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * For further information about Alkacon Software GmbH, please see the * company website: http://www.alkacon.com * * For further information about OpenCms, please see the * project website: http://www.opencms.org * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.opencms.jsp.decorator; import org.opencms.cache.CmsVfsMemoryObjectCache; import org.opencms.file.CmsObject; import org.opencms.file.CmsResource; import org.opencms.file.CmsResourceFilter; import org.opencms.file.types.CmsResourceTypePlain; import org.opencms.loader.CmsLoaderException; import org.opencms.main.CmsException; import org.opencms.main.CmsLog; import org.opencms.main.OpenCms; import org.opencms.module.CmsModule; import org.opencms.util.CmsStringUtil; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Locale; import org.apache.commons.logging.Log; /** * This class defines text decoration to be made by the postprocessor.<p> * * @since 6.1.3 */ public class CmsDecorationDefintion { /** The log object for this class. */ private static final Log LOG = CmsLog.getLog(CmsDecorationDefintion.class); /** The name of the configuration file holding all word substitutions. */ private String m_configurationFile; /** Flag, signaling if the first occurance of a word must be marked differntly. */ private boolean m_markFirst; /** The name of the substitution. */ private String m_name; /** The post to be added after the occurance of a word. */ private String m_postText; /** The post to be added after the occurance of a word on its first occurance. */ private String m_postTextFirst; /** The prefix to be added in front of the occurance of a word. */ private String m_preText; /** The prefix to be added in front of the occurance of a word on its first occurance. */ private String m_preTextFirst; /** * Constructor, creates a new empty CmsDecorationDefintion.<p> */ public CmsDecorationDefintion() { m_configurationFile = null; m_markFirst = false; m_name = null; m_postText = null; m_postTextFirst = null; m_preText = null; m_preTextFirst = null; } /** * Constructor, creates a new CmsDecorationDefintion with given values.<p> * * @param name the name of the decoration defintinion * @param preText the preText to be used * @param postText the postText to be used * @param preTextFirst the preTextFirst to be used * @param postTextFirst the postTextFirst to be used * @param markFrist the flag to use different decorations for the first occurance * @param configurationFile the name of the configuration file */ public CmsDecorationDefintion( String name, String preText, String postText, String preTextFirst, String postTextFirst, boolean markFrist, String configurationFile) { m_configurationFile = configurationFile; m_markFirst = markFrist; m_name = name; m_postText = postText; m_postTextFirst = postTextFirst; m_preText = preText; m_preTextFirst = preTextFirst; } /** * Returns all different decoration configuration names (like "abbr" or "acronym") that * are in the config file pointed to by module parameter "configfile".<p> * * @param cms needed to access the decoration definition XML content * * @return all different decoration configuration names (like "abbr" or "acronym") that * are in the config file pointed to by module parameter "configfile" * * @throws CmsException if sth goes wrong */ public static List getDecorationDefinitionNames(CmsObject cms) throws CmsException { List result = new ArrayList(); CmsModule module = OpenCms.getModuleManager().getModule("com.alkacon.opencms.extendeddecorator"); String configFile = module.getParameter("configfile"); if (CmsStringUtil.isEmpty(configFile)) { LOG.error(Messages.get().getBundle().key(Messages.LOG_ERROR_CONFIG_MISSING_0)); } else { CmsDecoratorConfiguration config = new CmsDecoratorConfiguration(cms, configFile); List decorationDefinitions = config.getDecorationDefinitions(); Iterator it = decorationDefinitions.iterator(); CmsDecorationDefintion decDef; while (it.hasNext()) { decDef = (CmsDecorationDefintion)it.next(); result.add(decDef.getName()); } } return result; } /** * Creates a CmsDecorationBundle of text decoration to be used by the decorator.<p> * * @param cms the CmsObject * @param locale the locale to build the decoration bundle for. If no locale is given, a bundle of all locales is build * @return CmsDecorationBundle including all decoration lists that match the locale * @throws CmsException if something goes wrong */ public CmsDecorationBundle createDecorationBundle(CmsObject cms, Locale locale) throws CmsException { // get configfile basename and the list of all decoration map files List decorationMapFiles = getDecorationMapFiles(cms); if (LOG.isDebugEnabled()) { LOG.debug(Messages.get().getBundle().key( Messages.LOG_DECORATION_DEFINITION_MAP_FILES_2, decorationMapFiles, locale)); } // create decoration maps List decorationMaps = getDecorationMaps(cms, decorationMapFiles); if (LOG.isDebugEnabled()) { LOG.debug(Messages.get().getBundle().key(Messages.LOG_DECORATION_DEFINITION_MAPS_2, decorationMaps, locale)); } // now that we have all decoration maps we can build the decoration bundle // the bundele is depending on the locale, if a locale is given, only those decoration maps that contain the // locale (or no locale at all) must be used. If no locale is given, all decoration maps are // put into the decoration bundle return createDecorationBundle(decorationMaps, locale); } /** * Creates a CmsDecorationBundle of text decoration to be used by the decorator based on a list of decoration maps.<p> * * @param decorationMaps the decoration maps to build the bundle from * @param locale the locale to build the decoration bundle for. If no locale is given, a bundle of all locales is build * @return CmsDecorationBundle including all decoration lists that match the locale */ public CmsDecorationBundle createDecorationBundle(List decorationMaps, Locale locale) { CmsDecorationBundle decorationBundle = new CmsDecorationBundle(locale); // sort the bundles Collections.sort(decorationMaps); // now process the decoration maps to see which of those must be added to the bundle Iterator i = decorationMaps.iterator(); while (i.hasNext()) { CmsDecorationMap decMap = (CmsDecorationMap)i.next(); // a decoration map must be added to the bundle if one of the following conditions match: // 1) the bundle has no locale // 2) the bundle has a locale and the locale of the map is equal or a sublocale // 3) the bundle has a locale and the map has no locale if ((locale == null) || ((decMap.getLocale() == null)) || (locale.getDisplayLanguage().equals(decMap.getLocale().getDisplayLanguage()))) { decorationBundle.putAll(decMap.getDecorationMap()); if (LOG.isDebugEnabled()) { LOG.debug(Messages.get().getBundle().key( Messages.LOG_DECORATION_DEFINITION_CREATE_BUNDLE_2, decMap.getName(), locale)); } } } return decorationBundle; } /** * Returns the configurationFile.<p> * * * @return the configurationFile */ public String getConfigurationFile() { return m_configurationFile; } /** * Returns the name.<p> * * @return the name */ public String getName() { return m_name; } /** * Returns the postText.<p> * * @return the postText */ public String getPostText() { return m_postText; } /** * Returns the postTextFirst.<p> * * @return the postTextFirst */ public String getPostTextFirst() { return m_postTextFirst; } /** * Returns the preText.<p> * * @return the preText */ public String getPreText() { return m_preText; } /** * Returns the preTextFirst.<p> * * @return the preTextFirst */ public String getPreTextFirst() { return m_preTextFirst; } /** * Returns the markFirst flag.<p> * * @return the markFirst flag */ public boolean isMarkFirst() { return m_markFirst; } /** * Sets the configurationFile.<p> * * @param configurationFile the configurationFile to set */ public void setConfigurationFile(String configurationFile) { m_configurationFile = configurationFile; } /** * Sets the markFirst flag.<p> * * @param markFirst the markFirst flag to set */ public void setMarkFirst(boolean markFirst) { m_markFirst = markFirst; } /** * Sets the name.<p> * * @param name the name to set */ public void setName(String name) { m_name = name; } /** * Sets the postText.<p> * * @param postText the postText to set */ public void setPostText(String postText) { m_postText = postText; } /** * Sets the postTextFirst.<p> * * @param postTextFirst the postTextFirst to set */ public void setPostTextFirst(String postTextFirst) { m_postTextFirst = postTextFirst; } /** * Sets the preText.<p> * * @param preText the preText to set */ public void setPreText(String preText) { m_preText = preText; } /** * Sets the preTextFirst.<p> * * @param preTextFirst the preTextFirst to set */ public void setPreTextFirst(String preTextFirst) { m_preTextFirst = preTextFirst; } /** * @see java.lang.Object#toString() */ public String toString() { StringBuffer buf = new StringBuffer(); buf.append(this.getClass().getName()); buf.append(" [name = '"); buf.append(m_name); buf.append("', markFirst = '"); buf.append(m_markFirst); buf.append("', preText = '"); buf.append(m_preText); buf.append("', postText = '"); buf.append(m_postText); buf.append("', preTextFirst = '"); buf.append(m_preTextFirst); buf.append("', postTextFirst = '"); buf.append(m_postTextFirst); buf.append("', configFile = "); buf.append(m_configurationFile); buf.append("]"); return buf.toString(); } /** * Gets the list of all decoartion map files that match to the current basename.<p> * * @param cms the CmsObject * @return list of CmsResources of the decoration map files * @throws CmsException if something goes wrong. */ private List getDecorationMapFiles(CmsObject cms) throws CmsException { List files = new ArrayList(); // calcualte the basename for the decoration map files // the basename is the filename without the fileextension and any "_locale" postfixes // e.g. decoration_en.csv will generate "decoration" as basename StringBuffer baseFilename = new StringBuffer(); baseFilename.append(CmsResource.getParentFolder(m_configurationFile)); String filename = cms.readResource(m_configurationFile).getName(); // get rid of the fileextension if there is one if (filename.lastIndexOf(".") > -1) { filename = filename.substring(0, filename.lastIndexOf(".")); } // extract the basename if (filename.lastIndexOf("_") > -1) { filename = filename.substring(0, filename.lastIndexOf("_")); } baseFilename.append(filename); String basename = baseFilename.toString(); // get all config files which belong to this basename int plainId; try { plainId = OpenCms.getResourceManager().getResourceType(CmsResourceTypePlain.getStaticTypeName()).getTypeId(); } catch (CmsLoaderException e) { // this should really never happen plainId = CmsResourceTypePlain.getStaticTypeId(); } List resources = cms.readResources(CmsResource.getParentFolder(m_configurationFile), CmsResourceFilter.DEFAULT); Iterator i = resources.iterator(); while (i.hasNext()) { CmsResource res = (CmsResource)i.next(); if (cms.getSitePath(res).startsWith(basename) && (res.getTypeId() == plainId)) { files.add(res); } } return files; } /** * Creates a list of decoration map objects from a given list of decoration files.<p> * * @param cms the CmsObject * @param decorationListFiles the list of decoration files * @return list of decoration map objects */ private List getDecorationMaps(CmsObject cms, List decorationListFiles) { List decorationMaps = new ArrayList(); Iterator i = decorationListFiles.iterator(); while (i.hasNext()) { CmsResource res = (CmsResource)i.next(); try { CmsDecorationMap decMap = (CmsDecorationMap)CmsVfsMemoryObjectCache.getVfsMemoryObjectCache().getCachedObject( cms, res.getRootPath()); if (decMap == null) { decMap = new CmsDecorationMap(cms, res, this); CmsVfsMemoryObjectCache.getVfsMemoryObjectCache().putCachedObject(cms, res.getRootPath(), decMap); } decorationMaps.add(decMap); } catch (CmsException e) { if (LOG.isErrorEnabled()) { LOG.error(Messages.get().getBundle().key( Messages.LOG_DECORATION_DEFINITION_CREATE_MAP_2, res.getName(), e)); } } } return decorationMaps; } }