001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://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: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://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.xml.types; 029 030import org.opencms.file.CmsObject; 031import org.opencms.file.CmsResource; 032import org.opencms.file.types.CmsResourceTypeXmlContent; 033import org.opencms.xml.I_CmsXmlDocument; 034 035import java.util.Locale; 036 037import org.dom4j.Element; 038 039/** 040 * Provides access to the value of a specific XML content node.<p> 041 * 042 * @since 6.0.0 043 */ 044public interface I_CmsXmlContentValue extends I_CmsXmlSchemaType { 045 046 /** 047 * Search content configuration for the value. 048 * The configuration determines how the conent's value should be added to the indexed content fields. 049 */ 050 public static class CmsSearchContentConfig { 051 052 /** Configuration for not adding the value to the content fields. */ 053 public static final CmsSearchContentConfig FALSE = new CmsSearchContentConfig(SearchContentType.FALSE, null); 054 /** Configuration for adding the extraction of the content linked by the value to the content fields. */ 055 public static final CmsSearchContentConfig CONTENT = new CmsSearchContentConfig( 056 SearchContentType.CONTENT, 057 null); 058 /** Configuration for triggering re-indexing if the resource linked by the value to the content fields changes. */ 059 public static final CmsSearchContentConfig UPDATE = new CmsSearchContentConfig( 060 SearchContentType.UPDATE, 061 null); 062 /** Configuration for adding the value unchanged to the content fields. */ 063 public static final CmsSearchContentConfig TRUE = new CmsSearchContentConfig(SearchContentType.TRUE, null); 064 /** The search content type. */ 065 private SearchContentType m_type; 066 /** The adjustment implementation for the value. */ 067 private String m_adjustmentClass; 068 069 /** 070 * Constructs a new search content configuration. 071 * @param type the search content type 072 * @param adjustmentClass the adjustment implementation 073 */ 074 private CmsSearchContentConfig(SearchContentType type, String adjustmentClass) { 075 076 m_type = type; 077 m_adjustmentClass = adjustmentClass; 078 } 079 080 /** 081 * Returns a flag, indicating if the the re-index relation should be added. 082 * @param config the search content config 083 * @return true, iff the re-indexing relation should be added. 084 */ 085 public static boolean addReIndexRelation(CmsSearchContentConfig config) { 086 087 return null == config ? false : SearchContentType.addReIndexRelation(config.getSearchContentType()); 088 } 089 090 /** 091 * Returns the configuration for the search content type. 092 * @param searchContentType the type to get the configuration for 093 * @return the configuration for the type 094 */ 095 public static CmsSearchContentConfig get(SearchContentType searchContentType) { 096 097 return get(searchContentType, null); 098 } 099 100 /** 101 * Returns the configuration for the combination of search content type and adjustment class. 102 * @param searchContentType the type to get the configuration for 103 * @param adjustmentClass the adjustment class 104 * @return the configuration for the type/adjustment combination. 105 */ 106 public static CmsSearchContentConfig get(SearchContentType searchContentType, String adjustmentClass) { 107 108 if (searchContentType == null) { 109 return adjustmentClass == null 110 ? null 111 : new CmsSearchContentConfig(SearchContentType.TRUE, adjustmentClass); 112 } 113 switch (searchContentType) { 114 case FALSE: 115 return FALSE; 116 case TRUE: 117 return adjustmentClass == null 118 ? TRUE 119 : new CmsSearchContentConfig(SearchContentType.TRUE, adjustmentClass); 120 case CONTENT: 121 return CONTENT; 122 case UPDATE: 123 return UPDATE; 124 default: 125 return null; 126 } 127 } 128 129 /** 130 * @return the adjustment class. 131 */ 132 public String getAdjustmentClass() { 133 134 return m_adjustmentClass; 135 } 136 137 /** 138 * @return the search content type. 139 */ 140 public SearchContentType getSearchContentType() { 141 142 return m_type; 143 } 144 145 /** 146 * Checks if the re-index relation can be added for resources of the provided type. 147 * @param res the resource to add the relation to. 148 * @return true, iff the relation can be added. 149 */ 150 public boolean isResourceSuitableForReIndexRelation(CmsResource res) { 151 152 switch (getSearchContentType()) { 153 case CONTENT: 154 return CmsResourceTypeXmlContent.isXmlContent(res); 155 default: 156 return true; 157 } 158 } 159 } 160 161 /** 162 * The available search types for element searchsetting. 163 */ 164 public static enum SearchContentType { 165 166 /** Do not merge the value of the field into the content field. */ 167 FALSE, 168 /** Merge the value of the field into the content field. */ 169 TRUE, 170 /** Merge the extracted content of the resource linked by the element into the content field. */ 171 CONTENT, 172 /** Do not merge the value of the field into the content field, but re-index if the resource linked in this field changed. */ 173 UPDATE; 174 175 /** 176 * Returns a flag, indicating if the the re-index relation should be added. 177 * @param type the search content type 178 * @return true, iff the re-indexing relation should be added. 179 */ 180 public static boolean addReIndexRelation(SearchContentType type) { 181 182 if (null == type) { 183 return false; 184 } 185 switch (type) { 186 case CONTENT: 187 case UPDATE: 188 return true; 189 default: 190 return false; 191 } 192 } 193 194 /** 195 * Converts the String into a SearchContentType. Returns <code>null</code> if conversion is not possible. 196 * @param type the search content type as String. 197 * @return the search content type specified by the provided String, or <code>null</code> if the String did not specify any search content type. 198 */ 199 public static SearchContentType fromString(String type) { 200 201 if (null == type) { 202 return null; 203 } 204 switch (type.toLowerCase()) { 205 case "false": 206 return FALSE; 207 case "true": 208 return TRUE; 209 case "content": 210 return CONTENT; 211 case "update": 212 return UPDATE; 213 default: 214 return null; 215 } 216 } 217 } 218 219 /** 220 * Returns the XML content instance this value belongs to.<p> 221 * 222 * @return the XML content instance this value belongs to 223 */ 224 I_CmsXmlDocument getDocument(); 225 226 /** 227 * Returns the original XML element of this XML content value.<p> 228 * 229 * @return the original XML element of this XML content value 230 */ 231 Element getElement(); 232 233 /** 234 * Returns the node index of this XML content value in the source XML document, 235 * starting with 0, with special handling of elements in choice groups.<p> 236 * 237 * This is useful in case there are more than one elements 238 * with the same XML node name in the source XML document.<p> 239 * 240 * Elements in XML choice groups will share the same number space, so a choice 241 * sequence will be numbered like this: 242 * <code>Title[1], Text[2], Title[3], Image[4]</code><p> 243 * 244 * @return the index of this XML content node in the source document with special handling of elements in choice groups 245 * 246 * @see #getXmlIndex() 247 */ 248 int getIndex(); 249 250 /** 251 * Returns the locale of this XML content value was generated for.<p> 252 * 253 * @return the locale of this XML content value was generated for 254 */ 255 Locale getLocale(); 256 257 /** 258 * Returns the total number of XML elements of this type that currently exist in the source document.<p> 259 * 260 * @return the total number of XML elements of this type that currently exist in the source document 261 */ 262 int getMaxIndex(); 263 264 /** 265 * Returns the path of this XML content value in the source document.<p> 266 * 267 * @return the path of this XML content value in the source document 268 */ 269 String getPath(); 270 271 /** 272 * Returns the value of this XML content node as a plain text String.<p> 273 * 274 * Plain text in this context means a pure textual representation 275 * of the content (i.e. without html tags). 276 * The plain text may be <code>null</code>, too, if there is no sound or useful 277 * textual representation (i.e. color values).<p> 278 * 279 * @param cms an initialized instance of a CmsObject 280 * 281 * @return the value of this XML content node as a plain text String 282 */ 283 String getPlainText(CmsObject cms); 284 285 /** 286 * Returns the search content type for the value. Default implementation uses the historic isSearchable() method. 287 * @return the search content type 288 */ 289 default CmsSearchContentConfig getSearchContentConfig() { 290 291 return new CmsSearchContentConfig(isSearchable() ? SearchContentType.TRUE : SearchContentType.FALSE, null); 292 } 293 294 /** 295 * Returns the value of this XML content node as a String.<p> 296 * 297 * @param cms an initialized instance of a CmsObject 298 * 299 * @return the value of this XML content node as a String 300 */ 301 String getStringValue(CmsObject cms); 302 303 /** 304 * Returns the node index of this XML content value in the source XML document, 305 * starting with 0, based on the XML ordering.<p> 306 * 307 * Elements in choice groups will be numbered like this: 308 * <code>Title[1], Text[1], Title[2], Image[1]</code><p> 309 * 310 * @return the index of this XML content node in the source document with special handling of elements in choice groups 311 * 312 * @see #getIndex() 313 */ 314 int getXmlIndex(); 315 316 /** 317 * Returns <code>true</code> in case this value is searchable by default with 318 * the integrated full text search.<p> 319 * 320 * @return <code>true</code> in case this value is searchable by default 321 */ 322 boolean isSearchable(); 323 324 /** 325 * Moves this XML content value one position down in the source document, if possible.<p> 326 * 327 * If the XML content value is already the first in it's sequence, it is not moved.<p> 328 */ 329 void moveDown(); 330 331 /** 332 * Moves this XML content value one position up in the source document, if possible.<p> 333 * 334 * If the XML content value is already the last in it's sequence, it is not moved.<p> 335 */ 336 void moveUp(); 337 338 /** 339 * Sets the provided String as value of this XML content node.<p> 340 * 341 * This method does provide processing of the content based on the 342 * users current OpenCms context. This can be used e.g. for link 343 * extraction and replacement in the content.<p> 344 * 345 * @param cms an initialized instance of a CmsObject 346 * @param value the value to set 347 * 348 */ 349 void setStringValue(CmsObject cms, String value); 350}