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