001/* 002 * Copyright 2010 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.cms.contenttype; 017 018import java.io.IOException; 019import java.io.InputStream; 020import java.util.ArrayList; 021import java.util.Arrays; 022import java.util.Comparator; 023import java.util.Date; 024import java.util.HashMap; 025import java.util.HashSet; 026import java.util.LinkedHashMap; 027import java.util.List; 028import java.util.Locale; 029import java.util.Map; 030import java.util.Set; 031import java.util.stream.Collectors; 032 033import org.apache.avalon.framework.service.ServiceException; 034import org.apache.avalon.framework.service.ServiceManager; 035import org.apache.cocoon.xml.AttributesImpl; 036import org.apache.cocoon.xml.XMLUtils; 037import org.apache.commons.io.IOUtils; 038import org.apache.commons.lang3.StringUtils; 039import org.xml.sax.ContentHandler; 040import org.xml.sax.SAXException; 041 042import org.ametys.cms.content.external.ExternalizableMetadataHelper; 043import org.ametys.cms.content.external.ExternalizableMetadataProvider.ExternalizableMetadataStatus; 044import org.ametys.cms.content.external.ExternalizableMetadataProviderExtensionPoint; 045import org.ametys.cms.repository.Content; 046import org.ametys.cms.transformation.RichTextTransformer; 047import org.ametys.cms.transformation.xslt.ResolveURIComponent; 048import org.ametys.core.user.UserIdentity; 049import org.ametys.core.util.DateUtils; 050import org.ametys.core.util.IgnoreRootHandler; 051import org.ametys.plugins.explorer.resources.Resource; 052import org.ametys.plugins.repository.AmetysObjectIterable; 053import org.ametys.plugins.repository.AmetysRepositoryException; 054import org.ametys.plugins.repository.TraversableAmetysObject; 055import org.ametys.plugins.repository.data.holder.DataHolder; 056import org.ametys.plugins.repository.metadata.BinaryMetadata; 057import org.ametys.plugins.repository.metadata.CommentableCompositeMetadata; 058import org.ametys.plugins.repository.metadata.CompositeMetadata; 059import org.ametys.plugins.repository.metadata.MetadataComment; 060import org.ametys.plugins.repository.metadata.MetadataSaxer; 061import org.ametys.plugins.repository.metadata.ModifiableRichText; 062import org.ametys.plugins.repository.metadata.MultilingualString; 063import org.ametys.plugins.repository.metadata.MultilingualStringHelper; 064import org.ametys.plugins.repository.metadata.RichText; 065import org.ametys.runtime.parameter.Enumerator; 066 067/** 068 * Component for helping SAXing metadata and especially metadata of a content. 069 * @deprecated Use {@link DataHolder} toSAX methods instead of this helper 070 */ 071@Deprecated 072public class MetadataManager extends MetadataSaxer 073{ 074 /** Avalon Role. */ 075 @SuppressWarnings("hiding") 076 public static final String ROLE = MetadataManager.class.getName(); 077 078 /** A comparator for repeater entry names. */ 079 public static final Comparator<String> REPEATER_ENTRY_COMPARATOR = new RepeaterEntryComparator(); 080 081 /** Content type extension point. */ 082 protected ContentTypeExtensionPoint _contentTypeExtensionPoint; 083 /** Helper for content types */ 084 protected ContentTypesHelper _contentTypesHelper; 085 /** The component to retrieve externalizable metadata */ 086 protected ExternalizableMetadataProviderExtensionPoint _externalizableMetadataProviderEP; 087 088 @Override 089 public void service(ServiceManager manager) throws ServiceException 090 { 091 super.service(manager); 092 _contentTypeExtensionPoint = (ContentTypeExtensionPoint) manager.lookup(ContentTypeExtensionPoint.ROLE); 093 _contentTypesHelper = (ContentTypesHelper) manager.lookup(ContentTypesHelper.ROLE); 094 _externalizableMetadataProviderEP = (ExternalizableMetadataProviderExtensionPoint) manager.lookup(ExternalizableMetadataProviderExtensionPoint.ROLE); 095 } 096 097 /** 098 * Get the local and external metadata 099 * @param content The content 100 * @return the externalizable metadata 101 */ 102 protected Set<String> getExternalizableMetadata (Content content) 103 { 104 return _externalizableMetadataProviderEP.getExternalAndLocalMetadata(content); 105 } 106 107 /** 108 * SAXes a composite metadata. 109 * @param contentHandler the content handler where to SAX into. 110 * @param content the content. 111 * @param compositeMetadata the composite metadata. 112 * @param metadataSet the metadata set to SAX or <code>null</code> for all metadata. 113 * @param metadataDefinition The metadata definition corresponding to the parameter compositeMetadata 114 * @param defaultLocale The locale to use to sax localized values such as multilingual content or multilingual string 115 * @param externalizableMetadata The externalizable (with local and external value) metadata 116 * @throws AmetysRepositoryException if an error occurs. 117 * @throws SAXException if an error occurs. 118 * @throws IOException if an error occurs. 119 */ 120 public void saxMetadata(ContentHandler contentHandler, Content content, CompositeMetadata compositeMetadata, MetadataSet metadataSet, MetadataDefinition metadataDefinition, Locale defaultLocale, Set<String> externalizableMetadata) throws AmetysRepositoryException, SAXException, IOException 121 { 122 _saxMetadataSetElementOrAll(contentHandler, content, compositeMetadata, metadataSet, metadataDefinition, defaultLocale, "", false, metadataSet == null ? false : metadataSet.isEdition(), false, externalizableMetadata); 123 } 124 125 /** 126 * SAXes a content metadata. This method does not check rights. 127 * @param contentHandler the content handler where to SAX into. 128 * @param content the content. 129 * @param metadataName the metadata name. 130 * @param defaultLocale The locale to use to sax localized values such as multilingual content or multilingual string. Only use if initial content's language is not null. Can be null. 131 * @throws AmetysRepositoryException if an error occurs. 132 * @throws SAXException if an error occurs. 133 * @throws IOException if an error occurs. 134 */ 135 public void saxMetadata(ContentHandler contentHandler, Content content, String metadataName, Locale defaultLocale) throws AmetysRepositoryException, SAXException, IOException 136 { 137 MetadataSet metadataSet = new MetadataSet(); 138 MetadataDefinitionReference metaDefRef = new MetadataDefinitionReference(metadataName); 139 metadataSet.addElement(metaDefRef); 140 saxMetadata(contentHandler, content, metadataSet, defaultLocale); 141 } 142 143 /** 144 * SAX the content metadata if it is readable. 145 * @param contentHandler the content handler where to SAX into. 146 * @param content the content. 147 * @param metadataName the metadata name. 148 * @param defaultLocale The locale to use to sax localized values such as multilingual content or multilingual string. Only use if initial content's language is not null. Can be null. 149 * @throws AmetysRepositoryException if an error occurs. 150 * @throws SAXException if an error occurs. 151 * @throws IOException if an error occurs. 152 */ 153 public void saxReadableMetadata(ContentHandler contentHandler, Content content, String metadataName, Locale defaultLocale) throws AmetysRepositoryException, SAXException, IOException 154 { 155 MetadataSet metadataSet = new MetadataSet(); 156 MetadataDefinitionReference metaDefRef = new MetadataDefinitionReference(metadataName); 157 metadataSet.addElement(metaDefRef); 158 saxReadableMetadata(contentHandler, content, metadataSet, defaultLocale); 159 } 160 161 162 /** 163 * SAXes a content metadata set. This method does not check rights. 164 * @param contentHandler the content handler where to SAX into. 165 * @param content the content. 166 * @param metadataSet the metadata set. 167 * @param defaultLocale The locale to use to sax localized values such as multilingual content or multilingual string. 168 * Only to be valued if initial content's language is null, otherwise set this parameter to null. 169 * @throws AmetysRepositoryException if an error occurs. 170 * @throws SAXException if an error occurs. 171 * @throws IOException if an error occurs. 172 */ 173 public void saxMetadata(ContentHandler contentHandler, Content content, MetadataSet metadataSet, Locale defaultLocale) throws AmetysRepositoryException, SAXException, IOException 174 { 175 _saxMetadataSetElementOrAll(contentHandler, content, content.getMetadataHolder(), metadataSet, null, defaultLocale, "", false, metadataSet.isEdition(), false, metadataSet.isEdition() ? getExternalizableMetadata(content) : new HashSet<>()); 176 } 177 178 /** 179 * SAXes the metadata comments of a content metadata set. This method does not check rights. 180 * @param contentHandler the content handler where to SAX into. 181 * @param content the content. 182 * @param metadataSet the metadata set. 183 * @param defaultLocale The locale to use to sax localized values such as multilingual content or multilingual string. 184 * Only to be valued if initial content's language is null, otherwise set this parameter to null. 185 * @throws AmetysRepositoryException if an error occurs. 186 * @throws SAXException if an error occurs. 187 * @throws IOException if an error occurs. 188 */ 189 public void saxMetadataComments(ContentHandler contentHandler, Content content, MetadataSet metadataSet, Locale defaultLocale) throws AmetysRepositoryException, SAXException, IOException 190 { 191 _saxMetadataSetElementOrAll(contentHandler, content, content.getMetadataHolder(), metadataSet, null, defaultLocale, "", false, metadataSet.isEdition(), true, new HashSet<>()); 192 } 193 194 /** 195 * SAX a content metadata set that are readable. 196 * @param contentHandler the content handler where to SAX into. 197 * @param content the content. 198 * @param metadataSet the metadata set. 199 * @param defaultLocale The locale to use to sax localized values such as multilingual content or multilingual string. 200 * Only to be valued if initial content's language is null, otherwise set this parameter to null. 201 * @throws AmetysRepositoryException if an error occurs. 202 * @throws SAXException if an error occurs. 203 * @throws IOException if an error occurs. 204 */ 205 public void saxReadableMetadata (ContentHandler contentHandler, Content content, MetadataSet metadataSet, Locale defaultLocale) throws AmetysRepositoryException, SAXException, IOException 206 { 207 _saxMetadataSetElementOrAll(contentHandler, content, content.getMetadataHolder(), metadataSet, null, defaultLocale, "", true, metadataSet.isEdition(), false, metadataSet.isEdition() ? getExternalizableMetadata(content) : new HashSet<>()); 208 } 209 210 private void _saxMetadataSetElementOrAll(ContentHandler contentHandler, Content content, CompositeMetadata metadata, AbstractMetadataSetElement metadataSetElement, MetadataDefinition metadataDefinition, Locale defaultLocale, String prefix, boolean checkRead, boolean editionRendering, boolean saxCommentsMode, Set<String> externalizableMetadata) throws AmetysRepositoryException, SAXException, IOException 211 { 212 if (metadataSetElement != null) 213 { 214 if (metadataSetElement instanceof MetadataDefinitionReference) 215 { 216 MetadataDefinitionReference metadataDefRef = (MetadataDefinitionReference) metadataSetElement; 217 String subMetadataName = metadataDefRef.getMetadataName(); 218 MetadataDefinition subMetadataDefinition = _getMetadataDefinition(content, metadataDefinition, subMetadataName); 219 220 if (subMetadataDefinition != null) 221 { 222 _saxMetadata(contentHandler, content, metadata, metadataDefRef, subMetadataDefinition, defaultLocale, prefix, checkRead, editionRendering, saxCommentsMode, externalizableMetadata); 223 } 224 } 225 else 226 { 227 for (AbstractMetadataSetElement subElement : metadataSetElement.getElements()) 228 { 229 _saxMetadataSetElementOrAll(contentHandler, content, metadata, subElement, metadataDefinition, defaultLocale, prefix, checkRead, editionRendering, saxCommentsMode, externalizableMetadata); 230 } 231 } 232 } 233 else 234 { 235 for (String metadataName : metadata.getMetadataNames()) 236 { 237 MetadataDefinition childMetadataDefinition = _getMetadataDefinition(content, metadataDefinition, metadataName); 238 239 if (childMetadataDefinition != null) 240 { 241 _saxMetadata(contentHandler, content, metadata, null, childMetadataDefinition, defaultLocale, prefix, checkRead, editionRendering, saxCommentsMode, externalizableMetadata); 242 } 243 } 244 } 245 } 246 247 private MetadataDefinition _getMetadataDefinition(Content content, MetadataDefinition parentMetadataDefinition, String metadataName) 248 { 249 MetadataDefinition metadataDefinition = null; 250 251 if (parentMetadataDefinition == null) 252 { 253 if (content != null) 254 { 255 metadataDefinition = _contentTypesHelper.getMetadataDefinition(metadataName, content.getTypes(), content.getMixinTypes()); 256 } 257 } 258 else 259 { 260 metadataDefinition = parentMetadataDefinition.getMetadataDefinition(metadataName); 261 } 262 263 return metadataDefinition; 264 } 265 266 /** 267 * SAX a metadata 268 * @param contentHandler The content handler where to SAX into. 269 * @param content The content 270 * @param metadata The parent composite metadata. 271 * @param metadataSetElement The {@link MetadataSet} element. 272 * @param metadataDefinition The metadata definition 273 * @param defaultLocale The locale to use to sax localized values such as multilingual content or multilingual string. Only use if initial content's language is not null. Can be null. 274 * @param prefix the metadata path prefix. 275 * @param checkRead true if need to check read right 276 * @param editionRendering true if the context rendering is for edition 277 * @param saxCommentsMode if true the comments will be SAXed for this metadata instead of the metadata value. 278 * @param externalizableMetadata The externalizable (with local and external value) metadata 279 * @throws AmetysRepositoryException if an error occurred 280 * @throws SAXException if an error occurred while SAXing 281 * @throws IOException if an error occurred 282 */ 283 protected void _saxMetadata(ContentHandler contentHandler, Content content, CompositeMetadata metadata, AbstractMetadataSetElement metadataSetElement, MetadataDefinition metadataDefinition, Locale defaultLocale, String prefix, boolean checkRead, boolean editionRendering, boolean saxCommentsMode, Set<String> externalizableMetadata) throws AmetysRepositoryException, SAXException, IOException 284 { 285 if (saxCommentsMode) 286 { 287 _saxMetadataComments(contentHandler, content, metadata, metadataSetElement, metadataDefinition, defaultLocale, prefix, checkRead, editionRendering, externalizableMetadata); 288 } 289 else 290 { 291 boolean isExternalizable = editionRendering && externalizableMetadata.contains(metadataDefinition.getId()); 292 if (isExternalizable) 293 { 294 _saxExternalisableMetadata(contentHandler, content, metadata, metadataSetElement, metadataDefinition, defaultLocale, prefix, checkRead, editionRendering, saxCommentsMode, externalizableMetadata); 295 } 296 else 297 { 298 _saxNoExternalisableMetadata(contentHandler, content, metadata, metadataSetElement, metadataDefinition, defaultLocale, prefix, checkRead, editionRendering, saxCommentsMode, externalizableMetadata); 299 } 300 } 301 } 302 303 /** 304 * SAX a non-externalizable metadata 305 * @param contentHandler The content handler where to SAX into. 306 * @param content The content 307 * @param metadata The parent composite metadata. 308 * @param metadataSetElement The {@link MetadataSet} element. 309 * @param metadataDefinition The metadata definition 310 * @param defaultLocale The locale to use to resolve localized values such as multilingual string or multilingual contents. Only use if the content's language is null. 311 * @param prefix the metadata path prefix. 312 * @param checkRead true if need to check read right 313 * @param editionRendering true if the context rendering is for edition 314 * @param saxCommentsMode if true the comments will be SAXed for this metadata instead of the metadata value. 315 * @param externalizableMetadata The externalizable (with local and external value) metadata 316 * @throws AmetysRepositoryException if an error occurred 317 * @throws SAXException if an error occurred while SAXing 318 * @throws IOException if an error occurred 319 */ 320 protected void _saxNoExternalisableMetadata(ContentHandler contentHandler, Content content, CompositeMetadata metadata, AbstractMetadataSetElement metadataSetElement, MetadataDefinition metadataDefinition, Locale defaultLocale, String prefix, boolean checkRead, boolean editionRendering, boolean saxCommentsMode, Set<String> externalizableMetadata) throws AmetysRepositoryException, SAXException, IOException 321 { 322 String metadataName = metadataDefinition.getName(); 323 324 if (metadata.hasMetadata(metadataName)) 325 { 326 MetadataType type = metadataDefinition.getType(); 327 switch (type) 328 { 329 case COMPOSITE: 330 _saxCompositeMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, metadataSetElement, defaultLocale, prefix, checkRead, editionRendering, saxCommentsMode, externalizableMetadata); 331 break; 332 case BINARY: 333 _saxBinaryMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, prefix, checkRead, editionRendering); 334 break; 335 336 case FILE: 337 _saxFileMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, prefix, checkRead, editionRendering); 338 break; 339 340 case RICH_TEXT: 341 _saxRichTextMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, prefix, checkRead, editionRendering); 342 break; 343 344 case DATE: 345 case DATETIME: 346 _saxSingleDateMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, prefix, checkRead); 347 break; 348 349 case USER: 350 _saxUserMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, prefix, checkRead, editionRendering); 351 break; 352 353 case CONTENT: 354 _saxContentReferenceMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, metadataSetElement, defaultLocale, prefix, checkRead, editionRendering); 355 break; 356 357 case SUB_CONTENT: 358 _saxSubContentMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, metadataSetElement, defaultLocale, prefix, checkRead, editionRendering); 359 break; 360 361 case GEOCODE: 362 _saxGeocodeMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, prefix, checkRead, editionRendering); 363 break; 364 365 case REFERENCE: 366 _saxReferenceMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, prefix, checkRead, editionRendering); 367 break; 368 369 case MULTILINGUAL_STRING: 370 _saxMultilingualStringMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, defaultLocale, prefix, checkRead, editionRendering); 371 break; 372 373 default: 374 _saxStringMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, prefix, checkRead, metadataDefinition.getEnumerator()); 375 break; 376 } 377 } 378 } 379 380 /** 381 * SAX a externalizable metadata 382 * @param contentHandler The content handler where to SAX into. 383 * @param content The content 384 * @param metadata The parent composite metadata. 385 * @param metadataSetElement The {@link MetadataSet} element. 386 * @param metadataDefinition The metadata definition 387 * @param prefix the metadata path prefix. 388 * @param checkRead true if need to check read right 389 * @param editionRendering true if the context rendering is for edition 390 * @param saxCommentsMode if true the comments will be SAXed for this metadata instead of the metadata value. 391 * @param externalizableMetadata The externalizable (with local and external value) metadata 392 * @param defaultLocale The default locale for multilingual rendering 393 * @throws AmetysRepositoryException if an error occurred 394 * @throws SAXException if an error occurred while SAXing 395 * @throws IOException if an error occurred 396 */ 397 protected void _saxExternalisableMetadata(ContentHandler contentHandler, Content content, CompositeMetadata metadata, AbstractMetadataSetElement metadataSetElement, MetadataDefinition metadataDefinition, Locale defaultLocale, String prefix, boolean checkRead, boolean editionRendering, boolean saxCommentsMode, Set<String> externalizableMetadata) throws AmetysRepositoryException, SAXException, IOException 398 { 399 String metadataName = metadataDefinition.getName(); 400 401 if (!checkRead || _canRead(content, metadataDefinition)) 402 { 403 MetadataType type = metadataDefinition.getType(); 404 switch (type) 405 { 406 case COMPOSITE: 407 _saxCompositeMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, metadataSetElement, null, prefix, checkRead, editionRendering, saxCommentsMode, externalizableMetadata); 408 break; 409 case BINARY: 410 _saxExternalisableBinaryMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, prefix, checkRead); 411 break; 412 413 case FILE: 414 _saxExternalisableFileMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, prefix, checkRead); 415 break; 416 417 case RICH_TEXT: 418 _saxExternalisableRichTextMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, checkRead); 419 break; 420 421 case DATE: 422 case DATETIME: 423 _saxExternalizableDateMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, checkRead); 424 break; 425 426 case LONG: 427 _saxExternalizableLongMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, checkRead); 428 break; 429 430 case DOUBLE: 431 _saxExternalizableDoubleMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, checkRead); 432 break; 433 434 case BOOLEAN: 435 _saxExternalizableBooleanMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, checkRead); 436 break; 437 438 case USER: 439 _saxExternalisableUserMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, checkRead); 440 break; 441 442 case SUB_CONTENT: 443 _saxExternalisableObjectCollectionMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, checkRead); 444 break; 445 446 case GEOCODE: 447 _saxExternalisableGeocodeMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, checkRead); 448 break; 449 450 case REFERENCE: 451 _saxExternalisableReferenceMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, checkRead); 452 break; 453 454 case MULTILINGUAL_STRING: 455 _saxExternalisableMultilingualStringMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, checkRead); 456 break; 457 458 case CONTENT: 459 _saxExternalizableContentReferenceMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, checkRead, defaultLocale); 460 break; 461 case STRING: 462 default: 463 _saxExternalizableStringMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, checkRead); 464 break; 465 } 466 } 467 } 468 469 /** 470 * SAX the jsonified values of an externalizable Binary metadata 471 * @param contentHandler The content handler 472 * @param content The content 473 * @param parentMetadata The parent composite metadata 474 * @param metadataDef The metadata definition 475 * @param metadataName The metadata name 476 * @param prefix The prefix 477 * @param checkRead true if need to check read right 478 * @throws AmetysRepositoryException if an error occurs. 479 * @throws SAXException if an error occurs. 480 */ 481 protected void _saxExternalisableBinaryMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, String prefix, boolean checkRead) throws SAXException 482 { 483 if (!checkRead || _canRead(content, metadataDef)) 484 { 485 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 486 487 Map<String, Object> localValue = null; 488 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 489 { 490 BinaryMetadata localBinary = ExternalizableMetadataHelper.getBinaryMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 491 localValue = _binaryAsJson(content, localBinary, prefix, ExternalizableMetadataHelper.getMetadataName(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)); 492 } 493 494 Map<String, Object> extValue = null; 495 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 496 { 497 BinaryMetadata extBinary = ExternalizableMetadataHelper.getBinaryMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 498 extValue = _binaryAsJson(content, extBinary, prefix, ExternalizableMetadataHelper.getMetadataName(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)); 499 } 500 501 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValue, extValue); 502 } 503 } 504 505 /** 506 * SAX the comments of a metadata 507 * @param contentHandler The content handler where to SAX into. 508 * @param content The content 509 * @param metadata The parent composite metadata. 510 * @param metadataSetElement The {@link MetadataSet} element. 511 * @param metadataDefinition The metadata definition 512 * @param defaultLocale The locale to use to sax localized values such as multilingual content or multilingual string. Only use if initial content's language is not null. Can be null. 513 * @param prefix the metadata path prefix. 514 * @param checkRead true if need to check read right 515 * @param editionRendering true if the context rendering is for edition 516 * @param externalizableMetadata The externalizable (with local and external value) metadata 517 * @throws AmetysRepositoryException if an error occurred 518 * @throws SAXException if an error occurred while SAXing 519 * @throws IOException if an error occurred 520 */ 521 protected void _saxMetadataComments(ContentHandler contentHandler, Content content, CompositeMetadata metadata, AbstractMetadataSetElement metadataSetElement, MetadataDefinition metadataDefinition, Locale defaultLocale, String prefix, boolean checkRead, boolean editionRendering, Set<String> externalizableMetadata) throws SAXException, IOException 522 { 523 String metadataName = metadataDefinition.getName(); 524 MetadataType type = metadataDefinition.getType(); 525 526 if (MetadataType.COMPOSITE.equals(type)) 527 { 528 if (metadata.hasMetadata(metadataName)) 529 { 530 _saxCompositeMetadata(contentHandler, content, metadata, metadataDefinition, metadataName, metadataSetElement, defaultLocale, prefix, checkRead, editionRendering, true, externalizableMetadata); 531 } 532 } 533 else 534 { 535 if (editionRendering && metadata instanceof CommentableCompositeMetadata) 536 { 537 CommentableCompositeMetadata commentableMetadata = (CommentableCompositeMetadata) metadata; 538 List<MetadataComment> comments = commentableMetadata.getComments(metadataName); 539 540 if (!comments.isEmpty()) 541 { 542 AttributesImpl metadataAttrs = new AttributesImpl(); 543 metadataAttrs.addCDATAAttribute("path", prefix + metadataName); 544 XMLUtils.startElement(contentHandler, "metadata", metadataAttrs); 545 546 int id = 1; 547 for (MetadataComment comment : comments) 548 { 549 AttributesImpl commentAttrs = new AttributesImpl(); 550 commentAttrs.addCDATAAttribute("id", String.valueOf(id++)); 551 commentAttrs.addCDATAAttribute("date", DateUtils.dateToString(comment.getDate())); 552 commentAttrs.addCDATAAttribute("author", comment.getAuthor()); 553 XMLUtils.createElement(contentHandler, "comment", commentAttrs, comment.getComment()); 554 } 555 556 XMLUtils.endElement(contentHandler, "metadata"); 557 } 558 } 559 } 560 } 561 562 /** 563 * SAX a composite metadata. 564 * @param contentHandler the content handler to SAX into. 565 * @param content the content. 566 * @param metadata the parent metadata holder. 567 * @param metadataDefinition the metadata definition. 568 * @param metadataName The name of the metadata to sax 569 * @param metadataSetElement the metadata-set element. 570 * @param defaultLocale The locale to use to sax localized values such as multilingual content or multilingual string. Only use if initial content's language is not null. Can be null. 571 * @param prefix the metadata path prefix. 572 * @param checkRead true if need to check read right. 573 * @param editionRendering true if rendering in edition mode, false in view mode. 574 * @param saxCommentsMode if true the comments will be SAXed for this metadata instead of the metadata value. 575 * @param externalizableMetadata The externalizable (with local and external value) metadata 576 * @throws SAXException if an error occurs. 577 * @throws IOException if an error occurs. 578 */ 579 protected void _saxCompositeMetadata(ContentHandler contentHandler, Content content, CompositeMetadata metadata, MetadataDefinition metadataDefinition, String metadataName, AbstractMetadataSetElement metadataSetElement, Locale defaultLocale, String prefix, boolean checkRead, boolean editionRendering, boolean saxCommentsMode, Set<String> externalizableMetadata) throws SAXException, IOException 580 { 581 CompositeMetadata subMetadata = metadata.getCompositeMetadata(metadataName); 582 583 AttributesImpl attrs = new AttributesImpl(); 584 if (metadataDefinition instanceof RepeaterDefinition) 585 { 586 attrs.addCDATAAttribute("entryCount", Integer.toString(subMetadata.getMetadataNames().length)); 587 } 588 589 if (!saxCommentsMode) 590 { 591 XMLUtils.startElement(contentHandler, metadataName, attrs); 592 } 593 594 if (metadataDefinition instanceof RepeaterDefinition) 595 { 596 String[] subMetadataNames = subMetadata.getMetadataNames(); 597 Arrays.sort(subMetadataNames, REPEATER_ENTRY_COMPARATOR); 598 599 for (String entryName : subMetadataNames) 600 { 601 org.ametys.plugins.repository.metadata.CompositeMetadata.MetadataType entryType = subMetadata.getType(entryName); 602 603 if (entryType != org.ametys.plugins.repository.metadata.CompositeMetadata.MetadataType.COMPOSITE) 604 { 605 throw new AmetysRepositoryException("Invalid type: " + entryType + " for metadata: " 606 + metadataName + " and entry of name: " + entryName); 607 } 608 609 CompositeMetadata entry = subMetadata.getCompositeMetadata(entryName); 610 611 if (!saxCommentsMode) 612 { 613 AttributesImpl entryAttrs = new AttributesImpl(); 614 entryAttrs.addCDATAAttribute("name", entryName); 615 XMLUtils.startElement(contentHandler, "entry", entryAttrs); 616 } 617 618 if (metadataSetElement != null) 619 { 620 for (AbstractMetadataSetElement subElement : metadataSetElement.getElements()) 621 { 622 // SAX all metadata contains in the current subElement 623 _saxMetadataSetElementOrAll(contentHandler, content, entry, subElement, metadataDefinition, defaultLocale, prefix + metadataName + "[" + entryName + "]/", checkRead, editionRendering, saxCommentsMode, externalizableMetadata); 624 } 625 } 626 else 627 { 628 // SAX all metadata contains in the current MetadataSetElement or all metadata having a definition 629 _saxMetadataSetElementOrAll(contentHandler, content, entry, metadataSetElement, metadataDefinition, defaultLocale, prefix + metadataName + "[" + entryName + "]/", checkRead, editionRendering, saxCommentsMode, externalizableMetadata); 630 } 631 632 if (!saxCommentsMode) 633 { 634 XMLUtils.endElement(contentHandler, "entry"); 635 } 636 } 637 } 638 else if (metadataSetElement != null) 639 { 640 // SAX all metadata contains in the current MetadataSetElement or all metadata having a definition 641 for (AbstractMetadataSetElement subElement : metadataSetElement.getElements()) 642 { 643 _saxMetadataSetElementOrAll(contentHandler, content, subMetadata, subElement, metadataDefinition, defaultLocale, prefix + metadataName + "/", checkRead, editionRendering, saxCommentsMode, externalizableMetadata); 644 } 645 } 646 else 647 { 648 _saxMetadataSetElementOrAll(contentHandler, content, subMetadata, null, metadataDefinition, defaultLocale, prefix + metadataName + "/", checkRead, editionRendering, saxCommentsMode, externalizableMetadata); 649 } 650 651 if (!saxCommentsMode) 652 { 653 XMLUtils.endElement(contentHandler, metadataName); 654 } 655 } 656 657 /** 658 * SAX a metadata as a Binary. 659 * @param contentHandler the content handler where to SAX into. 660 * @param content The content 661 * @param metadata the parent composite metadata. 662 * @param metadataName the metadata name. 663 * @param metadataDef the metadata definition. 664 * @param prefix the metadata path prefix. 665 * @param checkRead true if need to check read right 666 * @param editionRendering true if rendering in edition mode, false in view mode. 667 * @throws AmetysRepositoryException if an error occurs. 668 * @throws SAXException if an error occurs. 669 */ 670 protected void _saxBinaryMetadata(ContentHandler contentHandler, Content content, CompositeMetadata metadata, MetadataDefinition metadataDef, String metadataName, String prefix, boolean checkRead, boolean editionRendering) throws AmetysRepositoryException, SAXException 671 { 672 if (!checkRead || _canRead(content, metadataDef)) 673 { 674 if (editionRendering) 675 { 676 // In edition, generate the metadata as JSON. 677 _saxBinaryMetadataAsJson(contentHandler, content, metadata, metadataName, prefix); 678 } 679 else 680 { 681 _saxBinaryMetadata(contentHandler, metadata, metadataName, prefix); 682 } 683 } 684 } 685 686 /** 687 * SAX a binary metadata as a JSON string. 688 * @param contentHandler the content handler where to SAX into. 689 * @param content the content. 690 * @param parentMetadata the parent composite metadata. 691 * @param metadataName the metadata name. 692 * @param prefix the metadata path prefix. 693 * @throws AmetysRepositoryException if an error occurs. 694 * @throws SAXException if an error occurs. 695 */ 696 protected void _saxBinaryMetadataAsJson(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, String metadataName, String prefix) throws AmetysRepositoryException, SAXException 697 { 698 BinaryMetadata binaryMetadata = parentMetadata.getBinaryMetadata(metadataName); 699 700 Map<String, Object> values = _binaryAsJson(content, binaryMetadata, prefix, metadataName); 701 String jsonString = _jsonUtils.convertObjectToJson(values); 702 703 AttributesImpl attrs = new AttributesImpl(); 704 attrs.addCDATAAttribute("json", "true"); 705 XMLUtils.createElement(contentHandler, metadataName, attrs, jsonString); 706 } 707 708 /** 709 * SAX a metadata as a File. 710 * @param contentHandler the content handler where to SAX into. 711 * @param content The content 712 * @param metadata the parent composite metadata. 713 * @param metadataName the metadata name. 714 * @param metadataDef the metadata definition 715 * @param prefix the metadata path prefix. 716 * @param checkRead true if need to check read right 717 * @param editionRendering true if rendering in edition mode, false in view mode. 718 * @throws AmetysRepositoryException if an error occurs. 719 * @throws SAXException if an error occurs. 720 */ 721 protected void _saxFileMetadata(ContentHandler contentHandler, Content content, CompositeMetadata metadata, MetadataDefinition metadataDef, String metadataName, String prefix, boolean checkRead, boolean editionRendering) throws AmetysRepositoryException, SAXException 722 { 723 if (org.ametys.plugins.repository.metadata.CompositeMetadata.MetadataType.BINARY.equals(metadata.getType(metadataName))) 724 { 725 _saxBinaryMetadata(contentHandler, content, metadata, metadataDef, metadataName, prefix, checkRead, editionRendering); 726 } 727 else 728 { 729 _saxResourceFileMetadata(contentHandler, content, metadata, metadataDef, metadataName, prefix, checkRead, editionRendering); 730 } 731 } 732 733 /** 734 * Get the JSON representation of a {@link Resource} 735 * @param resource The resource 736 * @return The resource as JSON 737 */ 738 protected Map<String, Object> _resourceAsJson (Resource resource) 739 { 740 Map<String, Object> json = new LinkedHashMap<>(); 741 742 String filename = resource.getName(); 743 744 json.put("type", "explorer"); 745 json.put("mimeType", resource.getMimeType()); 746 json.put("id", resource.getId()); 747 json.put("path", resource.getId()); 748 749 if (filename != null) 750 { 751 json.put("filename", filename); 752 } 753 json.put("size", String.valueOf(resource.getLength())); 754 json.put("lastModified", DateUtils.dateToString(resource.getLastModified())); 755 756 757 String viewUrl = ResolveURIComponent.resolveBoundedImage("explorer", resource.getId(), 100, 100); 758 String downloadUrl = ResolveURIComponent.resolve("explorer", resource.getId(), true); 759 760 json.put("viewUrl", viewUrl); 761 json.put("downloadUrl", downloadUrl); 762 763 return json; 764 } 765 766 /** 767 * SAX a metadata as a binary file from resource. 768 * @param contentHandler the content handler where to SAX into. 769 * @param content The content 770 * @param metadata the parent composite metadata. 771 * @param metadataName the metadata name. 772 * @param metadataDef the metadata definition 773 * @param prefix the metadata path prefix. 774 * @param checkRead true if need to check read right 775 * @param editionRendering true if rendering in edition mode, false in view mode. 776 * @throws AmetysRepositoryException if an error occurs. 777 * @throws SAXException if an error occurs. 778 */ 779 protected void _saxResourceFileMetadata (ContentHandler contentHandler, Content content, CompositeMetadata metadata, MetadataDefinition metadataDef, String metadataName, String prefix, boolean checkRead, boolean editionRendering) throws AmetysRepositoryException, SAXException 780 { 781 if (!checkRead || _canRead(content, metadataDef)) 782 { 783 if (editionRendering) 784 { 785 _saxResourceFileMetadataAsJson(contentHandler, metadata, metadataName); 786 } 787 else 788 { 789 _saxResourceFileMetadata(contentHandler, metadata, metadataName); 790 } 791 } 792 } 793 794 /** 795 * SAX a metadata as a binary file from resource, as a JSON string. 796 * @param contentHandler the content handler where to SAX into. 797 * @param metadata the parent composite metadata. 798 * @param metadataName the metadata name. 799 * @throws AmetysRepositoryException if an error occurs. 800 * @throws SAXException if an error occurs. 801 */ 802 protected void _saxResourceFileMetadata(ContentHandler contentHandler, CompositeMetadata metadata, String metadataName) throws AmetysRepositoryException, SAXException 803 { 804 String value = metadata.getString(metadataName); 805 806 try 807 { 808 Resource resource = (Resource) _resolver.resolveById(value); 809 810 String filename = resource.getName(); 811 AttributesImpl attrs = new AttributesImpl(); 812 813 attrs.addCDATAAttribute("type", "explorer"); 814 attrs.addCDATAAttribute("id", resource.getId()); 815 attrs.addCDATAAttribute("path", resource.getId()); 816 attrs.addCDATAAttribute("mime-type", resource.getMimeType()); 817 818 if (filename != null) 819 { 820 attrs.addCDATAAttribute("filename", filename); 821 } 822 attrs.addCDATAAttribute("size", String.valueOf(resource.getLength())); 823 attrs.addCDATAAttribute("lastModified", DateUtils.dateToString(resource.getLastModified())); 824 825 XMLUtils.createElement(contentHandler, metadataName, attrs); 826 } 827 catch (AmetysRepositoryException e) 828 { 829 getLogger().warn("The resource of id '" + value + "' does not exist.", e); 830 } 831 } 832 833 /** 834 * SAX a metadata as a binary file from resource, as a JSON string. 835 * @param contentHandler the content handler where to SAX into. 836 * @param metadata the parent composite metadata. 837 * @param metadataName the metadata name. 838 * @throws AmetysRepositoryException if an error occurs. 839 * @throws SAXException if an error occurs. 840 */ 841 protected void _saxResourceFileMetadataAsJson(ContentHandler contentHandler, CompositeMetadata metadata, String metadataName) throws AmetysRepositoryException, SAXException 842 { 843 Map<String, Object> values = new LinkedHashMap<>(); 844 845 String value = metadata.getString(metadataName); 846 847 try 848 { 849 Resource resource = (Resource) _resolver.resolveById(value); 850 851 values = _resourceAsJson(resource); 852 853 String jsonString = _jsonUtils.convertObjectToJson(values); 854 855 AttributesImpl attrs = new AttributesImpl(); 856 attrs.addCDATAAttribute("json", "true"); 857 XMLUtils.createElement(contentHandler, metadataName, attrs, jsonString); 858 } 859 catch (AmetysRepositoryException e) 860 { 861 getLogger().warn("The resource of id '" + value + "' does not exist.", e); 862 } 863 } 864 865 /** 866 * SAX a metadata as a User. 867 * @param contentHandler the content handler where to SAX into. 868 * @param content The content 869 * @param metadata the parent composite metadata. 870 * @param metadataName the metadata name. 871 * @param metadataDef the metadata definition 872 * @param prefix the metadata path prefix. 873 * @param checkRead true if need to check read right 874 * @param editionRendering true if rendering in edition mode, false in view mode. 875 * @throws AmetysRepositoryException if an error occurs. 876 * @throws SAXException if an error occurs. 877 */ 878 protected void _saxUserMetadata (ContentHandler contentHandler, Content content, CompositeMetadata metadata, MetadataDefinition metadataDef, String metadataName, String prefix, boolean checkRead, boolean editionRendering) throws AmetysRepositoryException, SAXException 879 { 880 if (!checkRead || _canRead(content, metadataDef)) 881 { 882 if (editionRendering) 883 { 884 if (metadataDef.isMultiple()) 885 { 886 _saxMultipleUserMetadataAsJson(contentHandler, metadata, metadataName); 887 } 888 else 889 { 890 _saxSingleUserMetadataAsJson(contentHandler, metadata, metadataName); 891 } 892 } 893 else 894 { 895 _saxUserMetadata(contentHandler, metadata, metadataName); 896 } 897 } 898 } 899 900 /** 901 * SAX a "content" metadata. 902 * @param contentHandler the content handler to SAX into. 903 * @param content The currently saxed content. 904 * @param metadatas the parent composite metadata. 905 * @param metadataDefinition the metadata definition. 906 * @param metadataName the metadata name. 907 * @param metadataSetElement the metadata-set element. 908 * @param defaultLocale The locale to use to sax localized values such as multilingual content or multilingual string. Only use if initial content's language is not null. Can be null. 909 * @param prefix the metadata path prefix. 910 * @param checkRead true if need to check read right. 911 * @param editionRendering true if rendering in edition mode, false in view mode. 912 * @throws SAXException if an error occurs. 913 * @throws IOException if an error occurs. 914 */ 915 protected void _saxContentReferenceMetadata(ContentHandler contentHandler, Content content, CompositeMetadata metadatas, MetadataDefinition metadataDefinition, String metadataName, AbstractMetadataSetElement metadataSetElement, Locale defaultLocale, String prefix, boolean checkRead, boolean editionRendering) throws SAXException, IOException 916 { 917 if (!checkRead || _canRead(content, metadataDefinition)) 918 { 919 String[] values = metadatas.getStringArray(metadataName); 920 921 if (values != null) 922 { 923 if (editionRendering) 924 { 925 _saxContentReferenceMetadataForEdition(contentHandler, content, metadataDefinition, metadataName, defaultLocale, values); 926 } 927 else 928 { 929 for (String value : values) 930 { 931 try 932 { 933 // In view mode, render the contents 934 Content refContent = _resolver.resolveById(value); 935 Locale locale = content.getLanguage() != null ? new Locale(content.getLanguage()) : defaultLocale; 936 _saxNonEditionRenderingContent(contentHandler, refContent, locale, metadataName, metadataSetElement, prefix, checkRead); 937 } 938 catch (AmetysRepositoryException e) 939 { 940 if (getLogger().isWarnEnabled()) 941 { 942 getLogger().warn(String.format("The content of id '%s' references a non-existing content with value '%s' for metadata %s", content.getId(), value, metadataDefinition.getId()), e); 943 } 944 } 945 } 946 } 947 } 948 } 949 } 950 951 private void _saxContentReferenceMetadataForEdition(ContentHandler contentHandler, Content content, MetadataDefinition metadataDefinition, String metadataName, Locale defaultLocale, String[] values) throws SAXException 952 { 953 String jsonString = ""; 954 955 if (metadataDefinition.isMultiple()) 956 { 957 List<Map<String, Object>> contentsAsJson = new ArrayList<>(); 958 959 for (String value : values) 960 { 961 try 962 { 963 Content refContent = _resolver.resolveById(value); 964 contentsAsJson.add(_contentAsJson(refContent, content, defaultLocale)); 965 } 966 catch (AmetysRepositoryException e) 967 { 968 if (getLogger().isWarnEnabled()) 969 { 970 getLogger().warn(String.format("The content of id '%s' references a non-existing content with value '%s' for metadata %s", content.getId(), value, metadataDefinition.getId()), e); 971 } 972 } 973 } 974 975 jsonString = _jsonUtils.convertObjectToJson(contentsAsJson); 976 } 977 else if (values.length > 0) 978 { 979 String value = values[0]; 980 try 981 { 982 Content refContent = _resolver.resolveById(value); 983 jsonString = _jsonUtils.convertObjectToJson(_contentAsJson(refContent, content, defaultLocale)); 984 } 985 catch (AmetysRepositoryException e) 986 { 987 if (getLogger().isWarnEnabled()) 988 { 989 getLogger().warn(String.format("The content of id '%s' references a non-existing content with value '%s' for metadata %s", content.getId(), value, metadataDefinition.getId()), e); 990 } 991 } 992 } 993 994 AttributesImpl attrs = new AttributesImpl(); 995 attrs.addCDATAAttribute("json", "true"); 996 XMLUtils.createElement(contentHandler, metadataName, attrs, jsonString); 997 } 998 999 /** 1000 * Get the JSON representation of content value 1001 * @param refContent The content to sax 1002 * @param parentContent The owning content 1003 * @param defaultLocale The default local to resolve multilingual titles 1004 * @return The json properties of the content of null 1005 */ 1006 protected Map<String, Object> _contentAsJson(Content refContent, Content parentContent, Locale defaultLocale) 1007 { 1008 Locale locale = parentContent.getLanguage() != null ? new Locale(parentContent.getLanguage()) : defaultLocale; 1009 1010 Map<String, Object> contentProperties = new HashMap<>(); 1011 contentProperties.put("id", refContent.getId()); 1012 contentProperties.put("title", refContent.getTitle(locale)); 1013 contentProperties.put("iconGlyph", StringUtils.defaultString(_contentTypesHelper.getIconGlyph(refContent))); 1014 contentProperties.put("iconDecorator", StringUtils.defaultString(_contentTypesHelper.getIconDecorator(refContent))); 1015 contentProperties.put("smallIcon", StringUtils.defaultString(_contentTypesHelper.getSmallIcon(refContent))); 1016 contentProperties.put("mediumIcon", StringUtils.defaultString(_contentTypesHelper.getMediumIcon(refContent))); 1017 contentProperties.put("largeIcon", StringUtils.defaultString(_contentTypesHelper.getLargeIcon(refContent))); 1018 contentProperties.put("contentTypes", refContent.getTypes()); 1019 contentProperties.put("mixins", refContent.getMixinTypes()); 1020 1021 return contentProperties; 1022 } 1023 1024 /** 1025 * SAX a "content" metadata. 1026 * @param contentHandler the content handler to SAX into. 1027 * @param content The currently saxed content. 1028 * @param metadatas the parent composite metadata. 1029 * @param metadataDefinition the metadata definition. 1030 * @param metadataName the metadata name. 1031 * @param metadataSetElement the metadata-set element. 1032 * @param defaultLocale The locale to use to sax localized values such as multilingual content or multilingual string. Only use if initial content's language is not null. Can be null. 1033 * @param prefix the metadata path prefix. 1034 * @param checkRead true if need to check read right. 1035 * @param editionRendering true if rendering in edition mode, false in view mode. 1036 * @throws SAXException if an error occurs. 1037 * @throws IOException if an error occurs. 1038 */ 1039 protected void _saxSubContentMetadata(ContentHandler contentHandler, Content content, CompositeMetadata metadatas, MetadataDefinition metadataDefinition, String metadataName, AbstractMetadataSetElement metadataSetElement, Locale defaultLocale, String prefix, boolean checkRead, boolean editionRendering) throws SAXException, IOException 1040 { 1041 if (!checkRead || _canRead(content, metadataDefinition)) 1042 { 1043 TraversableAmetysObject contentMeta = metadatas.getObjectCollection(metadataName); 1044 1045 try (AmetysObjectIterable<Content> contents = contentMeta.getChildren()) 1046 { 1047 for (Content refContent : contents) 1048 { 1049 if (editionRendering) 1050 { 1051 // In edition, just SAX the content ID. 1052 XMLUtils.createElement(contentHandler, metadataName, refContent.getId()); 1053 } 1054 else 1055 { 1056 // In view mode, render the contents 1057 Locale locale = content.getLanguage() != null ? new Locale(content.getLanguage()) : defaultLocale; 1058 _saxNonEditionRenderingContent(contentHandler, refContent, locale, metadataName, metadataSetElement, prefix, checkRead); 1059 } 1060 } 1061 } 1062 } 1063 } 1064 1065 /** 1066 * SAX a content (referenced or sub-content) in view mode. 1067 * @param contentHandler the content handler to SAX into. 1068 * @param content The referenced or sub-content to SAX. 1069 * @param defaultLocale The locale to use to sax the localized values of this content. Only use if content 's language is null. 1070 * @param metadataName the metadata name. 1071 * @param metadataSetElement the metadata-set element. 1072 * @param prefix the metadata path prefix. 1073 * @param checkRead true if need to check read right. 1074 * @throws SAXException if an error occurs. 1075 * @throws IOException if an error occurs. 1076 */ 1077 protected void _saxNonEditionRenderingContent(ContentHandler contentHandler, Content content, Locale defaultLocale, String metadataName, AbstractMetadataSetElement metadataSetElement, String prefix, boolean checkRead) throws SAXException, IOException 1078 { 1079 MetadataSet metadataSet = _getContentMetadataSet(content, metadataSetElement, false); 1080 1081 AttributesImpl attrs = new AttributesImpl(); 1082 attrs.addCDATAAttribute("id", content.getId()); 1083 attrs.addCDATAAttribute("name", content.getName()); 1084 attrs.addCDATAAttribute("title", content.getTitle(defaultLocale)); 1085 if (content.getLanguage() != null) 1086 { 1087 attrs.addCDATAAttribute("language", content.getLanguage()); 1088 } 1089 attrs.addCDATAAttribute("createdAt", DateUtils.dateToString(content.getCreationDate())); 1090 attrs.addCDATAAttribute("creator", content.getCreator().getLogin()); 1091 attrs.addCDATAAttribute("lastModifiedAt", DateUtils.dateToString(content.getLastModified())); 1092 XMLUtils.startElement(contentHandler, metadataName, attrs); 1093 1094 if (metadataSet != null) 1095 { 1096 _saxMetadataSetElementOrAll(contentHandler, content, content.getMetadataHolder(), metadataSet, null, defaultLocale, prefix, checkRead, false, false, getExternalizableMetadata(content)); 1097 } 1098 1099 XMLUtils.endElement(contentHandler, metadataName); 1100 } 1101 1102 /** 1103 * SAX "geocode" metadata 1104 * @param contentHandler the content handler where to SAX into. 1105 * @param content The content 1106 * @param metadatas the parent composite metadata. 1107 * @param metadataDefinition the metadata definition. 1108 * @param metadataName the metadata name. 1109 * @param prefix the metadata path prefix. 1110 * @param checkRead true if need to check read right. 1111 * @param editionRendering true if rendering in edition mode, false in view mode. 1112 * @throws AmetysRepositoryException if an error occurs. 1113 * @throws SAXException if an error occurs. 1114 */ 1115 protected void _saxGeocodeMetadata(ContentHandler contentHandler, Content content, CompositeMetadata metadatas, MetadataDefinition metadataDefinition, String metadataName, String prefix, boolean checkRead, boolean editionRendering) throws SAXException 1116 { 1117 if (!checkRead || _canRead(content, metadataDefinition)) 1118 { 1119 if (editionRendering) 1120 { 1121 _saxSingleGeocodeMetadataAsJson(contentHandler, metadatas, metadataName); 1122 } 1123 else 1124 { 1125 _saxSingleGeocodeMetadata(contentHandler, metadatas, metadataName); 1126 } 1127 } 1128 } 1129 1130 /** 1131 * SAX a geocode metadata 1132 * @param contentHandler the content handler where to SAX into. 1133 * @param parentMetadata the parent composite metadata. 1134 * @param metadataName the metadata name. 1135 * @throws SAXException if an error occurs 1136 */ 1137 protected void _saxSingleGeocodeMetadata(ContentHandler contentHandler, CompositeMetadata parentMetadata, String metadataName) throws SAXException 1138 { 1139 CompositeMetadata geoCode = parentMetadata.getCompositeMetadata(metadataName); 1140 1141 AttributesImpl attrs = new AttributesImpl(); 1142 attrs.addCDATAAttribute("longitude", String.valueOf(geoCode.getDouble("longitude"))); 1143 attrs.addCDATAAttribute("latitude", String.valueOf(geoCode.getDouble("latitude"))); 1144 1145 XMLUtils.createElement(contentHandler, metadataName, attrs); 1146 } 1147 1148 /** 1149 * SAX values of a GeoCode metadata as a JSON String 1150 * @param contentHandler the content handler where to SAX into. 1151 * @param parentMetadata the parent composite metadata. 1152 * @param metadataName the metadata name. 1153 * @throws SAXException if an error occurs 1154 */ 1155 protected void _saxSingleGeocodeMetadataAsJson(ContentHandler contentHandler, CompositeMetadata parentMetadata, String metadataName) throws SAXException 1156 { 1157 CompositeMetadata geoCode = parentMetadata.getCompositeMetadata(metadataName); 1158 1159 String jsonString = _jsonUtils.convertObjectToJson(_geocodeAsJson(geoCode)); 1160 1161 AttributesImpl attrs = new AttributesImpl(); 1162 attrs.addCDATAAttribute("json", "true"); 1163 XMLUtils.createElement(contentHandler, metadataName, attrs, jsonString); 1164 } 1165 1166 /** 1167 * Get the JSON representation of geocode values 1168 * @param geoCode The composite metadata 1169 * @return The values as json 1170 */ 1171 protected Map<String, Object> _geocodeAsJson (CompositeMetadata geoCode) 1172 { 1173 Map<String, Object> values = new LinkedHashMap<>(); 1174 values.put("longitude", geoCode.getDouble("longitude")); 1175 values.put("latitude", geoCode.getDouble("latitude")); 1176 return values; 1177 } 1178 1179 /** 1180 * SAX "geocode" metadata 1181 * @param contentHandler the content handler where to SAX into. 1182 * @param content The content 1183 * @param metadatas the parent composite metadata. 1184 * @param metadataDefinition the metadata definition. 1185 * @param metadataName the metadata name. 1186 * @param defaultLocale The default locale to use to sax multilingual value if content's language is null. 1187 * @param prefix the metadata path prefix. 1188 * @param checkRead true if need to check read right. 1189 * @param editionRendering true if rendering in edition mode, false in view mode. 1190 * @throws AmetysRepositoryException if an error occurs. 1191 * @throws SAXException if an error occurs. 1192 */ 1193 protected void _saxMultilingualStringMetadata(ContentHandler contentHandler, Content content, CompositeMetadata metadatas, MetadataDefinition metadataDefinition, String metadataName, Locale defaultLocale, String prefix, boolean checkRead, boolean editionRendering) throws SAXException 1194 { 1195 if (!checkRead || _canRead(content, metadataDefinition)) 1196 { 1197 if (editionRendering) 1198 { 1199 _saxMultilingualStringAsJson(contentHandler, metadatas, metadataName); 1200 } 1201 else 1202 { 1203 _saxMultilingualStringMetadata(contentHandler, metadatas, metadataName, prefix, content.getLanguage() != null ? new Locale(content.getLanguage()) : defaultLocale); 1204 } 1205 } 1206 } 1207 1208 /** 1209 * SAX values of a GeoCode metadata as a JSON String 1210 * @param contentHandler the content handler where to SAX into. 1211 * @param parentMetadata the parent composite metadata. 1212 * @param metadataName the metadata name. 1213 * @throws SAXException if an error occurs 1214 */ 1215 protected void _saxMultilingualStringAsJson(ContentHandler contentHandler, CompositeMetadata parentMetadata, String metadataName) throws SAXException 1216 { 1217 MultilingualString multilingualString = parentMetadata.getMultilingualString(metadataName); 1218 1219 String jsonString = _jsonUtils.convertObjectToJson(_multilingualStringAsJson(multilingualString)); 1220 1221 AttributesImpl attrs = new AttributesImpl(); 1222 attrs.addCDATAAttribute("json", "true"); 1223 XMLUtils.createElement(contentHandler, metadataName, attrs, jsonString); 1224 } 1225 1226 /** 1227 * SAX "reference" metadata 1228 * @param contentHandler the content handler where to SAX into. 1229 * @param content The content 1230 * @param metadatas the parent composite metadata. 1231 * @param metadataDefinition the metadata definition. 1232 * @param metadataName the metadata name. 1233 * @param prefix the metadata path prefix. 1234 * @param checkRead true if need to check read right. 1235 * @param editionRendering true if rendering in edition mode, false in view mode. 1236 * @throws AmetysRepositoryException if an error occurs. 1237 * @throws SAXException if an error occurs. 1238 */ 1239 protected void _saxReferenceMetadata(ContentHandler contentHandler, Content content, CompositeMetadata metadatas, MetadataDefinition metadataDefinition, String metadataName, String prefix, boolean checkRead, boolean editionRendering) throws SAXException 1240 { 1241 if (!checkRead || _canRead(content, metadataDefinition)) 1242 { 1243 if (editionRendering) 1244 { 1245 _saxSingleReferenceMetadataAsJson(contentHandler, metadatas, metadataName); 1246 } 1247 else 1248 { 1249 _saxSingleReferenceMetadata(contentHandler, metadatas, metadataName); 1250 } 1251 } 1252 } 1253 1254 /** 1255 * SAX values of a Reference metadata 1256 *@param contentHandler the content handler where to SAX into. 1257 * @param parentMetadata the parent composite metadata. 1258 * @param metadataName the metadata name. 1259 * @throws SAXException if an error occurs 1260 */ 1261 protected void _saxSingleReferenceMetadata(ContentHandler contentHandler, CompositeMetadata parentMetadata, String metadataName) throws SAXException 1262 { 1263 CompositeMetadata refMetadata = parentMetadata.getCompositeMetadata(metadataName); 1264 1265 AttributesImpl attrs = new AttributesImpl(); 1266 attrs.addCDATAAttribute("type", refMetadata.getString("type")); 1267 1268 XMLUtils.createElement(contentHandler, metadataName, attrs, refMetadata.getString("value")); 1269 } 1270 1271 /** 1272 * SAX values of a Reference metadata to be used as a JSON String. 1273 * @param contentHandler the content handler where to SAX into. 1274 * @param parentMetadata the parent composite metadata. 1275 * @param metadataName the metadata name. 1276 * @throws SAXException if an error occurs 1277 */ 1278 protected void _saxSingleReferenceMetadataAsJson(ContentHandler contentHandler, CompositeMetadata parentMetadata, String metadataName) throws SAXException 1279 { 1280 CompositeMetadata refMetadata = parentMetadata.getCompositeMetadata(metadataName); 1281 1282 Map<String, Object> refValue = _referenceAsJson(refMetadata); 1283 String jsonString = _jsonUtils.convertObjectToJson(refValue); 1284 1285 AttributesImpl attrs = new AttributesImpl(); 1286 attrs.addCDATAAttribute("json", "true"); 1287 XMLUtils.createElement(contentHandler, metadataName, attrs, jsonString); 1288 } 1289 1290 /** 1291 * Get the JSON representation of a reference metadata 1292 * @param refMetadata The composite metadata 1293 * @return The value as JSON 1294 */ 1295 protected Map<String, Object> _referenceAsJson (CompositeMetadata refMetadata) 1296 { 1297 Map<String, Object> value = new LinkedHashMap<>(); 1298 value.put("type", refMetadata.getString("type")); 1299 value.put("value", refMetadata.getString("value")); 1300 return value; 1301 } 1302 1303 private MetadataSet _getContentMetadataSet(Content content, AbstractMetadataSetElement metadataSetElement, boolean editionRendering) throws AmetysRepositoryException 1304 { 1305 MetadataSet metadataSet = null; 1306 1307 String metadataSetName = null; 1308 if (metadataSetElement != null && metadataSetElement instanceof MetadataDefinitionReference) 1309 { 1310 metadataSetName = ((MetadataDefinitionReference) metadataSetElement).getMetadataSetName(); 1311 } 1312 1313 if (metadataSetName != null) 1314 { 1315 if (editionRendering) 1316 { 1317 metadataSet = _contentTypesHelper.getMetadataSetForEdition(metadataSetName, content.getTypes(), content.getMixinTypes()); 1318 } 1319 else 1320 { 1321 metadataSet = _contentTypesHelper.getMetadataSetForView(metadataSetName, content.getTypes(), content.getMixinTypes()); 1322 } 1323 } 1324 else if (metadataSetElement != null) 1325 { 1326 metadataSet = new MetadataSet(); 1327 for (AbstractMetadataSetElement element : metadataSetElement.getElements()) 1328 { 1329 metadataSet.addElement(element); 1330 } 1331 } 1332 1333 return metadataSet; 1334 } 1335 1336 /** 1337 * SAX a metadata as a RichText. 1338 * @param contentHandler the content handler where to SAX into. 1339 * @param content The content 1340 * @param metadata the parent composite metadata. 1341 * @param metadataDef The metadata definition 1342 * @param metadataName the metadata name. 1343 * @param prefix the metadata path prefix. 1344 * @param checkRead true if need to check read right 1345 * @param editionRendering true if the context rendering is for edition 1346 * @throws AmetysRepositoryException if an error occurs. 1347 * @throws SAXException if an error occurs. 1348 * @throws IOException if an error occurs. 1349 */ 1350 protected void _saxRichTextMetadata(ContentHandler contentHandler, Content content, CompositeMetadata metadata, MetadataDefinition metadataDef, String metadataName, String prefix, boolean checkRead, boolean editionRendering) throws AmetysRepositoryException, SAXException, IOException 1351 { 1352 if (!checkRead || _canRead(content, metadataDef)) 1353 { 1354 RichText richText = metadata.getRichText(metadataName); 1355 AttributesImpl attrs = new AttributesImpl(); 1356 String mimeType = richText.getMimeType(); 1357 1358 attrs.addCDATAAttribute("mime-type", richText.getMimeType()); 1359 attrs.addCDATAAttribute("lastModified", DateUtils.dateToString(richText.getLastModified())); 1360 1361 XMLUtils.startElement(contentHandler, metadataName, attrs); 1362 1363 if (editionRendering) 1364 { 1365 if (!(richText instanceof ModifiableRichText)) 1366 { 1367 throw new SAXException(""); 1368 } 1369 1370 RichTextTransformer richTextTransformer = metadataDef.getRichTextTransformer(); 1371 StringBuilder result = new StringBuilder(2048); 1372 1373 try 1374 { 1375 richTextTransformer.transformForEditing((ModifiableRichText) richText, result); 1376 } 1377 catch (IOException e) 1378 { 1379 throw new AmetysRepositoryException("Unable to transform a rich text into a string", e); 1380 } 1381 1382 XMLUtils.data(contentHandler, result.toString()); 1383 } 1384 else 1385 { 1386 if (mimeType.equals("text/xml") || mimeType.equals("application/xml")) 1387 { 1388 RichTextTransformer richTextTransformer = metadataDef.getRichTextTransformer(); 1389 richTextTransformer.transformForRendering(richText, new IgnoreRootHandler(contentHandler)); 1390 } 1391 else if (mimeType.equals("text/plain")) 1392 { 1393 String encoding = richText.getEncoding(); 1394 1395 try (InputStream is = richText.getInputStream()) 1396 { 1397 XMLUtils.data(contentHandler, IOUtils.toString(is, encoding)); 1398 } 1399 } 1400 else 1401 { 1402 throw new AmetysRepositoryException("Mime-type " + mimeType + " is not supported for rich text rendering"); 1403 } 1404 } 1405 1406 XMLUtils.endElement(contentHandler, metadataName); 1407 } 1408 } 1409 1410 1411 1412 /** 1413 * SAX a metadata as a String. 1414 * @param contentHandler the content handler where to SAX into 1415 * @param content The content 1416 * @param metadatas the parent composite metadata. 1417 * @param metadataName the metadata name. 1418 * @param metadataDef the metadata definition 1419 * @param prefix the metadata path prefix. 1420 * @param checkRead true if need to check read right 1421 * @param enumerator The enumerator for values 1422 * @throws AmetysRepositoryException if an error occurs. 1423 * @throws SAXException if an error occurs. 1424 */ 1425 protected void _saxStringMetadata(ContentHandler contentHandler, Content content, CompositeMetadata metadatas, MetadataDefinition metadataDef, String metadataName, String prefix, boolean checkRead, Enumerator enumerator) throws AmetysRepositoryException, SAXException 1426 { 1427 if (!checkRead || _canRead(content, metadataDef)) 1428 { 1429 if (enumerator != null) 1430 { 1431 _saxEnumeratedStringMetadata(contentHandler, metadatas, metadataName, enumerator); 1432 } 1433 else 1434 { 1435 _saxStringMetadata(contentHandler, metadatas, metadataName, prefix); 1436 } 1437 } 1438 } 1439 1440 /** 1441 * SAX a metadata as a Date. 1442 * @param contentHandler the content handler where to SAX into. 1443 * @param content The content 1444 * @param metadatas the parent composite metadata. 1445 * @param metadataName the metadata name. 1446 * @param metadataDef the metadata definition. 1447 * @param prefix the metadata path prefix. 1448 * @param checkRead true if need to check read right 1449 * @throws AmetysRepositoryException if an error occurs. 1450 * @throws SAXException if an error occurs. 1451 */ 1452 protected void _saxSingleDateMetadata(ContentHandler contentHandler, Content content, CompositeMetadata metadatas, MetadataDefinition metadataDef, String metadataName, String prefix, boolean checkRead) throws AmetysRepositoryException, SAXException 1453 { 1454 if (!checkRead || _canRead(content, metadataDef)) 1455 { 1456 _saxDateMetadata(contentHandler, metadatas, metadataName, prefix); 1457 } 1458 } 1459 1460 /** 1461 * Get the JSON representation of a {@link BinaryMetadata} 1462 * @param content The content 1463 * @param binaryMetadata The metadata 1464 * @param prefix The prefix 1465 * @param metadataName The metadata name 1466 * @return The binary as JSON 1467 */ 1468 protected Map<String, Object> _binaryAsJson (Content content, BinaryMetadata binaryMetadata, String prefix, String metadataName) 1469 { 1470 Map<String, Object> values = _binaryAsJson(binaryMetadata, prefix, metadataName); 1471 1472 StringBuffer sb = new StringBuffer(); 1473 sb.append(prefix) 1474 .append(metadataName) 1475 .append("?contentId=") 1476 .append(content.getId()); 1477 1478 String viewUrl = ResolveURIComponent.resolveBoundedImage("attribute", sb.toString(), 100, 100); 1479 String downloadUrl = ResolveURIComponent.resolve("attribute", sb.toString(), true); 1480 1481 values.put("viewUrl", viewUrl); 1482 values.put("downloadUrl", downloadUrl); 1483 1484 return values; 1485 } 1486 1487 /** 1488 * SAX the jsonified values of an externalizable Content metadata 1489 * @param contentHandler The content handler 1490 * @param content The content 1491 * @param parentMetadata The parent composite metadata 1492 * @param metadataDef The metadata definition 1493 * @param metadataName The metadata name 1494 * @param checkRead true if need to check read right 1495 * @param defaultLocale The default locale for multilingual title rendering 1496 * @throws AmetysRepositoryException if an error occurs. 1497 * @throws SAXException if an error occurs. 1498 */ 1499 protected void _saxExternalizableContentReferenceMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, boolean checkRead, Locale defaultLocale) throws AmetysRepositoryException, SAXException 1500 { 1501 if (!checkRead || _canRead(content, metadataDef)) 1502 { 1503 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 1504 1505 if (metadataDef.isMultiple()) 1506 { 1507 _saxExternalizableContentReferenceMultipleMetadata(contentHandler, content, parentMetadata, metadataDef, metadataName, defaultLocale, status); 1508 } 1509 else 1510 { 1511 _saxExternalizableContentReferenceSimpleMetadata(contentHandler, content, parentMetadata, metadataDef, metadataName, defaultLocale, status); 1512 } 1513 } 1514 } 1515 1516 private void _saxExternalizableContentReferenceMultipleMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, Locale defaultLocale, ExternalizableMetadataStatus status) throws AmetysRepositoryException, SAXException 1517 { 1518 List<Object> localValues = new ArrayList<>(); 1519 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1520 { 1521 String[] values = ExternalizableMetadataHelper.getStringArray(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1522 for (String value : values) 1523 { 1524 try 1525 { 1526 // In view mode, render the contents 1527 Content refContent = _resolver.resolveById(value); 1528 localValues.add(_contentAsJson(refContent, content, defaultLocale)); 1529 } 1530 catch (AmetysRepositoryException e) 1531 { 1532 if (getLogger().isWarnEnabled()) 1533 { 1534 getLogger().warn(String.format("The content of id '%s' references a non-existing content with value '%s' for metadata %s", content.getId(), value, metadataDef.getId()), e); 1535 } 1536 } 1537 } 1538 } 1539 1540 List<Object> extValues = new ArrayList<>(); 1541 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1542 { 1543 String[] values = ExternalizableMetadataHelper.getStringArray(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1544 for (String value : values) 1545 { 1546 try 1547 { 1548 // In view mode, render the contents 1549 Content refContent = _resolver.resolveById(value); 1550 extValues.add(_contentAsJson(refContent, content, defaultLocale)); 1551 } 1552 catch (AmetysRepositoryException e) 1553 { 1554 if (getLogger().isWarnEnabled()) 1555 { 1556 getLogger().warn(String.format("The content of id '%s' references a non-existing content with value '%s' for metadata %s", content.getId(), value, metadataDef.getId()), e); 1557 } 1558 } 1559 } 1560 } 1561 1562 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValues, extValues); 1563 } 1564 1565 private void _saxExternalizableContentReferenceSimpleMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, Locale defaultLocale, ExternalizableMetadataStatus status) throws AmetysRepositoryException, SAXException 1566 { 1567 Map<String, Object> localValue = null; 1568 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1569 { 1570 String value = ExternalizableMetadataHelper.getString(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1571 try 1572 { 1573 // In view mode, render the contents 1574 Content refContent = _resolver.resolveById(value); 1575 localValue = _contentAsJson(refContent, content, defaultLocale); 1576 } 1577 catch (AmetysRepositoryException e) 1578 { 1579 if (getLogger().isWarnEnabled()) 1580 { 1581 getLogger().warn(String.format("The content of id '%s' references a non-existing content with value '%s' for metadata %s", content.getId(), value, metadataDef.getId()), e); 1582 } 1583 } 1584 } 1585 1586 Map<String, Object> extValue = null; 1587 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1588 { 1589 String value = ExternalizableMetadataHelper.getString(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1590 try 1591 { 1592 // In view mode, render the contents 1593 Content refContent = _resolver.resolveById(value); 1594 extValue = _contentAsJson(refContent, content, defaultLocale); 1595 } 1596 catch (AmetysRepositoryException e) 1597 { 1598 if (getLogger().isWarnEnabled()) 1599 { 1600 getLogger().warn(String.format("The content of id '%s' references a non-existing content with value '%s' for metadata %s", content.getId(), value, metadataDef.getId()), e); 1601 } 1602 } 1603 } 1604 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValue, extValue); 1605 } 1606 1607 /** 1608 * SAX the jsonified values of an externalizable String metadata 1609 * @param contentHandler The content handler 1610 * @param content The content 1611 * @param parentMetadata The parent composite metadata 1612 * @param metadataDef The metadata definition 1613 * @param metadataName The metadata name 1614 * @param checkRead true if need to check read right 1615 * @throws AmetysRepositoryException if an error occurs. 1616 * @throws SAXException if an error occurs. 1617 */ 1618 protected void _saxExternalizableStringMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, boolean checkRead) throws AmetysRepositoryException, SAXException 1619 { 1620 if (!checkRead || _canRead(content, metadataDef)) 1621 { 1622 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 1623 1624 if (metadataDef.isMultiple()) 1625 { 1626 List<String> localValues = new ArrayList<>(); 1627 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1628 { 1629 String[] values = ExternalizableMetadataHelper.getStringArray(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1630 localValues = Arrays.asList(values); 1631 } 1632 1633 List<String> extValues = new ArrayList<>(); 1634 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1635 { 1636 String[] values = ExternalizableMetadataHelper.getStringArray(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1637 extValues = Arrays.asList(values); 1638 } 1639 1640 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValues, extValues); 1641 } 1642 else 1643 { 1644 String localValue = null; 1645 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1646 { 1647 localValue = ExternalizableMetadataHelper.getString(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1648 } 1649 1650 String extValue = null; 1651 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1652 { 1653 extValue = ExternalizableMetadataHelper.getString(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1654 } 1655 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValue, extValue); 1656 } 1657 } 1658 } 1659 1660 /** 1661 * SAX the jsonified values of an externalizable multilingual String metadata 1662 * @param contentHandler The content handler 1663 * @param content The content 1664 * @param parentMetadata The parent composite metadata 1665 * @param metadataDef The metadata definition 1666 * @param metadataName The metadata name 1667 * @param checkRead true if need to check read right 1668 * @throws AmetysRepositoryException if an error occurs. 1669 * @throws SAXException if an error occurs. 1670 */ 1671 protected void _saxExternalisableMultilingualStringMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, boolean checkRead) throws AmetysRepositoryException, SAXException 1672 { 1673 if (!checkRead || _canRead(content, metadataDef)) 1674 { 1675 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 1676 1677 Map<String, Object> localValue = null; 1678 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1679 { 1680 localValue = _multilingualStringAsJson(ExternalizableMetadataHelper.getMultilingualString(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)); 1681 } 1682 1683 Map<String, Object> extValue = null; 1684 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1685 { 1686 extValue = _multilingualStringAsJson(ExternalizableMetadataHelper.getMultilingualString(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)); 1687 } 1688 1689 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValue, extValue); 1690 } 1691 } 1692 1693 /** 1694 * Get the JSON representation of a {@link MultilingualString} 1695 * @param multilingualString The multilingual string 1696 * @return The MultilingualString as JSON 1697 */ 1698 protected Map<String, Object> _multilingualStringAsJson (MultilingualString multilingualString) 1699 { 1700 return MultilingualStringHelper.toJson(multilingualString); 1701 } 1702 1703 1704 /** 1705 * SAX the jsonified values of an externalizable Date metadata 1706 * @param contentHandler The content handler 1707 * @param content The content 1708 * @param parentMetadata The parent composite metadata 1709 * @param metadataDef The metadata definition 1710 * @param metadataName The metadata name 1711 * @param checkRead true if need to check read right 1712 * @throws AmetysRepositoryException if an error occurs. 1713 * @throws SAXException if an error occurs. 1714 */ 1715 protected void _saxExternalizableDateMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, boolean checkRead) throws AmetysRepositoryException, SAXException 1716 { 1717 if (!checkRead || _canRead(content, metadataDef)) 1718 { 1719 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 1720 1721 if (metadataDef.isMultiple()) 1722 { 1723 List<String> localValuesAsStr = new ArrayList<>(); 1724 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1725 { 1726 Date[] localValues = ExternalizableMetadataHelper.getDateArray(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1727 localValuesAsStr = Arrays.asList(localValues).stream().map(date -> DateUtils.dateToString(date)).collect(Collectors.toList()); 1728 } 1729 1730 List<String> extValuesAsStr = new ArrayList<>(); 1731 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1732 { 1733 Date[] extValues = ExternalizableMetadataHelper.getDateArray(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1734 extValuesAsStr = Arrays.asList(extValues).stream().map(date -> DateUtils.dateToString(date)).collect(Collectors.toList()); 1735 } 1736 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValuesAsStr, extValuesAsStr); 1737 } 1738 else 1739 { 1740 Date localValue = null; 1741 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1742 { 1743 localValue = ExternalizableMetadataHelper.getDate(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1744 } 1745 Date extValue = null; 1746 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1747 { 1748 extValue = ExternalizableMetadataHelper.getDate(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1749 } 1750 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, DateUtils.dateToString(localValue), DateUtils.dateToString(extValue)); 1751 } 1752 } 1753 } 1754 1755 /** 1756 * SAX the jsonified values of an externalizable Long metadata 1757 * @param contentHandler The content handler 1758 * @param content The content 1759 * @param parentMetadata The parent composite metadata 1760 * @param metadataDef The metadata definition 1761 * @param metadataName The metadata name 1762 * @param checkRead true if need to check read right 1763 * @throws AmetysRepositoryException if an error occurs. 1764 * @throws SAXException if an error occurs. 1765 */ 1766 protected void _saxExternalizableLongMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, boolean checkRead) throws AmetysRepositoryException, SAXException 1767 { 1768 if (!checkRead || _canRead(content, metadataDef)) 1769 { 1770 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 1771 1772 if (metadataDef.isMultiple()) 1773 { 1774 long[] localValues = null; 1775 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1776 { 1777 localValues = ExternalizableMetadataHelper.getLongArray(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1778 } 1779 long[] extValues = null; 1780 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1781 { 1782 extValues = ExternalizableMetadataHelper.getLongArray(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1783 } 1784 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, Arrays.asList(localValues), Arrays.asList(extValues)); 1785 } 1786 else 1787 { 1788 Long localValue = null; 1789 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1790 { 1791 localValue = ExternalizableMetadataHelper.getLong(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1792 } 1793 Long extValue = null; 1794 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1795 { 1796 extValue = ExternalizableMetadataHelper.getLong(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1797 } 1798 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValue, extValue); 1799 } 1800 } 1801 } 1802 1803 /** 1804 * SAX the jsonified values of an externalizable Double metadata 1805 * @param contentHandler The content handler 1806 * @param content The content 1807 * @param parentMetadata The parent composite metadata 1808 * @param metadataDef The metadata definition 1809 * @param metadataName The metadata name 1810 * @param checkRead true if need to check read right 1811 * @throws AmetysRepositoryException if an error occurs. 1812 * @throws SAXException if an error occurs. 1813 */ 1814 protected void _saxExternalizableDoubleMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, boolean checkRead) throws AmetysRepositoryException, SAXException 1815 { 1816 if (!checkRead || _canRead(content, metadataDef)) 1817 { 1818 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 1819 1820 if (metadataDef.isMultiple()) 1821 { 1822 double[] localValues = null; 1823 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1824 { 1825 localValues = ExternalizableMetadataHelper.getDoubleArray(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1826 } 1827 double[] extValues = null; 1828 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1829 { 1830 extValues = ExternalizableMetadataHelper.getDoubleArray(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1831 } 1832 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, Arrays.asList(localValues), Arrays.asList(extValues)); 1833 } 1834 else 1835 { 1836 Double localValue = null; 1837 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1838 { 1839 localValue = ExternalizableMetadataHelper.getDouble(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1840 } 1841 Double extValue = null; 1842 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1843 { 1844 extValue = ExternalizableMetadataHelper.getDouble(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1845 } 1846 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValue, extValue); 1847 } 1848 } 1849 } 1850 1851 /** 1852 * SAX the jsonified values of an externalizable Boolean metadata 1853 * @param contentHandler The content handler 1854 * @param content The content 1855 * @param parentMetadata The parent composite metadata 1856 * @param metadataDef The metadata definition 1857 * @param metadataName The metadata name 1858 * @param checkRead true if need to check read right 1859 * @throws AmetysRepositoryException if an error occurs. 1860 * @throws SAXException if an error occurs. 1861 */ 1862 protected void _saxExternalizableBooleanMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, boolean checkRead) throws AmetysRepositoryException, SAXException 1863 { 1864 if (!checkRead || _canRead(content, metadataDef)) 1865 { 1866 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 1867 1868 if (metadataDef.isMultiple()) 1869 { 1870 boolean[] localValues = null; 1871 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1872 { 1873 localValues = ExternalizableMetadataHelper.getBooleanArray(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1874 } 1875 1876 boolean[] extValues = null; 1877 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1878 { 1879 extValues = ExternalizableMetadataHelper.getBooleanArray(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1880 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, Arrays.asList(localValues), Arrays.asList(extValues)); 1881 } 1882 } 1883 else 1884 { 1885 Boolean localValue = null; 1886 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1887 { 1888 localValue = ExternalizableMetadataHelper.getBoolean(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1889 } 1890 Boolean extValue = null; 1891 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1892 { 1893 extValue = ExternalizableMetadataHelper.getBoolean(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1894 } 1895 1896 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValue, extValue); 1897 } 1898 } 1899 } 1900 1901 /** 1902 * SAX the jsonified values of an externalizable Reference metadata 1903 * @param contentHandler The content handler 1904 * @param content The content 1905 * @param parentMetadata The parent composite metadata 1906 * @param metadataDef The metadata definition 1907 * @param metadataName The metadata name 1908 * @param checkRead true if need to check read right 1909 * @throws AmetysRepositoryException if an error occurs. 1910 * @throws SAXException if an error occurs. 1911 */ 1912 protected void _saxExternalisableReferenceMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, boolean checkRead) throws SAXException 1913 { 1914 if (!checkRead || _canRead(content, metadataDef)) 1915 { 1916 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 1917 1918 Map<String, Object> localValue = null; 1919 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1920 { 1921 CompositeMetadata localRef = ExternalizableMetadataHelper.getCompositeMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1922 localValue = _referenceAsJson(localRef); 1923 } 1924 1925 Map<String, Object> extValue = null; 1926 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1927 { 1928 CompositeMetadata extRef = ExternalizableMetadataHelper.getCompositeMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1929 extValue = _referenceAsJson(extRef); 1930 } 1931 1932 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValue, extValue); 1933 } 1934 } 1935 1936 /** 1937 * SAX the jsonified values of an externalizable geocode metadata 1938 * @param contentHandler The content handler 1939 * @param content The content 1940 * @param parentMetadata The parent composite metadata 1941 * @param metadataDef The metadata definition 1942 * @param metadataName The metadata name 1943 * @param checkRead true if need to check read right 1944 * @throws AmetysRepositoryException if an error occurs. 1945 * @throws SAXException if an error occurs. 1946 */ 1947 protected void _saxExternalisableGeocodeMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, boolean checkRead) throws SAXException 1948 { 1949 if (!checkRead || _canRead(content, metadataDef)) 1950 { 1951 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 1952 1953 Map<String, Object> localValues = null; 1954 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1955 { 1956 CompositeMetadata localGeoCode = ExternalizableMetadataHelper.getCompositeMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1957 localValues = _geocodeAsJson(localGeoCode); 1958 } 1959 1960 Map<String, Object> extValues = null; 1961 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1962 { 1963 CompositeMetadata extGeoCode = ExternalizableMetadataHelper.getCompositeMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1964 extValues = _geocodeAsJson(extGeoCode); 1965 } 1966 1967 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValues, extValues); 1968 } 1969 } 1970 1971 /** 1972 * SAX the jsonified values of an externalizable geocode metadata 1973 * @param contentHandler The content handler 1974 * @param content The content 1975 * @param parentMetadata The parent composite metadata 1976 * @param metadataDef The metadata definition 1977 * @param metadataName The metadata name 1978 * @param checkRead true if need to check read right 1979 * @throws AmetysRepositoryException if an error occurs. 1980 * @throws SAXException if an error occurs. 1981 */ 1982 protected void _saxExternalisableObjectCollectionMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, boolean checkRead) throws SAXException 1983 { 1984 if (!checkRead || _canRead(content, metadataDef)) 1985 { 1986 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 1987 1988 List<String> localValues = new ArrayList<>(); 1989 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 1990 { 1991 TraversableAmetysObject localCollection = ExternalizableMetadataHelper.getObjectCollection(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 1992 localValues = _getRefAmetysObjectIds(localCollection); 1993 } 1994 1995 List<String> extValues = new ArrayList<>(); 1996 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 1997 { 1998 TraversableAmetysObject extCollection = ExternalizableMetadataHelper.getObjectCollection(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 1999 extValues = _getRefAmetysObjectIds(extCollection); 2000 } 2001 2002 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValues, extValues); 2003 } 2004 } 2005 2006 /** 2007 * SAX the jsonified values of an externalizable File metadata 2008 * @param contentHandler The content handler 2009 * @param content The content 2010 * @param parentMetadata The parent composite metadata 2011 * @param metadataDef The metadata definition 2012 * @param metadataName The metadata name 2013 * @param prefix The prefix 2014 * @param checkRead true if need to check read right 2015 * @throws AmetysRepositoryException if an error occurs. 2016 * @throws SAXException if an error occurs. 2017 */ 2018 protected void _saxExternalisableFileMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, String prefix, boolean checkRead) throws AmetysRepositoryException, SAXException 2019 { 2020 if (!checkRead || _canRead(content, metadataDef)) 2021 { 2022 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 2023 2024 Map<String, Object> localValue = new HashMap<>(); 2025 Map<String, Object> extValue = new HashMap<>(); 2026 2027 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 2028 { 2029 if (org.ametys.plugins.repository.metadata.CompositeMetadata.MetadataType.BINARY.equals(ExternalizableMetadataHelper.getType(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL))) 2030 { 2031 BinaryMetadata localBinary = ExternalizableMetadataHelper.getBinaryMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 2032 localValue = _binaryAsJson(content, localBinary, prefix, ExternalizableMetadataHelper.getMetadataName(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)); 2033 } 2034 else 2035 { 2036 String id = ExternalizableMetadataHelper.getString(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 2037 try 2038 { 2039 Resource resource = (Resource) _resolver.resolveById(id); 2040 localValue = _resourceAsJson(resource); 2041 } 2042 catch (AmetysRepositoryException e) 2043 { 2044 getLogger().warn("The resource of id '" + id + "' does not exist.", e); 2045 } 2046 } 2047 2048 } 2049 2050 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 2051 { 2052 if (org.ametys.plugins.repository.metadata.CompositeMetadata.MetadataType.BINARY.equals(ExternalizableMetadataHelper.getType(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL))) 2053 { 2054 BinaryMetadata localBinary = ExternalizableMetadataHelper.getBinaryMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 2055 extValue = _binaryAsJson(content, localBinary, prefix, ExternalizableMetadataHelper.getMetadataName(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)); 2056 } 2057 else 2058 { 2059 String id = ExternalizableMetadataHelper.getString(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 2060 try 2061 { 2062 Resource resource = (Resource) _resolver.resolveById(id); 2063 extValue = _resourceAsJson(resource); 2064 } 2065 catch (AmetysRepositoryException e) 2066 { 2067 getLogger().warn("The resource of id '" + id + "' does not exist.", e); 2068 } 2069 } 2070 } 2071 2072 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValue, extValue); 2073 } 2074 2075 } 2076 2077 /** 2078 * SAX the jsonified values of an externalizable resource file metadata 2079 * @param contentHandler The content handler 2080 * @param content The content 2081 * @param parentMetadata The parent composite metadata 2082 * @param metadataDef The metadata definition 2083 * @param metadataName The metadata name 2084 * @param checkRead true if need to check read right 2085 * @throws AmetysRepositoryException if an error occurs. 2086 * @throws SAXException if an error occurs. 2087 */ 2088 protected void _saxExternalisableResourceFileMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, boolean checkRead) throws AmetysRepositoryException, SAXException 2089 { 2090 if (!checkRead || _canRead(content, metadataDef)) 2091 { 2092 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 2093 2094 Map<String, Object> localValue = new HashMap<>(); 2095 Map<String, Object> extValue = new HashMap<>(); 2096 2097 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 2098 { 2099 String id = ExternalizableMetadataHelper.getString(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 2100 try 2101 { 2102 Resource resource = (Resource) _resolver.resolveById(id); 2103 localValue = _resourceAsJson(resource); 2104 } 2105 catch (AmetysRepositoryException e) 2106 { 2107 getLogger().warn("The resource of id '" + id + "' does not exist.", e); 2108 } 2109 } 2110 2111 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 2112 { 2113 String id = ExternalizableMetadataHelper.getString(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 2114 try 2115 { 2116 Resource resource = (Resource) _resolver.resolveById(id); 2117 extValue = _resourceAsJson(resource); 2118 } 2119 catch (AmetysRepositoryException e) 2120 { 2121 getLogger().warn("The resource of id '" + id + "' does not exist.", e); 2122 } 2123 } 2124 2125 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValue, extValue); 2126 } 2127 } 2128 2129 /** 2130 * SAX the jsonified values of an externalizable resource file metadata 2131 * @param contentHandler The content handler 2132 * @param content The content 2133 * @param parentMetadata The parent composite metadata 2134 * @param metadataDef The metadata definition 2135 * @param metadataName The metadata name 2136 * @param checkRead true if need to check read right 2137 * @throws AmetysRepositoryException if an error occurs. 2138 * @throws SAXException if an error occurs. 2139 */ 2140 protected void _saxExternalisableRichTextMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, boolean checkRead) throws AmetysRepositoryException, SAXException 2141 { 2142 if (!checkRead || _canRead(content, metadataDef)) 2143 { 2144 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 2145 2146 String localValue = null; 2147 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 2148 { 2149 RichText localRichText = ExternalizableMetadataHelper.getRichText(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 2150 if (!(localRichText instanceof ModifiableRichText)) 2151 { 2152 throw new SAXException("The rich text '" + metadataDef.getId() + "' is not a modifiable rich text"); 2153 } 2154 localValue = _richTextAsString((ModifiableRichText) localRichText, metadataDef); 2155 } 2156 2157 String extValue = null; 2158 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 2159 { 2160 RichText extRichText = ExternalizableMetadataHelper.getRichText(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 2161 if (!(extRichText instanceof ModifiableRichText)) 2162 { 2163 throw new SAXException("The rich text '" + metadataDef.getId() + "' is not a modifiable rich text"); 2164 } 2165 extValue = _richTextAsString((ModifiableRichText) extRichText, metadataDef); 2166 } 2167 2168 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValue, extValue); 2169 } 2170 } 2171 2172 /** 2173 * SAX the jsonified values of an externalizable geocode metadata 2174 * @param contentHandler The content handler 2175 * @param content The content 2176 * @param parentMetadata The parent composite metadata 2177 * @param metadataDef The metadata definition 2178 * @param metadataName The metadata name 2179 * @param checkRead true if need to check read right 2180 * @throws AmetysRepositoryException if an error occurs. 2181 * @throws SAXException if an error occurs. 2182 */ 2183 protected void _saxExternalisableUserMetadata(ContentHandler contentHandler, Content content, CompositeMetadata parentMetadata, MetadataDefinition metadataDef, String metadataName, boolean checkRead) throws SAXException 2184 { 2185 if (!checkRead || _canRead(content, metadataDef)) 2186 { 2187 ExternalizableMetadataStatus status = ExternalizableMetadataHelper.getStatus(parentMetadata, metadataName); 2188 2189 if (metadataDef.isMultiple()) 2190 { 2191 List<Map<String, Object>> localValues = new ArrayList<>(); 2192 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 2193 { 2194 UserIdentity[] localUsers = ExternalizableMetadataHelper.getUserArray(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 2195 for (UserIdentity userIdentity : localUsers) 2196 { 2197 localValues.add(_userAsJson(userIdentity)); 2198 } 2199 } 2200 2201 List<Map<String, Object>> extValues = new ArrayList<>(); 2202 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 2203 { 2204 UserIdentity[] extUsers = ExternalizableMetadataHelper.getUserArray(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 2205 for (UserIdentity userIdentity : extUsers) 2206 { 2207 extValues.add(_userAsJson(userIdentity)); 2208 } 2209 } 2210 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValues, extValues); 2211 } 2212 else 2213 { 2214 Map<String, Object> localValue = null; 2215 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL)) 2216 { 2217 UserIdentity localUser = ExternalizableMetadataHelper.getUser(parentMetadata, metadataName, ExternalizableMetadataStatus.LOCAL); 2218 localValue = _userAsJson(localUser); 2219 } 2220 2221 Map<String, Object> extValue = null; 2222 if (ExternalizableMetadataHelper.hasMetadata(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL)) 2223 { 2224 UserIdentity extUser = ExternalizableMetadataHelper.getUser(parentMetadata, metadataName, ExternalizableMetadataStatus.EXTERNAL); 2225 extValue = _userAsJson(extUser); 2226 } 2227 _saxExternalizableValuesAsJson(contentHandler, metadataName, status, localValue, extValue); 2228 } 2229 } 2230 } 2231 2232 /** 2233 * SAX externalizable values as JSON 2234 * @param contentHandler The content handler 2235 * @param metadataName The metadata name 2236 * @param status The status 2237 * @param localValue The local value 2238 * @param extValue The external value 2239 * @throws SAXException if an error occurs. 2240 */ 2241 protected void _saxExternalizableValuesAsJson (ContentHandler contentHandler, String metadataName, ExternalizableMetadataStatus status, Object localValue, Object extValue) throws SAXException 2242 { 2243 Map<String, Object> values = new LinkedHashMap<>(); 2244 2245 values.put("status", status.name().toLowerCase()); 2246 if (localValue != null) 2247 { 2248 values.put("local", localValue); 2249 } 2250 if (extValue != null) 2251 { 2252 values.put("external", extValue); 2253 } 2254 2255 String jsonString = _jsonUtils.convertObjectToJson(values); 2256 2257 AttributesImpl attrs = new AttributesImpl(); 2258 attrs.addCDATAAttribute("json", "true"); 2259 XMLUtils.createElement(contentHandler, metadataName, attrs, jsonString); 2260 } 2261 2262 /** 2263 * Get the JSON representation of a {@link ModifiableRichText} 2264 * @param richText The rich text 2265 * @param metadataDef The metadata definition 2266 * @return The resource as JSON 2267 */ 2268 protected String _richTextAsString (ModifiableRichText richText, MetadataDefinition metadataDef) 2269 { 2270 RichTextTransformer richTextTransformer = metadataDef.getRichTextTransformer(); 2271 StringBuilder result = new StringBuilder(2048); 2272 2273 try 2274 { 2275 richTextTransformer.transformForEditing(richText, result); 2276 } 2277 catch (IOException e) 2278 { 2279 throw new AmetysRepositoryException("Unable to transform a rich text into a string", e); 2280 } 2281 2282 return result.toString(); 2283 } 2284 2285 /** 2286 * Determines if a metadata can be read 2287 * @param content the content 2288 * @param metadataDef the metadata definition. 2289 * @return <code>true</code> if the metadata can be read 2290 * @throws AmetysRepositoryException If an error occured 2291 */ 2292 protected boolean _canRead(Content content, MetadataDefinition metadataDef) throws AmetysRepositoryException 2293 { 2294 return _contentTypesHelper.canRead(content, metadataDef); 2295 } 2296 2297 /** 2298 * Compares repeater entry names to sort them. 2299 */ 2300 protected static class RepeaterEntryComparator implements Comparator<String> 2301 { 2302 @Override 2303 public int compare(String s1, String s2) 2304 { 2305 try 2306 { 2307 Integer i1 = new Integer(s1); 2308 Integer i2 = new Integer(s2); 2309 2310 return i1.compareTo(i2); 2311 } 2312 catch (NumberFormatException e) 2313 { 2314 return s1.compareTo(s2); 2315 } 2316 } 2317 } 2318 2319}